X-Git-Url: http://git.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=file.c;h=0b4f14ab045c759063794af3ba9745ac083f2dce;hp=19c6b07d6eb04b58e546b672fc6c9c119fdf5ef6;hb=3bff697cca125a6a4147e3bd1c469b36504e8237;hpb=8a06b55c63b13123ffcec33aff7f1fd752786dd1 diff --git a/file.c b/file.c index 19c6b07..0b4f14a 100644 --- a/file.c +++ b/file.c @@ -24,6 +24,7 @@ #include #include #include +#include static struct uci_backend uci_file_backend; @@ -163,6 +164,33 @@ error: uci_alloc_option(pctx->section, name, value); } +static void uci_parse_list(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, "list 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_add_list(ctx, pctx->package, pctx->section->e.name, name, value, NULL); + UCI_TRAP_RESTORE(ctx); + return; +error: + UCI_THROW(ctx, ctx->err); + } else + UCI_INTERNAL(uci_add_list, ctx, pctx->package, pctx->section->e.name, name, value, NULL); +} + /* * parse a complete input line, split up combined commands by ';' @@ -186,19 +214,33 @@ static void uci_parse_line(struct uci_context *ctx, bool single) case 'p': if ((word[1] == 0) || !strcmp(word + 1, "ackage")) uci_parse_package(ctx, &word, single); + else + goto invalid; break; case 'c': if ((word[1] == 0) || !strcmp(word + 1, "onfig")) uci_parse_config(ctx, &word); + else + goto invalid; break; case 'o': if ((word[1] == 0) || !strcmp(word + 1, "ption")) uci_parse_option(ctx, &word); + else + goto invalid; break; - default: - uci_parse_error(ctx, word, "unterminated command"); + case 'l': + if ((word[1] == 0) || !strcmp(word + 1, "ist")) + uci_parse_list(ctx, &word); + else + goto invalid; break; + default: + goto invalid; } + continue; +invalid: + uci_parse_error(ctx, word, "invalid command"); } while (1); } @@ -255,7 +297,7 @@ static char *uci_escape(struct uci_context *ctx, const char *str) static void uci_export_package(struct uci_package *p, FILE *stream, bool header) { struct uci_context *ctx = p->ctx; - struct uci_element *s, *o; + struct uci_element *s, *o, *i; if (header) fprintf(stream, "package '%s'\n", uci_escape(ctx, p->e.name)); @@ -267,8 +309,21 @@ static void uci_export_package(struct uci_package *p, FILE *stream, bool header) fprintf(stream, "\n"); uci_foreach_element(&sec->options, o) { struct uci_option *opt = uci_to_option(o); - fprintf(stream, "\toption '%s'", uci_escape(ctx, opt->e.name)); - fprintf(stream, " '%s'\n", uci_escape(ctx, opt->value)); + switch(opt->type) { + case UCI_TYPE_STRING: + fprintf(stream, "\toption '%s'", uci_escape(ctx, opt->e.name)); + fprintf(stream, " '%s'\n", uci_escape(ctx, opt->v.string)); + break; + case UCI_TYPE_LIST: + uci_foreach_element(&opt->v.list, i) { + fprintf(stream, "\tlist '%s'", uci_escape(ctx, opt->e.name)); + fprintf(stream, " '%s'\n", uci_escape(ctx, i->name)); + } + break; + default: + fprintf(stream, "\t# unknown type for option '%s'\n", uci_escape(ctx, opt->e.name)); + break; + } } } fprintf(stream, "\n");