add initial work for option datatype abstraction
authorFelix Fietkau <nbd@openwrt.org>
Sun, 17 Aug 2008 18:57:52 +0000 (20:57 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 17 Aug 2008 18:57:52 +0000 (20:57 +0200)
cli.c
file.c
list.c
lua/uci.c
uci.h

diff --git a/cli.c b/cli.c
index 9787988..5ae345e 100644 (file)
--- a/cli.c
+++ b/cli.c
@@ -93,11 +93,19 @@ static void cli_perror(void)
 
 static void uci_show_option(struct uci_option *o)
 {
-      printf("%s.%s.%s=%s\n",
-                      o->section->package->e.name,
-                      o->section->e.name,
-                      o->e.name,
-                       o->value);
+       printf("%s.%s.%s=",
+               o->section->package->e.name,
+               o->section->e.name,
+               o->e.name);
+
+       switch(o->type) {
+       case UCI_TYPE_STRING:
+               printf("%s\n", o->v.string);
+               break;
+       default:
+               printf("<unknown>\n");
+               break;
+       }
 }
 
 static void uci_show_section(struct uci_section *p)
@@ -301,6 +309,7 @@ static int uci_do_section_cmd(int cmd, int argc, char **argv)
        struct uci_package *p = NULL;
        struct uci_section *s = NULL;
        struct uci_element *e = NULL;
+       struct uci_option *o = NULL;
        char *section = NULL;
        char *option = NULL;
        char *value = NULL;
@@ -343,16 +352,23 @@ static int uci_do_section_cmd(int cmd, int argc, char **argv)
        case CMD_GET:
                switch(e->type) {
                case UCI_TYPE_SECTION:
-                       value = s->type;
+                       printf("%s\n", s->type);
                        break;
                case UCI_TYPE_OPTION:
-                       value = uci_to_option(e)->value;
+                       o = uci_to_option(e);
+                       switch(o->type) {
+                       case UCI_TYPE_STRING:
+                               printf("%s\n", o->v.string);
+                               break;
+                       default:
+                               printf("<unknown>\n");
+                               break;
+                       }
                        break;
                default:
                        break;
                }
                /* throw the value to stdout */
-               printf("%s\n", value);
                break;
        case CMD_RENAME:
                ret = uci_rename(ctx, p, section, option, value);
diff --git a/file.c b/file.c
index ae0008f..4098e59 100644 (file)
--- a/file.c
+++ b/file.c
@@ -275,8 +275,15 @@ 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(o->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;
+                       default:
+                               fprintf(stream, "\t# unknown type for option '%s'\n", uci_escape(ctx, opt->e.name));
+                               break;
+                       }
                }
        }
        fprintf(stream, "\n");
diff --git a/list.c b/list.c
index 41cfc24..0924edf 100644 (file)
--- a/list.c
+++ b/list.c
@@ -98,9 +98,10 @@ uci_alloc_option(struct uci_section *s, const char *name, const char *value)
        struct uci_option *o;
 
        o = uci_alloc_element(ctx, option, name, strlen(value) + 1);
-       o->value = uci_dataptr(o);
+       o->type = UCI_TYPE_STRING;
+       o->v.string = uci_dataptr(o);
        o->section = s;
-       strcpy(o->value, value);
+       strcpy(o->v.string, value);
        uci_list_add(&s->options, &o->e.list);
 
        return o;
@@ -109,9 +110,15 @@ uci_alloc_option(struct uci_section *s, const char *name, const char *value)
 static inline void
 uci_free_option(struct uci_option *o)
 {
-       if ((o->value != uci_dataptr(o)) &&
-               (o->value != NULL))
-               free(o->value);
+       switch(o->type) {
+       case UCI_TYPE_STRING:
+               if ((o->v.string != uci_dataptr(o)) &&
+                       (o->v.string != NULL))
+                       free(o->v.string);
+               break;
+       default:
+               break;
+       }
        uci_free_element(&o->e);
 }
 
