X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=file.c;h=06ba34df95dc4379e0d23974cc5f6222fd6c5701;hp=d5512084c1445399a26880bab28cbe329b6ab56d;hb=f18b4c6a13e288fae0fa0cdd92de63299e090dab;hpb=28d2cc2adde3f9ec077a77cf363045a17f116032 diff --git a/file.c b/file.c index d551208..06ba34d 100644 --- a/file.c +++ b/file.c @@ -102,6 +102,8 @@ static void uci_parse_package(struct uci_context *ctx, char **str, bool single) static void uci_parse_config(struct uci_context *ctx, char **str) { struct uci_parse_context *pctx = ctx->pctx; + struct uci_element *e; + struct uci_ptr ptr; char *name = NULL; char *type = NULL; @@ -117,61 +119,41 @@ static void uci_parse_config(struct uci_context *ctx, char **str) *str += strlen(*str) + 1; type = next_arg(ctx, str, true, false); - if (!uci_validate_str(type, false)) + if (!uci_validate_type(type)) uci_parse_error(ctx, type, "invalid character in field"); name = next_arg(ctx, str, false, true); assert_eol(ctx, str); - if (pctx->merge) { - UCI_TRAP_SAVE(ctx, error); - if (uci_set(ctx, pctx->package, name, NULL, type, NULL) != UCI_OK) - goto error; - UCI_TRAP_RESTORE(ctx); - return; -error: - UCI_THROW(ctx, ctx->err); - } else - pctx->section = uci_alloc_section(pctx->package, type, name); + if (!name) { + ctx->internal = !pctx->merge; + UCI_NESTED(uci_add_section, ctx, pctx->package, type, &pctx->section); + } else { + UCI_NESTED(uci_fill_ptr, ctx, &ptr, &pctx->package->e, false); + e = uci_lookup_list(&pctx->package->sections, name); + if (e) + ptr.s = uci_to_section(e); + ptr.section = name; + ptr.value = type; + + ctx->internal = !pctx->merge; + UCI_NESTED(uci_set, ctx, &ptr); + pctx->section = uci_to_section(ptr.last); + } } /* * parse the 'option' uci command (open a value) */ -static void uci_parse_option(struct uci_context *ctx, char **str) -{ - struct uci_parse_context *pctx = ctx->pctx; - char *name = NULL; - char *value = NULL; - - if (!pctx->section) - uci_parse_error(ctx, *str, "option command found before the first section"); - - /* command string null-terminated by strtok */ - *str += strlen(*str) + 1; - - name = next_arg(ctx, str, true, true); - value = next_arg(ctx, str, false, false); - assert_eol(ctx, str); - - if (pctx->merge) { - UCI_TRAP_SAVE(ctx, error); - uci_set(ctx, pctx->package, pctx->section->e.name, name, value, NULL); - UCI_TRAP_RESTORE(ctx); - return; -error: - UCI_THROW(ctx, ctx->err); - } else - uci_alloc_option(pctx->section, name, value); -} - -static void uci_parse_list(struct uci_context *ctx, char **str) +static void uci_parse_option(struct uci_context *ctx, char **str, bool list) { struct uci_parse_context *pctx = ctx->pctx; + struct uci_element *e; + struct uci_ptr ptr; char *name = NULL; char *value = NULL; if (!pctx->section) - uci_parse_error(ctx, *str, "list command found before the first section"); + uci_parse_error(ctx, *str, "option/list command found before the first section"); /* command string null-terminated by strtok */ *str += strlen(*str) + 1; @@ -180,30 +162,20 @@ static void uci_parse_list(struct uci_context *ctx, char **str) value = next_arg(ctx, str, false, false); assert_eol(ctx, str); - if (pctx->merge) { - UCI_TRAP_SAVE(ctx, error); - uci_add_list(ctx, pctx->package, pctx->section->e.name, name, value, NULL); - UCI_TRAP_RESTORE(ctx); - return; -error: - UCI_THROW(ctx, ctx->err); - } else { - struct uci_option *o; - struct uci_element *e; - - e = uci_lookup_list(&pctx->section->options, name); - o = uci_to_option(e); - if (!o) { - o = uci_alloc_list(pctx->section, name); - } else { - if (o->type != UCI_TYPE_LIST) - uci_parse_error(ctx, *str, "conflicting list/option keywords"); - } - UCI_INTERNAL(uci_add_element_list, ctx, o, value); - } + UCI_NESTED(uci_fill_ptr, ctx, &ptr, &pctx->section->e, false); + e = uci_lookup_list(&pctx->section->options, name); + if (e) + ptr.o = uci_to_option(e); + ptr.option = name; + ptr.value = value; + + ctx->internal = !pctx->merge; + if (list) + UCI_NESTED(uci_add_list, ctx, &ptr); + else + UCI_NESTED(uci_set, ctx, &ptr); } - /* * parse a complete input line, split up combined commands by ';' */ @@ -237,13 +209,13 @@ static void uci_parse_line(struct uci_context *ctx, bool single) break; case 'o': if ((word[1] == 0) || !strcmp(word + 1, "ption")) - uci_parse_option(ctx, &word); + uci_parse_option(ctx, &word, false); else goto invalid; break; case 'l': if ((word[1] == 0) || !strcmp(word + 1, "ist")) - uci_parse_list(ctx, &word); + uci_parse_option(ctx, &word, true); else goto invalid; break; @@ -381,7 +353,7 @@ int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct u * NB: the config file can still override the package name */ if (name) { - UCI_ASSERT(ctx, uci_validate_str(name, false)); + UCI_ASSERT(ctx, uci_validate_package(name)); pctx->name = name; } @@ -422,7 +394,7 @@ static char *uci_config_path(struct uci_context *ctx, const char *name) { char *filename; - UCI_ASSERT(ctx, uci_validate_str(name, false)); + UCI_ASSERT(ctx, uci_validate_package(name)); filename = uci_malloc(ctx, strlen(name) + strlen(ctx->confdir) + 2); sprintf(filename, "%s/%s", ctx->confdir, name); @@ -548,7 +520,7 @@ static char **uci_list_config_files(struct uci_context *ctx) if (!p) continue; - if (!uci_validate_name(p)) + if (!uci_validate_package(p)) continue; configs[i] = buf;