diff options
author | Karel Zak | 2015-05-15 14:57:04 +0200 |
---|---|---|
committer | Karel Zak | 2015-05-15 14:57:04 +0200 |
commit | 548b9714e82ec7aca28958f5d5c2927a9b134fbe (patch) | |
tree | 4ccf0a33d6dff3998f2e34607e42d4f7119885a0 /lib/strutils.c | |
parent | script: Fix mangled EOF and hang on big endian (diff) | |
download | kernel-qcow2-util-linux-548b9714e82ec7aca28958f5d5c2927a9b134fbe.tar.gz kernel-qcow2-util-linux-548b9714e82ec7aca28958f5d5c2927a9b134fbe.tar.xz kernel-qcow2-util-linux-548b9714e82ec7aca28958f5d5c2927a9b134fbe.zip |
lib/strv: add new functions (from systemd)
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/strutils.c')
-rw-r--r-- | lib/strutils.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/strutils.c b/lib/strutils.c index b8fd2eb56..cc90e043d 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -760,6 +760,106 @@ int streq_except_trailing_slash(const char *s1, const char *s2) } +char *strnappend(const char *s, const char *suffix, size_t b) +{ + size_t a; + char *r; + + if (!s && !suffix) + return strdup(""); + if (!s) + return strndup(suffix, b); + if (!suffix) + return strdup(s); + + assert(s); + assert(suffix); + + a = strlen(s); + if (b > ((size_t) -1) - a) + return NULL; + + r = malloc(a + b + 1); + if (!r) + return NULL; + + memcpy(r, s, a); + memcpy(r + a, suffix, b); + r[a+b] = 0; + + return r; +} + +char *strappend(const char *s, const char *suffix) +{ + return strnappend(s, suffix, suffix ? strlen(suffix) : 0); +} + + +static size_t strcspn_escaped(const char *s, const char *reject) +{ + int escaped = 0; + int n; + + for (n=0; s[n]; n++) { + if (escaped) + escaped = 0; + else if (s[n] == '\\') + escaped = 1; + else if (strchr(reject, s[n])) + break; + } + + /* if s ends in \, return index of previous char */ + return n - escaped; +} + +/* Split a string into words. */ +const char *split(const char **state, size_t *l, const char *separator, int quoted) +{ + const char *current; + + current = *state; + + if (!*current) { + assert(**state == '\0'); + return NULL; + } + + current += strspn(current, separator); + if (!*current) { + *state = current; + return NULL; + } + + if (quoted && 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 */ + *state = current; + return NULL; + } + *state = current++ + *l + 2; + } else if (quoted) { + *l = strcspn_escaped(current, separator); + if (current[*l] && !strchr(separator, current[*l])) { + /* unfinished escape */ + *state = current; + return NULL; + } + *state = current + *l; + } else { + *l = strcspn(current, separator); + *state = current + *l; + } + + return current; +} + + #ifdef TEST_PROGRAM int main(int argc, char *argv[]) |