return ss;
}
-/* Makes a malloc()'d, null-terminated copy of the contents of OLD
- and stores it in NEW. */
-void
-ss_alloc_substring (struct substring *new, struct substring old)
+/* Returns a malloc()'d, null-terminated copy of the contents of OLD. The
+ caller owns the returned string and must eventually free it. */
+struct substring
+ss_clone (struct substring old)
{
- new->string = xmemdup0 (old.string, old.length);
- new->length = old.length;
+ return (struct substring) {
+ .string = xmemdup0 (old.string, old.length),
+ .length = old.length,
+ };
}
/* Allocates room for a N-byte string in NEW. */
ss->string = xrealloc (ss->string, size);
}
-/* Makes a pool_alloc_unaligned()'d, null-terminated 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)
+/* Returns a pool_alloc_unaligned()'d, null-terminated copy of the contents of
+ OLD in POOL. The pool owns the returned string. */
+struct substring
+ss_clone_pool (struct substring old, struct pool *pool)
{
- new->string = pool_alloc_unaligned (pool, old.length + 1);
- new->length = old.length;
- memcpy (new->string, old.string, old.length);
- new->string[old.length] = '\0';
+ return (struct substring) {
+ .string = pool_memdup0 (pool, old.string, old.length),
+ .length = old.length
+ };
}
/* Allocates room for a N-byte string in NEW in POOL. */
return false;
}
+/* If SS begins with TARGET, except possibly for case differences, removes it
+ and returns true. Otherwise, returns false without changing SS. */
+bool
+ss_match_string_case (struct substring *ss, const struct substring target)
+{
+ size_t length = ss_length (target);
+ if (ss_equals_case (ss_head (*ss, length), target))
+ {
+ ss_advance (ss, length);
+ return true;
+ }
+ else
+ return false;
+}
+
/* Removes the first byte from SS and returns it.
If SS is empty, returns EOF without modifying SS. */
int
&& !memcmp (ss.string, prefix.string, prefix.length));
}
+/* Returns true if SS starts with PREFIX in any case, false otherwise. */
+bool
+ss_starts_with_case (struct substring ss, struct substring prefix)
+{
+ return (ss.length >= prefix.length
+ && !memcasecmp (ss.string, prefix.string, prefix.length));
+}
+
/* Returns true if SS ends with SUFFIX, false otherwise. */
bool
ss_ends_with (struct substring ss, struct substring suffix)
suffix.length));
}
+/* Returns true if SS ends with SUFFIX in any case, false otherwise. */
+bool
+ss_ends_with_case (struct substring ss, struct substring suffix)
+{
+ return (ss.length >= suffix.length
+ && !memcasecmp (&ss.string[ss.length - suffix.length], suffix.string,
+ suffix.length));
+}
+
/* Returns the number of contiguous bytes at the beginning
of SS that are in SKIP_SET. */
size_t
return retval;
}
+/* Compares A to B and returns a strcmp()-type comparison result. The shorter
+ string is considered to be padded with spaces to the length of the
+ longer. */
+int
+ss_compare_rpad (struct substring a, struct substring b)
+{
+ return buf_compare_rpad (a.string, a.length, b.string, b.length);
+}
+
/* Compares A and B case-insensitively and returns a
strcmp()-type comparison result. */
int
st->ss.length += u8_uctomb (CHAR_CAST (uint8_t *, ds_end (st)), uc, 6);
}
+/* Appends N copies of S to ST. */
+void
+ds_put_substring_multiple (struct string *dst, struct substring src, size_t n)
+{
+ char *p = ds_put_uninit (dst, n * src.length);
+ for (size_t i = 0; i < n; i++)
+ {
+ memcpy (p, src.string, src.length);
+ p += src.length;
+ }
+}
+
/* If relocation has been enabled, replace ST,
with its relocated version */
void