switch (state) {
case START:
- if (c == 0)
+ if (c == 0) {
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
+ if (!GREEDY_REALLOC(s, allocated, sz+1))
+ return -ENOMEM;
goto finish_force_terminate;
- else if (strchr(separators, c))
+ } else if (strchr(separators, c)) {
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
+ if (!GREEDY_REALLOC(s, allocated, sz+1))
+ return -ENOMEM;
+ (*p) ++;
+ goto finish_force_next;
+ }
break;
+ }
state = VALUE;
/* fallthrough */
return -ENOMEM;
state = DOUBLE_QUOTE;
- } else if (strchr(separators, c))
+ } else if (strchr(separators, c)) {
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
+ (*p) ++;
+ goto finish_force_next;
+ }
state = SEPARATOR;
- else {
+ } else {
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
case SEPARATOR:
if (c == 0)
- goto finish;
+ goto finish_force_terminate;
+ if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
+ goto finish_force_next;
if (!strchr(separators, c))
goto finish;
-
break;
}
return 0;
}
+finish_force_next:
s[sz] = 0;
*ret = s;
s = NULL;
EXTRACT_CUNESCAPE = 2,
EXTRACT_CUNESCAPE_RELAX = 4,
EXTRACT_QUOTES = 8,
+ EXTRACT_DONT_COALESCE_SEPARATORS = 16,
} ExtractFlags;
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
assert_se(streq(t, ""));
free(t);
assert_se(isempty(p));
+
+ p = original = ":foo\\:bar::waldo:";
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+ assert_se(t);
+ assert_se(streq(t, ""));
+ free(t);
+ assert_se(p == original + 1);
+
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+ assert_se(streq(t, "foo:bar"));
+ free(t);
+ assert_se(p == original + 10);
+
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+ assert_se(t);
+ assert_se(streq(t, ""));
+ free(t);
+ assert_se(p == original + 11);
+
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+ assert_se(streq(t, "waldo"));
+ free(t);
+ assert_se(p == original + 17);
+
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+ assert_se(streq(t, ""));
+ free(t);
+ assert_se(p == NULL);
+
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
+ assert_se(!t);
+ assert_se(!p);
}
static void test_extract_first_word_and_warn(void) {