X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fstr.c;h=afe32de9f2049bfcc5a80ac7a95b36b348be4cb7;hb=8830c95bb9e8d72621787866141a27fc22e8c786;hp=d082672060f5235d6610939221365663fb5652b8;hpb=a1efcf97ca2f75f4be6a0389ff2372c03ed2d4e1;p=pspp-builds.git diff --git a/src/libpspp/str.c b/src/libpspp/str.c index d0826720..afe32de9 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 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009 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 @@ -26,6 +26,7 @@ #include #include +#include #include "minmax.h" #include "xalloc.h" #include "xsize.h" @@ -124,9 +125,9 @@ str_compare_rpad (const char *a, const char *b) /* Copies string SRC to buffer DST, of size DST_SIZE bytes. DST is truncated to DST_SIZE bytes or padded on the right with - spaces as needed. */ + copies of PAD as needed. */ void -buf_copy_str_rpad (char *dst, size_t dst_size, const char *src) +buf_copy_str_rpad (char *dst, size_t dst_size, const char *src, char pad) { size_t src_len = strlen (src); if (src_len >= dst_size) @@ -134,15 +135,15 @@ buf_copy_str_rpad (char *dst, size_t dst_size, const char *src) else { memcpy (dst, src, src_len); - memset (&dst[src_len], ' ', dst_size - src_len); + memset (&dst[src_len], pad, dst_size - src_len); } } /* Copies string SRC to buffer DST, of size DST_SIZE bytes. DST is truncated to DST_SIZE bytes or padded on the left with - spaces as needed. */ + copies of PAD as needed. */ void -buf_copy_str_lpad (char *dst, size_t dst_size, const char *src) +buf_copy_str_lpad (char *dst, size_t dst_size, const char *src, char pad) { size_t src_len = strlen (src); if (src_len >= dst_size) @@ -150,40 +151,42 @@ buf_copy_str_lpad (char *dst, size_t dst_size, const char *src) else { size_t pad_cnt = dst_size - src_len; - memset (&dst[0], ' ', pad_cnt); + memset (&dst[0], pad, pad_cnt); memcpy (dst + pad_cnt, src, src_len); } } /* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes. DST is truncated to DST_SIZE bytes or padded on the left with - spaces as needed. */ + copies of PAD as needed. */ void buf_copy_lpad (char *dst, size_t dst_size, - const char *src, size_t src_size) + const char *src, size_t src_size, + char pad) { if (src_size >= dst_size) memmove (dst, src, dst_size); else { - memset (dst, ' ', dst_size - src_size); + memset (dst, pad, dst_size - src_size); memmove (&dst[dst_size - src_size], src, src_size); } } /* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes. DST is truncated to DST_SIZE bytes or padded on the right with - spaces as needed. */ + copies of PAD as needed. */ void buf_copy_rpad (char *dst, size_t dst_size, - const char *src, size_t src_size) + const char *src, size_t src_size, + char pad) { if (src_size >= dst_size) memmove (dst, src, dst_size); else { memmove (dst, src, src_size); - memset (&dst[src_size], ' ', dst_size - src_size); + memset (&dst[src_size], pad, dst_size - src_size); } } @@ -1068,6 +1071,34 @@ ds_set_length (struct string *st, size_t new_length, char pad) st->ss.length = new_length; } +/* Removes N characters from ST starting at offset START. */ +void +ds_remove (struct string *st, size_t start, size_t n) +{ + if (n > 0 && start < st->ss.length) + { + if (st->ss.length - start <= n) + { + /* All characters at or beyond START are deleted. */ + st->ss.length = start; + } + else + { + /* Some characters remain and must be shifted into + position. */ + memmove (st->ss.string + st->ss.length, + st->ss.string + st->ss.length + n, + st->ss.length - start - n); + st->ss.length -= n; + } + } + else + { + /* There are no characters to delete or no characters at or + beyond START, hence deletion is a no-op. */ + } +} + /* Returns true if ST is empty, false otherwise. */ bool ds_is_empty (const struct string *st) @@ -1190,48 +1221,42 @@ ds_cstr (const struct string *st_) return st->ss.string; } -/* 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). */ +/* 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 + comes first. Returns true if at least one character was added + 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. */ bool ds_read_line (struct string *st, FILE *stream, size_t max_length) { - 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; + + for (length = 0; length < max_length; length++) { - size_t length; + int c = getc (stream); + if (c == EOF) + break; - for (length = 0; length < max_length; length++) + if (c == '\r') { - int c = getc (stream); - if (c == EOF) - break; - - ds_put_char (st, c); - if (c == '\n') - return true; + c = getc (stream); + if (c != '\n') + { + ungetc (c, stream); + c = '\n'; + } } - - return length > 0; + ds_put_char (st, c); + if (c == '\n') + return true; } + + return length > 0; } /* Removes a comment introduced by `#' from ST, @@ -1399,3 +1424,42 @@ ds_put_char_multiple (struct string *st, int ch, size_t cnt) { memset (ds_put_uninit (st, cnt), ch, cnt); } + + +/* If relocation has been enabled, replace ST, + with its relocated version */ +void +ds_relocate (struct string *st) +{ + const char *orig = ds_cstr (st); + const char *rel = relocate (orig); + + if ( orig != rel) + { + ds_clear (st); + ds_put_cstr (st, rel); + free ((char *) rel); + } +} + + + + +/* Operations on uint8_t "strings" */ + +/* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes. + DST is truncated to DST_SIZE bytes or padded on the right with + copies of PAD as needed. */ +void +u8_buf_copy_rpad (uint8_t *dst, size_t dst_size, + const uint8_t *src, size_t src_size, + char pad) +{ + if (src_size >= dst_size) + memmove (dst, src, dst_size); + else + { + memmove (dst, src, src_size); + memset (&dst[src_size], pad, dst_size - src_size); + } +}