Rewrite system file reader code, to clean up and improve.
[pspp-builds.git] / src / libpspp / str.c
index 5a554b7b2acaba573aa602f1991e83a7de9145bb..183a4022cc1280fd4f9664fb427c5da9a095f6a3 100644 (file)
@@ -358,6 +358,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 +472,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 +484,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 +514,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