@@ -136,8 +143,16 @@ static void uci_fixup_section(struct uci_context *ctx, struct uci_section *s)
         */
        hash = djbhash(hash, s->type);
        uci_foreach_element(&s->options, e) {
+               struct uci_option *o;
                hash = djbhash(hash, e->name);
-               hash = djbhash(hash, uci_to_option(e)->value);
+               o = uci_to_option(e);
+               switch(o->type) {
+               case UCI_TYPE_STRING:
+                       hash = djbhash(hash, o->v.string);
+                       break;
+               default:
+                       break;
+               }
        }
        sprintf(buf, "cfg%02x%04x", ++s->package->n_section, hash % (1 << 16));
        s->e.name = uci_strdup(ctx, buf);
@@ -462,8 +477,10 @@ int uci_set_element_value(struct uci_context *ctx, struct uci_element **element,
                s = o->section;
                section = s->e.name;
                option = o->e.name;
+               if (o->type != UCI_TYPE_STRING)
+                       UCI_THROW(ctx, UCI_ERR_INVAL);
                /* matches the currently set value */
-               if (!strcmp(value, o->value))
+               if (!strcmp(value, o->v.string))
                        return 0;
                break;
        default:
@@ -485,7 +502,7 @@ int uci_set_element_value(struct uci_context *ctx, struct uci_element **element,
                uci_to_section(e)->type = str;
                break;
        case UCI_TYPE_OPTION:
-               uci_to_option(e)->value = str;
+               uci_to_option(e)->v.string = str;
                break;
        default:
                break;
index e3a1334..1535f56 100644 (file)
--- a/lua/uci.c
+++ b/lua/uci.c
@@ -100,8 +100,15 @@ static void uci_push_section(lua_State *L, struct uci_section *s)
 
        uci_foreach_element(&s->options, e) {
                struct uci_option *o = uci_to_option(e);
-               lua_pushstring(L, o->value);
-               lua_setfield(L, -2, o->e.name);
+               switch(o->type) {
+               case UCI_TYPE_STRING:
+                       lua_pushstring(L, o->v.string);
+                       lua_setfield(L, -2, o->e.name);
+                       break;
+               default:
+                       /* nothing to do yet */
+                       break;
+               }
        }
 }
 
@@ -201,6 +208,7 @@ uci_lua_get_any(lua_State *L, bool all)
 {
        struct uci_element *e = NULL;
        struct uci_package *p = NULL;
+       struct uci_option *o = NULL;
        const char *package = NULL;
        const char *section = NULL;
        const char *option = NULL;
@@ -254,7 +262,15 @@ uci_lua_get_any(lua_State *L, bool all)
                                lua_pushstring(L, uci_to_section(e)->type);
                        break;
                case UCI_TYPE_OPTION:
-                       lua_pushstring(L, uci_to_option(e)->value);
+                       o = uci_to_option(e);
+                       switch(o->type) {
+                       case UCI_TYPE_STRING:
+                               lua_pushstring(L, o->v.string);
+                               break;
+                       default:
+                               /* nothing to do yet */
+                               break;
+                       }
                        break;
                default:
                        err = UCI_ERR_INVAL;
diff --git a/uci.h b/uci.h
index 16c6966..d7fd1e2 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -319,6 +319,10 @@ enum uci_type {
        UCI_TYPE_BACKEND = 5,
 };
 
+enum uci_option_type {
+       UCI_TYPE_STRING = 0,
+};
+
 enum uci_flags {
        UCI_FLAG_STRICT =        (1 << 0), /* strict mode for the parser */
        UCI_FLAG_PERROR =        (1 << 1), /* print parser error messages */
@@ -404,7 +408,11 @@ struct uci_option
 {
        struct uci_element e;
        struct uci_section *section;
-       char *value;
+       enum uci_option_type type;
+       union {
+               struct uci_element *list;
+               char *string;
+       } v;
 };
 
 enum uci_command {