parser: fix precedence of quoting over ; as command terminator, thx to netprince...
[project/uci.git] / file.c
diff --git a/file.c b/file.c
index d2fdf58..5360ef7 100644 (file)
--- a/file.c
+++ b/file.c
@@ -35,6 +35,7 @@ static void assert_eol(struct uci_context *ctx, char **str)
 {
        char *tmp;
 
 {
        char *tmp;
 
+       skip_whitespace(ctx, str);
        tmp = next_arg(ctx, str, false, false);
        if (*tmp && (ctx->flags & UCI_FLAG_STRICT))
                uci_parse_error(ctx, *str, "too many arguments");
        tmp = next_arg(ctx, str, false, false);
        if (*tmp && (ctx->flags & UCI_FLAG_STRICT))
                uci_parse_error(ctx, *str, "too many arguments");
@@ -69,7 +70,7 @@ static void uci_switch_config(struct uci_context *ctx)
         * if an older config under the same name exists, unload it
         * ignore errors here, e.g. if the config was not found
         */
         * if an older config under the same name exists, unload it
         * ignore errors here, e.g. if the config was not found
         */
-       e = uci_lookup_list(ctx, &ctx->root, name);
+       e = uci_lookup_list(&ctx->root, name);
        if (e)
                UCI_THROW(ctx, UCI_ERR_DUPLICATE);
        pctx->package = uci_alloc_package(ctx, name);
        if (e)
                UCI_THROW(ctx, UCI_ERR_DUPLICATE);
        pctx->package = uci_alloc_package(ctx, name);
@@ -122,7 +123,8 @@ static void uci_parse_config(struct uci_context *ctx, char **str)
 
        if (pctx->merge) {
                UCI_TRAP_SAVE(ctx, error);
 
        if (pctx->merge) {
                UCI_TRAP_SAVE(ctx, error);
-               uci_set(ctx, pctx->package, name, NULL, type, NULL);
+               if (uci_set(ctx, pctx->package, name, NULL, type, NULL) != UCI_OK)
+                       goto error;
                UCI_TRAP_RESTORE(ctx);
                return;
 error:
                UCI_TRAP_RESTORE(ctx);
                return;
 error:
@@ -168,19 +170,17 @@ error:
 static void uci_parse_line(struct uci_context *ctx, bool single)
 {
        struct uci_parse_context *pctx = ctx->pctx;
 static void uci_parse_line(struct uci_context *ctx, bool single)
 {
        struct uci_parse_context *pctx = ctx->pctx;
-       char *word, *brk = NULL;
-
-       for (word = strtok_r(pctx->buf, ";", &brk);
-                word;
-                word = strtok_r(NULL, ";", &brk)) {
-
-               char *pbrk = NULL;
-               word = strtok_r(word, " \t", &pbrk);
+       char *word, *brk;
 
 
+       word = pctx->buf;
+       do {
+               brk = NULL;
+               word = strtok_r(word, " \t", &brk);
                if (!word)
                if (!word)
-                       continue;
+                       return;
 
                switch(word[0]) {
 
                switch(word[0]) {
+                       case 0:
                        case '#':
                                return;
                        case 'p':
                        case '#':
                                return;
                        case 'p':
@@ -199,7 +199,7 @@ static void uci_parse_line(struct uci_context *ctx, bool single)
                                uci_parse_error(ctx, word, "unterminated command");
                                break;
                }
                                uci_parse_error(ctx, word, "unterminated command");
                                break;
                }
-       }
+       } while (1);
 }
 
 /* max number of characters that escaping adds to the string */
 }
 
 /* max number of characters that escaping adds to the string */
@@ -329,6 +329,8 @@ error:
        }
 
        uci_fixup_section(ctx, ctx->pctx->section);
        }
 
        uci_fixup_section(ctx, ctx->pctx->section);
+       if (!pctx->package && name)
+               uci_switch_config(ctx);
        if (package)
                *package = pctx->package;
        if (pctx->merge)
        if (package)
                *package = pctx->package;
        if (pctx->merge)
@@ -527,9 +529,8 @@ done:
        return package;
 }
 
        return package;
 }
 
-static struct uci_backend uci_file_backend = {
-       .name = "file",
+static UCI_BACKEND(uci_file_backend, "file",
        .load = uci_file_load,
        .commit = uci_file_commit,
        .list_configs = uci_list_config_files,
        .load = uci_file_load,
        .commit = uci_file_commit,
        .list_configs = uci_list_config_files,
-};
+);