]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: move optstr parsing to lib/
authorKarel Zak <kzak@redhat.com>
Tue, 22 Mar 2022 10:09:07 +0000 (11:09 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 30 Mar 2022 09:14:31 +0000 (11:14 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/strutils.h
lib/strutils.c
libmount/src/optstr.c

index ae689a30ad22939456dad9af3c86836adf8e09a5..62129f6f30546e006af2fd67347c5473960872ae 100644 (file)
@@ -392,4 +392,6 @@ extern const char *split(const char **state, size_t *l, const char *separator, i
 extern int skip_fline(FILE *fp);
 extern int ul_stralnumcmp(const char *p1, const char *p2);
 
+extern int ul_optstr_next(char **optstr, char **name, size_t *namesz, char **value, size_t *valsz);
+
 #endif
index e85d265d2d273c6141e721653b3329523be4ba8b..cfbd35e677f62280682e3116dfdb594e677b0cb6 100644 (file)
@@ -1123,6 +1123,76 @@ int ul_stralnumcmp(const char *p1, const char *p2)
        return c1 - c2;
 }
 
+/*
+ * Parses the first option from @optstr. The @optstr pointer is set to the beginning
+ * of the next option. The options string looks like 'aaa,bbb=data,foo,bar="xxx"'.
+ *
+ * Note this function is used by libmount to parse mount options. Be careful when modify.
+ *
+ * Returns -EINVAL on parse error, 1 at the end of optstr and 0 on success.
+ */
+int ul_optstr_next(char **optstr, char **name, size_t *namesz,
+                  char **value, size_t *valsz)
+{
+       int open_quote = 0;
+       char *start = NULL, *stop = NULL, *p, *sep = NULL;
+       char *optstr0;
+
+       assert(optstr);
+       assert(*optstr);
+
+       optstr0 = *optstr;
+
+       if (name)
+               *name = NULL;
+       if (namesz)
+               *namesz = 0;
+       if (value)
+               *value = NULL;
+       if (valsz)
+               *valsz = 0;
+
+       /* trim leading commas as to not invalidate option
+        * strings with multiple consecutive commas */
+       while (optstr0 && *optstr0 == ',')
+               optstr0++;
+
+       for (p = optstr0; p && *p; p++) {
+               if (!start)
+                       start = p;              /* beginning of the option item */
+               if (*p == '"')
+                       open_quote ^= 1;        /* reverse the status */
+               if (open_quote)
+                       continue;               /* still in quoted block */
+               if (!sep && p > start && *p == '=')
+                       sep = p;                /* name and value separator */
+               if (*p == ',')
+                       stop = p;               /* terminate the option item */
+               else if (*(p + 1) == '\0')
+                       stop = p + 1;           /* end of optstr */
+               if (!start || !stop)
+                       continue;
+               if (stop <= start)
+                       return -EINVAL;
+
+               if (name)
+                       *name = start;
+               if (namesz)
+                       *namesz = sep ? sep - start : stop - start;
+               *optstr = *stop ? stop + 1 : stop;
+
+               if (sep) {
+                       if (value)
+                               *value = sep + 1;
+                       if (valsz)
+                               *valsz = stop - sep - 1;
+               }
+               return 0;
+       }
+
+       return 1;                               /* end of optstr */
+}
+
 #ifdef TEST_PROGRAM_STRUTILS
 struct testS {
        char *name;
index 5acc94eaec1fbdd86bb016e11502861d4b9fa083..5daa511a0cf34889494dd661e8f18f872627fbf4 100644 (file)
@@ -45,78 +45,6 @@ struct libmnt_optloc {
 #define mnt_optmap_entry_novalue(e) \
                (e && (e)->name && !strchr((e)->name, '=') && !((e)->mask & MNT_PREFIX))
 
-/*
- * Parses the first option from @optstr. The @optstr pointer is set to the beginning
- * of the next option.
- *
- * Returns -EINVAL on parse error, 1 at the end of optstr and 0 on success.
- */
-static int mnt_optstr_parse_next(char **optstr,         char **name, size_t *namesz,
-                                       char **value, size_t *valsz)
-{
-       int open_quote = 0;
-       char *start = NULL, *stop = NULL, *p, *sep = NULL;
-       char *optstr0;
-
-       assert(optstr);
-       assert(*optstr);
-
-       optstr0 = *optstr;
-
-       if (name)
-               *name = NULL;
-       if (namesz)
-               *namesz = 0;
-       if (value)
-               *value = NULL;
-       if (valsz)
-               *valsz = 0;
-
-       /* trim leading commas as to not invalidate option
-        * strings with multiple consecutive commas */
-       while (optstr0 && *optstr0 == ',')
-               optstr0++;
-
-       for (p = optstr0; p && *p; p++) {
-               if (!start)
-                       start = p;              /* beginning of the option item */
-               if (*p == '"')
-                       open_quote ^= 1;        /* reverse the status */
-               if (open_quote)
-                       continue;               /* still in quoted block */
-               if (!sep && p > start && *p == '=')
-                       sep = p;                /* name and value separator */
-               if (*p == ',')
-                       stop = p;               /* terminate the option item */
-               else if (*(p + 1) == '\0')
-                       stop = p + 1;           /* end of optstr */
-               if (!start || !stop)
-                       continue;
-               if (stop <= start)
-                       goto error;
-
-               if (name)
-                       *name = start;
-               if (namesz)
-                       *namesz = sep ? sep - start : stop - start;
-               *optstr = *stop ? stop + 1 : stop;
-
-               if (sep) {
-                       if (value)
-                               *value = sep + 1;
-                       if (valsz)
-                               *valsz = stop - sep - 1;
-               }
-               return 0;
-       }
-
-       return 1;                               /* end of optstr */
-
-error:
-       DBG(OPTIONS, ul_debug("parse error: \"%s\"", optstr0));
-       return -EINVAL;
-}
-
 /*
  * Locates the first option that matches @name. The @end is set to the
  * char behind the option (it means ',' or \0).
@@ -138,7 +66,7 @@ static int mnt_optstr_locate_option(char *optstr, const char *name,
        namesz = strlen(name);
 
        do {
-               rc = mnt_optstr_parse_next(&optstr, &n, &nsz,
+               rc = ul_optstr_next(&optstr, &n, &nsz,
                                        &ol->value, &ol->valsz);
                if (rc)
                        break;
@@ -172,7 +100,8 @@ int mnt_optstr_next_option(char **optstr, char **name, size_t *namesz,
 {
        if (!optstr || !*optstr)
                return -EINVAL;
-       return mnt_optstr_parse_next(optstr, name, namesz, value, valuesz);
+
+       return ul_optstr_next(optstr, name, namesz, value, valuesz);
 }
 
 static int __buffer_append_option(struct ul_buffer *buf,