#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
+#include <glob.h>
static struct uci_backend uci_file_backend;
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 ';'
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);
}
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));
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");