mirror of
https://github.com/systemd/systemd.git
synced 2024-12-24 17:43:40 +08:00
shared: util.c: unify split and split_quoted
This commit is contained in:
parent
e10e429f2d
commit
bf85c24daa
@ -359,8 +359,23 @@ int safe_atod(const char *s, double *ret_d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t strcspn_escaped(const char *s, const char *reject) {
|
||||
bool escaped = false;
|
||||
size_t n;
|
||||
|
||||
for (n=0; s[n]; n++) {
|
||||
if (escaped)
|
||||
escaped = false;
|
||||
else if (s[n] == '\\')
|
||||
escaped = true;
|
||||
else if (strchr(reject, s[n]))
|
||||
return n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Split a string into words. */
|
||||
char *split(const char *c, size_t *l, const char *separator, char **state) {
|
||||
char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state) {
|
||||
char *current;
|
||||
|
||||
current = *state ? *state : (char*) c;
|
||||
@ -369,70 +384,19 @@ char *split(const char *c, size_t *l, const char *separator, char **state) {
|
||||
return NULL;
|
||||
|
||||
current += strspn(current, separator);
|
||||
*l = strcspn(current, separator);
|
||||
*state = current+*l;
|
||||
|
||||
return (char*) current;
|
||||
}
|
||||
|
||||
/* Split a string into words, but consider strings enclosed in '' and
|
||||
* "" as words even if they include spaces. */
|
||||
char *split_quoted(const char *c, size_t *l, char **state) {
|
||||
const char *current, *e;
|
||||
bool escaped = false;
|
||||
|
||||
assert(c);
|
||||
assert(l);
|
||||
assert(state);
|
||||
|
||||
current = *state ? *state : c;
|
||||
|
||||
current += strspn(current, WHITESPACE);
|
||||
|
||||
if (*current == 0)
|
||||
if (!*current)
|
||||
return NULL;
|
||||
|
||||
else if (*current == '\'') {
|
||||
current ++;
|
||||
|
||||
for (e = current; *e; e++) {
|
||||
if (escaped)
|
||||
escaped = false;
|
||||
else if (*e == '\\')
|
||||
escaped = true;
|
||||
else if (*e == '\'')
|
||||
break;
|
||||
}
|
||||
|
||||
*l = e-current;
|
||||
*state = (char*) (*e == 0 ? e : e+1);
|
||||
|
||||
} else if (*current == '\"') {
|
||||
current ++;
|
||||
|
||||
for (e = current; *e; e++) {
|
||||
if (escaped)
|
||||
escaped = false;
|
||||
else if (*e == '\\')
|
||||
escaped = true;
|
||||
else if (*e == '\"')
|
||||
break;
|
||||
}
|
||||
|
||||
*l = e-current;
|
||||
*state = (char*) (*e == 0 ? e : e+1);
|
||||
|
||||
if (quoted && strchr("\'\"", *current)) {
|
||||
char quotechar = *(current++);
|
||||
*l = strcspn_escaped(current, (char[]){quotechar, '\0'});
|
||||
*state = current+*l+1;
|
||||
} else if (quoted) {
|
||||
*l = strcspn_escaped(current, separator);
|
||||
*state = current+*l;
|
||||
} else {
|
||||
for (e = current; *e; e++) {
|
||||
if (escaped)
|
||||
escaped = false;
|
||||
else if (*e == '\\')
|
||||
escaped = true;
|
||||
else if (strchr(WHITESPACE, *e))
|
||||
break;
|
||||
}
|
||||
*l = e-current;
|
||||
*state = (char*) e;
|
||||
*l = strcspn(current, separator);
|
||||
*state = current+*l;
|
||||
}
|
||||
|
||||
return (char*) current;
|
||||
|
@ -198,17 +198,22 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) {
|
||||
return safe_atolli(s, (long long int*) ret_i);
|
||||
}
|
||||
|
||||
char *split(const char *c, size_t *l, const char *separator, char **state);
|
||||
char *split_quoted(const char *c, size_t *l, char **state);
|
||||
char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state);
|
||||
|
||||
#define FOREACH_WORD(word, length, s, state) \
|
||||
for ((state) = NULL, (word) = split((s), &(length), WHITESPACE, &(state)); (word); (word) = split((s), &(length), WHITESPACE, &(state)))
|
||||
_FOREACH_WORD(word, length, s, WHITESPACE, false, state)
|
||||
|
||||
#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
|
||||
for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state)))
|
||||
_FOREACH_WORD(word, length, s, separator, false, state)
|
||||
|
||||
#define FOREACH_WORD_QUOTED(word, length, s, state) \
|
||||
for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state)))
|
||||
_FOREACH_WORD(word, length, s, WHITESPACE, true, state)
|
||||
|
||||
#define FOREACH_WORD_SEPARATOR_QUOTED(word, length, s, separator, state) \
|
||||
_FOREACH_WORD(word, length, s, separator, true, state)
|
||||
|
||||
#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
|
||||
for ((state) = NULL, (word) = split((s), &(length), (separator), (quoted), &(state)); (word); (word) = split((s), &(length), (separator), (quoted), &(state)))
|
||||
|
||||
pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
|
||||
int get_starttime_of_pid(pid_t pid, unsigned long long *st);
|
||||
|
Loading…
Reference in New Issue
Block a user