X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fstr.c;h=bde4de4be5bb4ee13edf877e217537336debfc0a;hb=c75794cffb05769b71a346af8513a3e8dde55f94;hp=afe32de9f2049bfcc5a80ac7a95b36b348be4cb7;hpb=8830c95bb9e8d72621787866141a27fc22e8c786;p=pspp diff --git a/src/libpspp/str.c b/src/libpspp/str.c index afe32de9f2..bde4de4be5 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -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 @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -1214,13 +1215,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 +1240,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 +1251,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 +1465,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)); } }