summaryrefslogtreecommitdiffstats
path: root/lib/strutils.c
diff options
context:
space:
mode:
authorKarel Zak2015-05-15 14:57:04 +0200
committerKarel Zak2015-05-15 14:57:04 +0200
commit548b9714e82ec7aca28958f5d5c2927a9b134fbe (patch)
tree4ccf0a33d6dff3998f2e34607e42d4f7119885a0 /lib/strutils.c
parentscript: Fix mangled EOF and hang on big endian (diff)
downloadkernel-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.c100
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[])