]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: consolidate script parser code
authorKarel Zak <kzak@redhat.com>
Wed, 8 Oct 2014 10:59:50 +0000 (12:59 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 8 Oct 2014 10:59:50 +0000 (12:59 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/src/script.c

index e01d8f8f0c74f8a3e19b454b1483beb5bf594706..a737c26aa58fb79167a38cdf67a6a0bb19c36278 100644 (file)
@@ -464,81 +464,72 @@ done:
 
 }
 
-static char *next_separator(char *s)
+/* returns zero terminated string with next token and @str is updated */
+static char *next_token(char **str)
 {
-       char *end;
+       char *tk_begin = NULL,
+            *tk_end = NULL,
+            *end = NULL,
+            *p;
+       int open_quote = 0;
+
+       for (p = *str; p && *p; p++) {
+               if (!tk_begin) {
+                       if (isblank(*p))
+                               continue;
+                       tk_begin = p;
+               }
+               if (*p == '"')
+                       open_quote ^= 1;
+               if (open_quote)
+                       continue;
+               if (isblank(*p) || *p == ',' || *p == ';' || *p == '"' )
+                       tk_end = p;
+               else if (*(p + 1) == '\0')
+                       tk_end = p + 1;
+               if (tk_begin && tk_end)
+                       break;
+       }
 
-       if ((end = strchr(s, ',')) ||
-           (end = strchr(s, ';')) ||
-           (end = strchr(s, ' ')))
-               return end;
+       if (!tk_end)
+               return NULL;
+       end = isblank(*tk_end) ? (char *) skip_blank(tk_end) : tk_end;
+       if (*end == ',' || *end == ';')
+               end++;
 
-       return NULL;
+       *tk_end = '\0';
+       *str = end;
+       return tk_begin;
 }
 
 static int next_number(char **s, uint64_t *num, int *power)
 {
-       char *end = NULL;
-       int rc;
+       char *tk;
+       int rc = -EINVAL;
 
        assert(num);
        assert(s);
 
-       *s = (char *) skip_blank(*s);
-       if (!**s)
-               return -1;
-
-       end = next_separator(*s);
-       if (end)
-               *end = '\0';
-
-       rc = parse_size(*s, (uintmax_t *) num, power);
-       if (end)
-               *s = ++end;
-       else
-               while (**s) (*s)++;
-
+       tk = next_token(s);
+       if (tk)
+               rc = parse_size(tk, (uintmax_t *) num, power);
        return rc;
 }
 
 static int next_string(char **s, char **str)
 {
-       char *xend = NULL, *end = NULL;
+       char *tk;
+       int rc = -EINVAL;
 
-       assert(str);
        assert(s);
+       assert(str);
 
-       *s = (char *) skip_blank(*s);
-       if (!**s)
-               return -1;
-
-       if (**s == '"') {
-               ++(*s);
-               xend = strchr(*s, '"');
-               if (!xend)
-                       return -EINVAL;
-               end = next_separator(xend);
-       } else
-               xend = end = next_separator(*s);
-
-       if (xend) {
-               *str = strndup(*s, xend - *s);
-               *s = end ? end + 1 : xend + 1;
-       } else {
-               *str = strdup(*s);
-               while (**s) (*s)++;
-       }
-
-       if (!*str)
-               return -ENOMEM;
-
-       if (xend == end)
-               ltrim_whitespace((unsigned char *) *str);
-       if (!**str) {
-               free(*str);
-               *str = NULL;
+       tk = next_token(s);
+       if (tk) {
+               *str = strdup(tk);
+               rc = !*str ? -ENOMEM : 0;
        }
-       return 0;
+       return rc;
 }
 
 static int partno_from_devname(char *s)
@@ -600,9 +591,6 @@ static int parse_script_line(struct fdisk_script *dp, char *s)
                p = s;
 
        while (rc == 0 && p && *p) {
-               while (isblank(*p)) p++;
-               if (!*p)
-                       break;
 
                DBG(SCRIPT, ul_debugobj(dp, " parsing '%s'", p));
 
@@ -626,33 +614,26 @@ static int parse_script_line(struct fdisk_script *dp, char *s)
                        }
 
                } else if (!strncasecmp(p, "bootable", 8)) {
-                       char *x;
-
-                       p += 8;
-                       x = next_separator(p);
-                       if (x)
-                               p = x + 1;
-                       pa->boot = 1;
+                       char *tk = next_token(&p);
+                       if (strcmp(tk, "bootable") == 0)
+                               pa->boot = 1;
+                       else
+                               rc = -EINVAL;
 
                } else if (!strncasecmp(p, "attrs=", 6)) {
                        p += 6;
                        rc = next_string(&p, &pa->attrs);
-                       if (rc)
-                               break;
 
                } else if (!strncasecmp(p, "uuid=", 5)) {
                        p += 5;
                        rc = next_string(&p, &pa->uuid);
-                       if (rc)
-                               break;
 
                } else if (!strncasecmp(p, "name=", 5)) {
                        p += 5;
                        rc = next_string(&p, &pa->name);
-                       if (rc)
-                               break;
 
                } else if (!strncasecmp(p, "type=", 5) ||
+
                           !strncasecmp(p, "Id=", 3)) {         /* backward compatiility */
                        char *type;
 
@@ -815,18 +796,17 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
                        }
                        break;
                case ITEM_BOOTABLE:
-                       if (*p == ',')
+                       if (*p == ',' || *p == ';')
                                break;
-                       if (*p == '*' &&
-                           (!*(p + 1) || *(p + 1) == ' ' || *(p + 1) == ',' || *(p + 1) == ';')) {
-                               pa->boot = 1;
-                               p++;
-                       } else if (*p == '-' &&
-                           (!*(p + 1) || *(p + 1) == ' ' || *(p + 1) == ',' || *(p + 1) == ';')) {
-                               pa->boot = 0;
-                               p++;
-                       } else
-                               rc = -EINVAL;
+                       else {
+                               char *tk = next_token(&p);
+                               if (tk && *tk == '*' && *(tk + 1) == '\0')
+                                       pa->boot = 1;
+                               else if (tk && *tk == '-' && *(tk + 1) == '\0')
+                                       pa->boot = 0;
+                               else
+                                       rc = -EINVAL;
+                       }
                        break;
                default:
                        break;