str: Inline some trivial functions.
[pspp-builds.git] / src / libpspp / str.c
index afe32de9f2049bfcc5a80ac7a95b36b348be4cb7..6c2e39918850b0fc09234f7567ee19e042645b06 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include <stdint.h>
 #include <stdlib.h>
 
+#include <libpspp/cast.h>
 #include <libpspp/message.h>
 #include <libpspp/pool.h>
 
 #include <relocatable.h>
 #include "minmax.h"
 #include "xalloc.h"
+#include "xmemdup0.h"
 #include "xsize.h"
 \f
 /* Reverses the order of NBYTES bytes at address P, thus converting
@@ -48,19 +50,6 @@ buf_reverse (char *p, size_t nbytes)
     }
 }
 
-/* Finds the last NEEDLE of length NEEDLE_LEN in a HAYSTACK of length
-   HAYSTACK_LEN.  Returns a pointer to the needle found. */
-char *
-buf_find_reverse (const char *haystack, size_t haystack_len,
-                 const char *needle, size_t needle_len)
-{
-  int i;
-  for (i = haystack_len - needle_len; i >= 0; i--)
-    if (!memcmp (needle, &haystack[i], needle_len))
-      return (char *) &haystack[i];
-  return 0;
-}
-
 /* Compares the SIZE bytes in A to those in B, disregarding case,
    and returns a strcmp()-type result. */
 int
@@ -293,21 +282,6 @@ str_format_26adic (unsigned long int number, char buffer[], size_t size)
   return true;
 }
 
-/* Formats FORMAT into DST, as with sprintf(), and returns the
-   address of the terminating null written to DST. */
-char *
-spprintf (char *dst, const char *format, ...)
-{
-  va_list args;
-  int count;
-
-  va_start (args, format);
-  count = vsprintf (dst, format, args);
-  va_end (args);
-
-  return dst + count;
-}
-
 /* Sets the SIZE bytes starting at BLOCK to C,
    and returns the byte following BLOCK. */
 void *
@@ -319,35 +293,6 @@ mempset (void *block, int c, size_t size)
 \f
 /* Substrings. */
 
-/* Returns an empty substring. */
-struct substring
-ss_empty (void)
-{
-  struct substring ss;
-  ss.string = NULL;
-  ss.length = 0;
-  return ss;
-}
-
-/* Returns a substring whose contents are the given C-style
-   string CSTR. */
-struct substring
-ss_cstr (const char *cstr)
-{
-  return ss_buffer (cstr, strlen (cstr));
-}
-
-/* Returns a substring whose contents are the CNT characters in
-   BUFFER. */
-struct substring
-ss_buffer (const char *buffer, size_t cnt)
-{
-  struct substring ss;
-  ss.string = (char *) buffer;
-  ss.length = cnt;
-  return ss;
-}
-
 /* Returns a substring whose contents are the CNT characters
    starting at the (0-based) position START in SS. */
 struct substring
@@ -378,14 +323,13 @@ ss_tail (struct substring ss, size_t cnt)
     return ss;
 }
 
-/* Makes a malloc()'d copy of the contents of OLD
+/* Makes a malloc()'d, null-terminated copy of the contents of OLD
    and stores it in NEW. */
 void
 ss_alloc_substring (struct substring *new, struct substring old)
 {
-  new->string = xmalloc (old.length);
+  new->string = xmemdup0 (old.string, old.length);
   new->length = old.length;
-  memcpy (new->string, old.string, old.length);
 }
 
 /* Allocates room for a CNT-character string in NEW. */
@@ -1214,13 +1158,24 @@ ds_capacity (const struct string *st)
 char *
 ds_cstr (const struct string *st_)
 {
-  struct string *st = (struct string *) st_;
+  struct string *st = CONST_CAST (struct string *, st_);
   if (st->ss.string == NULL)
     ds_extend (st, 1);
   st->ss.string[st->ss.length] = '\0';
   return st->ss.string;
 }
 
+/* Returns the value of ST as a null-terminated string and then
+   reinitialized ST as an empty string.  The caller must free the
+   returned string with free(). */
+char *
+ds_steal_cstr (struct string *st)
+{
+  char *s = ds_cstr (st);
+  ds_init_empty (st);
+  return s;
+}
+
 /* Reads characters from STREAM and appends them to ST, stopping
    after MAX_LENGTH characters, after appending a newline, or
    after an I/O error or end of file was encountered, whichever
@@ -1228,9 +1183,9 @@ ds_cstr (const struct string *st_)
    to ST, false if no characters were read before an I/O error or
    end of file (or if MAX_LENGTH was 0).
 
-   This function accepts LF, CR LF, and CR sequences as new-line,
-   and translates each of them to a single '\n' new-line
-   character in ST. */
+   This function treats LF and CR LF sequences as new-line,
+   translating each of them to a single '\n' new-line character
+   in ST. */
 bool
 ds_read_line (struct string *st, FILE *stream, size_t max_length)
 {
@@ -1239,21 +1194,36 @@ ds_read_line (struct string *st, FILE *stream, size_t max_length)
   for (length = 0; length < max_length; length++)
     {
       int c = getc (stream);
-      if (c == EOF)
-        break;
-
-      if (c == '\r')
+      switch (c)
         {
+        case EOF:
+          return length > 0;
+
+        case '\n':
+          ds_put_char (st, c);
+          return true;
+
+        case '\r':
           c = getc (stream);
-          if (c != '\n')
+          if (c == '\n')
+            {
+              /* CR followed by LF is special: translate to \n. */
+              ds_put_char (st, '\n');
+              return true;
+            }
+          else
             {
+              /* CR followed by anything else is just CR. */
+              ds_put_char (st, '\r');
+              if (c == EOF)
+                return true;
               ungetc (c, stream);
-              c = '\n';
             }
+          break;
+
+        default:
+          ds_put_char (st, c);
         }
-      ds_put_char (st, c);
-      if (c == '\n')
-        return true;
     }
 
   return length > 0;
@@ -1438,7 +1408,9 @@ ds_relocate (struct string *st)
     {
       ds_clear (st);
       ds_put_cstr (st, rel);
-      free ((char *) rel);
+      /* The documentation for relocate says that casting away const
+       and then freeing is appropriate ... */
+      free (CONST_CAST (char *, rel));
     }
 }