/* PSPP - computes sample statistics.
Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
- Written by Ben Pfaff <blp@gnu.org>.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
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)
/* 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
{
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;
}
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
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
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