#include "macro.h"
typedef enum ExtractFlags {
- EXTRACT_RELAX = 1 << 0,
- EXTRACT_CUNESCAPE = 1 << 1,
- EXTRACT_CUNESCAPE_RELAX = 1 << 2,
- EXTRACT_UNESCAPE_SEPARATORS = 1 << 3,
- EXTRACT_UNQUOTE = 1 << 4,
- EXTRACT_DONT_COALESCE_SEPARATORS = 1 << 5,
- EXTRACT_RETAIN_ESCAPE = 1 << 6,
+ EXTRACT_RELAX = 1 << 0, /* Allow unbalanced quote and eat up trailing backslash. */
+ EXTRACT_CUNESCAPE = 1 << 1, /* Unescape known escape sequences. */
+ EXTRACT_CUNESCAPE_RELAX = 1 << 2, /* Allow and keep unknown escape sequences, allow and keep trailing backslash. */
+ EXTRACT_UNESCAPE_SEPARATORS = 1 << 3, /* Unescape separators (those specified, or whitespace by default). */
+ EXTRACT_UNQUOTE = 1 << 4, /* Remove quoting with "" and ''. */
+ EXTRACT_DONT_COALESCE_SEPARATORS = 1 << 5, /* Don't treat multiple adjacent separators as one */
+ EXTRACT_RETAIN_ESCAPE = 1 << 6, /* Treat escape character '\' as any other character without special meaning */
+
+ /* Note that if no flags are specified, escaped escape characters will be silently stripped. */
} ExtractFlags;
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
free(t);
assert_se(p == NULL);
+ p = "\\:";
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_UNESCAPE_SEPARATORS) == 1);
+ assert_se(streq(t, ":"));
+ free(t);
+ assert_se(p == NULL);
+
+ p = "a\\:b";
+ assert_se(extract_first_word(&p, &t, ":", EXTRACT_UNESCAPE_SEPARATORS) == 1);
+ assert_se(streq(t, "a:b"));
+ free(t);
+ assert_se(p == NULL);
+
+ p = "a\\ b:c";
+ assert_se(extract_first_word(&p, &t, WHITESPACE ":", EXTRACT_UNESCAPE_SEPARATORS) == 1);
+ assert_se(streq(t, "a b"));
+ free(t);
+ assert_se(extract_first_word(&p, &t, WHITESPACE ":", EXTRACT_UNESCAPE_SEPARATORS) == 1);
+ assert_se(streq(t, "c"));
+ free(t);
+ assert_se(p == NULL);
+
p = "\\:";
assert_se(extract_first_word(&p, &t, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS) == 1);
assert_se(streq(t, ":"));