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 7e1e4e6f0ddcdbb545c4e83efda52fb33031374a..76f7f322afbd4e9575d75fd0774643a184c637d9 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 321861c8eb7d741c17a1cc764e4e648635640b13..2b859a62c1b7717d0dc3c1502772d97768810218 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 c5583ed0f798a081e964ba120760c59d179b36e2..6a72b6a0f9eadc0b2061589041fec502ea9f364e 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;
 };