X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fstr.c;h=655774d63d57c8e1b9b146b9d513edc8abe2a387;hb=8f734ed17443b6ad5085d1bccc1a6772ac1b4ab7;hp=e84021be4c41b036d7fb8105eec52e2f732d9128;hpb=b990f5c31bc831e588a86f9f4826387c6843c989;p=pspp-builds.git diff --git a/src/libpspp/str.c b/src/libpspp/str.c index e84021be..655774d6 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -18,13 +18,16 @@ 02110-1301, USA. */ #include + #include "str.h" -#include "message.h" + #include #include #include -#include "alloc.h" -#include "message.h" + +#include +#include + #include "minmax.h" #include "size_max.h" @@ -233,6 +236,21 @@ str_lowercase (char *s) for (; *s != '\0'; s++) *s = tolower ((unsigned char) *s); } + +/* Formats FORMAT into DST, as with sprintf(), and returns the + address of the terminating null written to DST. */ +char * +spprintf (char *dst, const char *format, ...) +{ + va_list args; + int count; + + va_start (args, format); + count = vsprintf (dst, format, args); + va_end (args); + + return dst + count; +} /* Initializes ST with initial contents S. */ void @@ -244,13 +262,13 @@ ds_create (struct string *st, const char *s) strcpy (st->string, s); } -/* Initializes ST, making room for at least CAPACITY characters. */ +/* Initializes ST as an empty string. */ void -ds_init (struct string *st, size_t capacity) +ds_init (struct string *st) { st->length = 0; - st->capacity = MAX (8, capacity); - st->string = xmalloc (st->capacity + 1); + st->capacity = 0; + st->string = NULL; } /* Frees ST. */ @@ -282,7 +300,7 @@ ds_init_substring (struct string *dst, const struct string *src, size_t idx, size_t cnt) { assert (dst != src); - ds_init (dst, cnt); + ds_init (dst); ds_assign_substring (dst, src, idx, cnt); } @@ -431,7 +449,7 @@ ds_chomp (struct string *st, char c_) empty string if no tokens remain. Returns true if a token was obtained, false otherwise. - Before the first call, initialize *SAVE_IDX to -1. Do not + Before the first call, initialize *SAVE_IDX to 0. Do not modify *SAVE_IDX between calls. ST divides into exactly one more tokens than it contains @@ -440,28 +458,36 @@ ds_chomp (struct string *st, char c_) empty string contains a single token. */ bool ds_separate (const struct string *st, struct string *token, - const char *delimiters, int *save_idx) + const char *delimiters, size_t *save_idx) { - int start_idx; - - ds_clear (token); - if (*save_idx < 0) + if (*save_idx <= ds_length (st)) { - *save_idx = 0; - if (ds_is_empty (st)) - return true; + size_t length = ds_cspan (st, *save_idx, delimiters); + ds_assign_substring (token, st, *save_idx, length); + *save_idx += length + 1; + return true; } - else if (*save_idx < ds_length (st)) - ++*save_idx; - else + else return false; +} - start_idx = *save_idx; - while (*save_idx < ds_length (st) - && strchr (delimiters, ds_data (st)[*save_idx]) == NULL) - ++*save_idx; - ds_assign_substring (token, st, start_idx, *save_idx - start_idx); - return true; +/* Divides ST into tokens separated by any of the DELIMITERS, + merging adjacent delimiters so that the empty string is never + produced as a token. Each call replaces TOKEN by the next + token in ST, or by an empty string if no tokens remain. + Returns true if a token was obtained, false otherwise. + + Before the first call, initialize *SAVE_IDX to 0. Do not + modify *SAVE_IDX between calls. */ +bool +ds_tokenize (const struct string *st, struct string *token, + const char *delimiters, size_t *save_idx) +{ + size_t start = *save_idx + ds_span (st, *save_idx, delimiters); + size_t length = ds_cspan (st, start, delimiters); + ds_assign_substring (token, st, start, length); + *save_idx = start + length; + return length > 0; } /* Returns true if ST is empty, false otherwise. */ @@ -673,6 +699,21 @@ ds_concat (struct string *st, const char *buf, size_t len) st->length += len; } +/* Returns ds_end(ST) and THEN increases the length by INCR. */ +char * +ds_append_uninit(struct string *st, size_t incr) +{ + char *end; + + ds_extend(st, ds_length(st) + incr); + + end = ds_end(st); + + st->length += incr; + + return end; +} + /* Formats FORMAT as a printf string and appends the result to ST. */ void ds_printf (struct string *st, const char *format, ...) @@ -691,12 +732,8 @@ ds_vprintf (struct string *st, const char *format, va_list args_) int avail, needed; va_list args; -#ifndef va_copy -#define va_copy(DST, SRC) (DST) = (SRC) -#endif - va_copy (args, args_); - avail = st->capacity - st->length + 1; + avail = st->string != NULL ? st->capacity - st->length + 1 : 0; needed = vsnprintf (st->string + st->length, avail, format, args); va_end (args);