mandatory anonymous section identifier
authorAntonio Paunovic <antonio.paunovic@sartura.hr>
Thu, 6 Oct 2016 13:47:56 +0000 (15:47 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 6 Oct 2016 17:55:30 +0000 (19:55 +0200)
This change makes sure there are no more anonymous (unnamed) sections
in configuration files. Previously it was optional and now the choice
is being removed.

All sections will have generated identifiers. This is important because
anonymous sections will be simpler to manipulate.

Signed-off-by: Antonio Paunovic <antonio.paunovic@sartura.hr>
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
file.c
list.c
uci.h

diff --git a/file.c b/file.c
index 7e1e4e6..76f7f32 100644 (file)
--- a/file.c
+++ b/file.c
@@ -288,6 +288,27 @@ int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char *
        return 0;
 }
 
+/*
+ * Fixup sections functions does the fixup of all sections for given package.
+ * It is used as a preprocessing step for fixing up existing anonymous sections
+ * from configurations.
+ *
+ * It uses uci_fixup_section() from list.c and then adds delta changes.
+ */
+static void
+uci_fixup_sections(struct uci_context *ctx, struct uci_package *p)
+{
+       struct uci_element *e;
+       struct uci_section *s;
+
+       uci_foreach_element(&p->sections, e) {
+               s = uci_to_section(e);
+               s->package->name_index++;
+               uci_fixup_section(ctx, s);
+               s->anonymous = false;
+       }
+}
+
 static int
 uci_fill_ptr(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_element *e)
 {
@@ -410,7 +431,6 @@ static void uci_parse_config(struct uci_context *ctx)
        char *name;
        char *type;
 
-       uci_fixup_section(ctx, ctx->pctx->section);
        if (!ctx->pctx->package) {
                if (!ctx->pctx->name)
                        uci_parse_error(ctx, "attempting to import a file without a package name");
@@ -606,8 +626,7 @@ static void uci_export_package(struct uci_package *p, FILE *stream, bool header)
        uci_foreach_element(&p->sections, s) {
                struct uci_section *sec = uci_to_section(s);
                fprintf(stream, "\nconfig %s", uci_escape(ctx, sec->type));
-               if (!sec->anonymous || (ctx->flags & UCI_FLAG_EXPORT_NAME))
-                       fprintf(stream, " '%s'", uci_escape(ctx, sec->e.name));
+               fprintf(stream, " '%s'", uci_escape(ctx, sec->e.name));
                fprintf(stream, "\n");
                uci_foreach_element(&sec->options, o) {
                        struct uci_option *opt = uci_to_option(o);
@@ -691,7 +710,6 @@ error:
                        UCI_THROW(ctx, ctx->err);
        }
 
-       uci_fixup_section(ctx, ctx->pctx->section);
        if (!pctx->package && name)
                uci_switch_config(ctx);
        if (package)
@@ -699,6 +717,7 @@ error:
        if (pctx->merge)
                pctx->package = NULL;
 
+       uci_fixup_sections(ctx, *package);
        pctx->name = NULL;
        uci_switch_config(ctx);
 
@@ -884,6 +903,7 @@ static struct uci_package *uci_file_load(struct uci_context *ctx, const char *na
        char *filename;
        bool confdir;
        FILE *file = NULL;
+       size_t n_change;
 
        switch (name[0]) {
        case '.':
@@ -913,7 +933,8 @@ static struct uci_package *uci_file_load(struct uci_context *ctx, const char *na
        if (package) {
                package->path = filename;
                package->has_delta = confdir;
-               uci_load_delta(ctx, package, false);
+               n_change = uci_load_delta(ctx, package, false);
+               package->name_index += n_change;
        }
 
 done:
diff --git a/list.c b/list.c
index 321861c..2b859a6 100644 (file)
--- a/list.c
+++ b/list.c
@@ -150,7 +150,7 @@ __private void uci_fixup_section(struct uci_context *ctx, struct uci_section *s)
        struct uci_element *e;
        char buf[16];
 
-       if (!s || s->e.name)
+       if (!s || !s->anonymous)
                return;
 
        /*
@@ -175,7 +175,7 @@ __private void uci_fixup_section(struct uci_context *ctx, struct uci_section *s)
                        break;
                }
        }
-       sprintf(buf, "cfg%02x%04x", ++s->package->n_section, hash % (1 << 16));
+       sprintf(buf, "cfg%02x%04x", s->package->name_index, hash % (1 << 16));
        s->e.name = uci_strdup(ctx, buf);
 }
 
@@ -274,7 +274,7 @@ uci_lookup_list(struct uci_list *list, const char *name)
        struct uci_element *e;
 
        uci_foreach_element(list, e) {
-               if (!strcmp(e->name, name))
+               if (e->name && !strcmp(e->name, name))
                        return e;
        }
        return NULL;
diff --git a/uci.h b/uci.h
index c5583ed..6a72b6a 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -435,6 +435,7 @@ struct uci_package
        struct uci_backend *backend;
        void *priv;
        int n_section;
+       int name_index;
        struct uci_list delta;
        struct uci_list saved_delta;
 };