X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fstr.c;h=ca23b08b7290c93ddc8138ff5810dbc0f9317f0f;hb=af6fd5651bf8075a0d962ba6d339373179e0195b;hp=965e3b301b5c67326390383d5e23c66d77c50280;hpb=8acca2de53c1852f38726f70fc6516b34732a79f;p=pspp-builds.git diff --git a/src/libpspp/str.c b/src/libpspp/str.c index 965e3b30..ca23b08b 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -1,6 +1,5 @@ /* PSPP - computes sample statistics. Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. - Written by Ben Pfaff . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -358,6 +357,25 @@ ss_alloc_uninit (struct substring *new, size_t cnt) new->length = cnt; } +/* Makes a pool_alloc_unaligned()'d copy of the contents of OLD + in POOL, and stores it in NEW. */ +void +ss_alloc_substring_pool (struct substring *new, struct substring old, + struct pool *pool) +{ + new->string = pool_alloc_unaligned (pool, old.length); + new->length = old.length; + memcpy (new->string, old.string, old.length); +} + +/* Allocates room for a CNT-character string in NEW in POOL. */ +void +ss_alloc_uninit_pool (struct substring *new, size_t cnt, struct pool *pool) +{ + new->string = pool_alloc_unaligned (pool, cnt); + new->length = cnt; +} + /* Frees the string that SS points to. */ void ss_dealloc (struct substring *ss) @@ -453,7 +471,8 @@ ss_separate (struct substring ss, struct substring delimiters, /* Divides SS 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 SS, or by an empty string if no tokens remain. + token in SS, or by an empty string if no tokens remain, and + then skips past the first delimiter following the token. Returns true if a token was obtained, false otherwise. Before the first call, initialize *SAVE_IDX to 0. Do not @@ -464,7 +483,8 @@ ss_tokenize (struct substring ss, struct substring delimiters, { ss_advance (&ss, *save_idx); *save_idx += ss_ltrim (&ss, delimiters); - *save_idx += ss_get_chars (&ss, ss_cspan (ss, delimiters), token); + ss_get_chars (&ss, ss_cspan (ss, delimiters), token); + *save_idx += ss_length (*token) + 1; return ss_length (*token) > 0; } @@ -493,6 +513,21 @@ ss_match_char (struct substring *ss, char c) return false; } +/* If SS begins with TARGET, removes it and returns true. + Otherwise, returns false without changing SS. */ +bool +ss_match_string (struct substring *ss, const struct substring target) +{ + size_t length = ss_length (target); + if (ss_equals (ss_head (*ss, length), target)) + { + ss_advance (ss, length); + return true; + } + else + return false; +} + /* Removes the first character from SS and returns it. If SS is empty, returns EOF without modifying SS. */ int @@ -529,6 +564,36 @@ ss_get_chars (struct substring *ss, size_t cnt, struct substring *out) return cnt; } +/* Parses and removes an optionally signed decimal integer from + the beginning of SS. Returns 0 if an error occurred, + otherwise the number of characters removed from SS. Stores + the integer's value into *VALUE. */ +size_t +ss_get_long (struct substring *ss, long *value) +{ + char tmp[64]; + size_t length; + + length = ss_span (*ss, ss_cstr ("+-")); + length += ss_span (ss_substr (*ss, length, SIZE_MAX), ss_cstr (CC_DIGITS)); + if (length > 0 && length < sizeof tmp) + { + char *tail; + + memcpy (tmp, ss_data (*ss), length); + tmp[length] = '\0'; + + *value = strtol (tmp, &tail, 10); + if (tail - tmp == length) + { + ss_advance (ss, length); + return length; + } + } + *value = 0; + return 0; +} + /* Returns true if SS is empty (contains no characters), false otherwise. */ bool @@ -627,6 +692,34 @@ ss_compare (struct substring a, struct substring b) return retval; } +/* Compares A and B case-insensitively and returns a + strcmp()-type comparison result. */ +int +ss_compare_case (struct substring a, struct substring b) +{ + int retval = memcasecmp (a.string, b.string, MIN (a.length, b.length)); + if (retval == 0) + retval = a.length < b.length ? -1 : a.length > b.length; + return retval; +} + +/* Compares A and B and returns true if their contents are + identical, false otherwise. */ +int +ss_equals (struct substring a, struct substring b) +{ + return a.length == b.length && !memcmp (a.string, b.string, a.length); +} + +/* Compares A and B and returns true if their contents are + identical except possibly for case differences, false + otherwise. */ +int +ss_equals_case (struct substring a, struct substring b) +{ + return a.length == b.length && !memcasecmp (a.string, b.string, a.length); +} + /* Returns the position in SS that the character at P occupies. P must point within SS or one past its end. */ size_t