summaryrefslogtreecommitdiff
path: root/src/basic/string-util.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-09-26 22:17:40 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2018-09-26 22:48:17 +0900
commit8059aa9c92fe1f9847fc33b11670d3f48ad92fb4 (patch)
tree0c6a66ae805e1bf4d6477d36d5b20c8b409b3d8c /src/basic/string-util.c
parent2c3a11d86efdf54493ac18719af5aa76b0483d51 (diff)
downloadsystemd-8059aa9c92fe1f9847fc33b11670d3f48ad92fb4.tar.gz
strv: introduce 'relax' mode to strv_split_full()
If SPLIT_RELAX is specified, then it accepts unfinished quotes or missing separator after right quote.
Diffstat (limited to 'src/basic/string-util.c')
-rw-r--r--src/basic/string-util.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 0a40683493..07b11d4fc8 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -128,7 +128,7 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
}
/* Split a string into words. */
-const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
+const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags) {
const char *current;
current = *state;
@@ -144,20 +144,24 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
return NULL;
}
- if (quoted && strchr("\'\"", *current)) {
+ if (flags & SPLIT_QUOTES && strchr("\'\"", *current)) {
char quotechars[2] = {*current, '\0'};
*l = strcspn_escaped(current + 1, quotechars);
if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
(current[*l + 2] && !strchr(separator, current[*l + 2]))) {
/* right quote missing or garbage at the end */
+ if (flags & SPLIT_RELAX) {
+ *state = current + *l + 1 + (current[*l + 1] != '\0');
+ return current + 1;
+ }
*state = current;
return NULL;
}
*state = current++ + *l + 2;
- } else if (quoted) {
+ } else if (flags & SPLIT_QUOTES) {
*l = strcspn_escaped(current, separator);
- if (current[*l] && !strchr(separator, current[*l])) {
+ if (current[*l] && !strchr(separator, current[*l]) && !(flags & SPLIT_RELAX)) {
/* unfinished escape */
*state = current;
return NULL;