X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fstr.c;h=b88493d47fabafff46fd36a724cdcc1ad3e26d68;hb=436b01ace5b84c27963f6130dca0e69fe15f9a17;hp=b169f0d7613ee556e7a5a32e746a36ac2f06af23;hpb=c725a4f64718ef1ee4139c27c94b2eb6447b51b4;p=pspp-builds.git diff --git a/src/libpspp/str.c b/src/libpspp/str.c index b169f0d7..b88493d4 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -1170,30 +1170,47 @@ ds_cstr (const struct string *st_) return st->ss.string; } -/* Appends to ST a newline-terminated line read from STREAM. - Newline is the last character of ST on return, unless an I/O error - or end of file is encountered after reading some characters. - Returns true if a line is successfully read, false if no characters at - all were read before an I/O error or end of file was - encountered. */ +/* Appends to ST a newline-terminated line read from STREAM, but + no more than MAX_LENGTH characters. + Newline is the last character of ST on return, if encountering + a newline was the reason for terminating. + Returns true if at least one character was read from STREAM + and appended to ST, false if no characters at all were read + before an I/O error or end of file was encountered (or + MAX_LENGTH was 0). */ bool -ds_read_line (struct string *st, FILE *stream) +ds_read_line (struct string *st, FILE *stream, size_t max_length) { - int c; + if (!st->ss.length && max_length == SIZE_MAX) + { + size_t capacity = st->capacity ? st->capacity + 1 : 0; + ssize_t n = getline (&st->ss.string, &capacity, stream); + if (capacity) + st->capacity = capacity - 1; + if (n > 0) + { + st->ss.length = n; + return true; + } + else + return false; + } + else + { + size_t length; - c = getc (stream); - if (c == EOF) - return false; + for (length = 0; length < max_length; length++) + { + int c = getc (stream); + if (c == EOF) + break; - for (;;) - { - ds_put_char (st, c); - if (c == '\n') - return true; + ds_put_char (st, c); + if (c == '\n') + return true; + } - c = getc (stream); - if (c == EOF) - return true; + return length > 0; } } @@ -1240,7 +1257,7 @@ ds_read_config_line (struct string *st, int *line_number, FILE *stream) ds_clear (st); do { - if (!ds_read_line (st, stream)) + if (!ds_read_line (st, stream, SIZE_MAX)) return false; (*line_number)++; ds_rtrim (st, ss_cstr (CC_SPACES));