X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fstr.c;h=b88493d47fabafff46fd36a724cdcc1ad3e26d68;hb=436b01ace5b84c27963f6130dca0e69fe15f9a17;hp=503d6c8bb9d7ac59f023a1b31722052217bba6f8;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp-builds.git diff --git a/src/libpspp/str.c b/src/libpspp/str.c index 503d6c8b..b88493d4 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -1,35 +1,33 @@ -/* PSPP - computes sample statistics. +/* PSPP - a program for statistical analysis. Copyright (C) 1997-9, 2000, 2006 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 the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with this program. If not, see . */ #include #include "str.h" #include -#include +#include +#include #include -#include #include #include #include "minmax.h" -#include "size_max.h" +#include "xalloc.h" #include "xsize.h" /* Reverses the order of NBYTES bytes at address P, thus converting @@ -254,6 +252,41 @@ str_lowercase (char *s) *s = tolower ((unsigned char) *s); } +/* Converts NUMBER into a string in 26-adic notation in BUFFER, + which has room for SIZE bytes. Returns true if successful, + false if NUMBER, plus a trailing null, is too large to fit in + the available space. + + 26-adic notation is "spreadsheet column numbering": 1 = A, 2 = + B, 3 = C, ... 26 = Z, 27 = AA, 28 = AB, 29 = AC, ... + + 26-adic notation is the special case of a k-adic numeration + system (aka bijective base-k numeration) with k=26. In k-adic + numeration, the digits are {1, 2, 3, ..., k} (there is no + digit 0), and integer 0 is represented by the empty string. + For more information, see + http://en.wikipedia.org/wiki/Bijective_numeration. */ +bool +str_format_26adic (unsigned long int number, char buffer[], size_t size) +{ + size_t length = 0; + + while (number-- > 0) + { + if (length >= size) + return false; + buffer[length++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[number % 26]; + number /= 26; + } + + if (length >= size) + return false; + buffer[length] = '\0'; + + buf_reverse (buffer, length); + return true; +} + /* Formats FORMAT into DST, as with sprintf(), and returns the address of the terminating null written to DST. */ char * @@ -1137,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; } } @@ -1207,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)); @@ -1220,8 +1270,8 @@ ds_read_config_line (struct string *st, int *line_number, FILE *stream) /* Attempts to read SIZE * CNT bytes from STREAM and append them to ST. - Returns number of bytes actually read. */ -size_t + Returns true if all the requested data was read, false otherwise. */ +bool ds_read_stream (struct string *st, size_t size, size_t cnt, FILE *stream) { if (size != 0) @@ -1230,12 +1280,18 @@ ds_read_stream (struct string *st, size_t size, size_t cnt, FILE *stream) if (size_in_bounds_p (xsum (ds_length (st), try_bytes))) { char *buffer = ds_put_uninit (st, try_bytes); - size_t got_bytes = fread (buffer, size, cnt, stream); + size_t got_bytes = fread (buffer, 1, try_bytes, stream); ds_truncate (st, ds_length (st) - (try_bytes - got_bytes)); - return got_bytes; + return got_bytes == try_bytes; + } + else + { + errno = ENOMEM; + return false; } } - return 0; + else + return true; } /* Concatenates S onto ST. */