/* 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 <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
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. */
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
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)
{
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;
{
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));
}
}