Changeset 5665

Show
Ignore:
Timestamp:
02/23/10 11:19:17 (3 years ago)
Author:
blogic
Message:

luci2 - improve api for widget handling. widget properties can now be forced.

Location:
luci2/cbi2
Files:
3 added
1 removed
9 modified

Legend:

Unmodified
Added
Removed
  • luci2/cbi2/cbi.c

    r5664 r5665  
    8686} 
    8787 
    88 const char* cbi_find_prop(struct cbi_element *e, char *key) 
     88const char* cbi_find_prop(struct cbi_element *e, const char *key) 
    8989{ 
    9090    struct list_head *q; 
     
    107107} 
    108108 
    109 void cbi_get_element_name(struct cbi_element *e, char *buffer, int file) 
    110 { 
    111     const char *name; 
     109void cbi_get_element_id(struct cbi_element *e, char *buffer, int file) 
     110{ 
     111    const char *id; 
    112112    if(!e) 
    113113        return; 
    114     cbi_get_element_name(e->parent, buffer, file); 
    115     name = cbi_find_prop(e, "name"); 
     114    cbi_get_element_id(e->parent, buffer, file); 
     115    id = cbi_find_prop(e, "id"); 
     116    if(!id && (e->caps & UCI)) 
     117        id = cbi_find_prop(e, "uci"); 
     118    if(!id) 
     119        return; 
    116120    if(file && e->file && !e->parent) 
    117121    { 
     
    120124    } else if(*buffer) 
    121125        strcat(buffer, "."); 
    122     strcat(buffer, name); 
    123 } 
    124  
    125 void cbi_gen_default_name(struct cbi_element *e, int *count) 
     126    strcat(buffer, id); 
     127} 
     128 
     129void cbi_gen_default_id(struct cbi_element *e, int *count) 
    126130{ 
    127131    char tmp[128]; 
    128132    char buffer[256]; 
    129     const char *name = cbi_find_prop(e, "name"); 
    130     if(name) 
     133    const char *id = cbi_find_prop(e, "id"); 
     134    if(id) 
    131135        return; 
    132     name = cbi_find_prop(e, "uci"); 
    133     if(name) 
    134     { 
    135         cbi_add_property(e, "name", name, 1); 
     136    if(e->caps & UCI) 
     137        id = cbi_find_prop(e, "uci"); 
     138    if(!id) 
     139        id = cbi_find_prop(e, "name"); 
     140    if(id) 
     141    { 
     142        cbi_add_property(e, "id", id, 1); 
    136143        return; 
    137144    } 
     
    141148        snprintf(tmp, 127, "%s%d", e->widget, *count); 
    142149    tmp[127] = '\0'; 
    143     cbi_add_property(e, "name", tmp, 1); 
     150    cbi_add_property(e, "id", tmp, 1); 
    144151    *buffer = 0; 
    145152    if(e->parent) 
    146153    { 
    147         cbi_get_element_name(e->parent, buffer, 1); 
    148         printf("generating name for %s.%s\n", buffer, tmp); 
     154        cbi_get_element_id(e->parent, buffer, 1); 
     155        //printf("generating id for %s\n", buffer); 
     156        printf("generating id for %s\n", tmp); 
    149157    } else if(e->file) 
    150         printf("generating name for %s:%s\n", e->file->name, tmp); 
     158        printf("generating id for %s:%s\n", e->file->name, tmp); 
    151159    (*count)++; 
    152160} 
     
    231239        } 
    232240    } 
    233 /*  if((e->caps & PACKAGE) || (e->caps & SECTION && file)) 
    234         cbi_uci_mapping(ctx, e);*/ 
    235241    return e; 
    236242} 
     
    247253    } 
    248254    return 0; 
     255} 
     256 
     257void cbi_index_verify(struct cbi_element *e) 
     258{ 
     259    struct list_head *p; 
     260    struct cbi_widget *w = cbi_widget_find(e->widget); 
     261    if(w) 
     262        widget_verify(e, w); 
     263    if(e->broken) 
     264        return; 
     265    list_for_each(p, &e->elements) 
     266    { 
     267        struct cbi_element *e = container_of(p, struct cbi_element, list); 
     268        cbi_index_verify(e); 
     269    } 
    249270} 
    250271 
     
    262283            list_add_tail(&e->index, &ctx->globals); 
    263284        } 
     285        cbi_index_verify(e); 
     286    } 
     287} 
     288 
     289void cbi_index(struct cbi_ctx *ctx) 
     290{ 
     291    struct list_head *p; 
     292    list_for_each(p, &ctx->files) 
     293    { 
     294        struct cbi_file *f = container_of(p, struct cbi_file, list); 
     295        cbi_index_add(ctx, f); 
    264296    } 
    265297} 
     
    339371} 
    340372 
    341 int cbi_add_file(struct cbi_ctx *ctx, char *filename) 
     373int cbi_add_file(struct cbi_ctx *ctx, char *filename, int index) 
    342374{ 
    343375    struct stat st; 
     
    393425    } 
    394426    list_add_tail(&f->list, &ctx->files); 
    395     cbi_index_add(ctx, f); 
     427    if(index) 
     428        cbi_index_add(ctx, f); 
    396429    return 0; 
    397430 
     
    410443    struct list_head *p; 
    411444    char nl = (!list_empty(&e->elements)?('\n'):('\0')); 
     445    if(e->broken) 
     446        return; 
    412447    print_spaces(depth); 
    413448    printf("<%s:%s", e->namespace, e->widget); 
     
    440475    { 
    441476        struct cbi_element *e = container_of(p, struct cbi_element, index); 
    442         const char *name = cbi_find_prop(e, "name"); 
    443         if(name) 
    444             printf("%s -> %s\n", e->widget, name); 
     477        const char *id = cbi_find_prop(e, "id"); 
     478        if(id) 
     479            printf("%s -> %s\n", e->widget, id); 
    445480    } 
    446481} 
     
    474509        int i; 
    475510        for(i = 0; i < gl.gl_pathc; i++) 
    476             cbi_add_file(ctx, gl.gl_pathv[i]); 
     511            cbi_add_file(ctx, gl.gl_pathv[i], 0); 
    477512        globfree(&gl); 
    478513    } 
     
    501536        int i; 
    502537        for(i = 0; i < gl.gl_pathc; i++) 
    503             cbi_add_file(ctx, gl.gl_pathv[i]); 
     538            cbi_add_file(ctx, gl.gl_pathv[i], 1); 
    504539        globfree(&gl); 
    505540    } 
     
    543578{ 
    544579    struct cbi_ctx *ctx = cbi_load_files("/lib/luci2/*.luco"); 
     580    cbi_index(ctx); 
    545581    return ctx; 
    546582} 
  • luci2/cbi2/cbi.h

    r5664 r5665  
    66#include "uvl.h" 
    77#include "validate.h" 
     8 
     9#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 
    810 
    911#define CBI_LUCI        0x4C554349 
     
    5658    char *value; 
    5759    char *packge, *type, *option; 
     60    int broken; 
    5861    _validator validate; 
    5962}; 
     
    6972}; 
    7073 
     74#define PROP_OPTIONAL       0 
     75#define PROP_REQUIRED       1 
     76 
     77struct cbi_widget_property 
     78{ 
     79    const char *name; 
     80    int type; 
     81}; 
     82 
    7183struct cbi_widget 
    7284{ 
    7385    struct list_head list; 
    7486    char *name; 
     87    int caps; 
     88    int parent_caps; 
     89    struct cbi_widget_property *props; 
     90    int prop_count; 
    7591    int (*init)(struct cbi_ctx *ctx, struct cbi_element *e, int *count); 
    7692}; 
     
    8096void cbi_free_context(struct cbi_ctx *ctx); 
    8197void cbi_reindex(struct cbi_ctx *ctx); 
    82 void cbi_gen_default_name(struct cbi_element *e, int *count); 
    83 const char* cbi_find_prop(struct cbi_element *e, char *key); 
     98void cbi_gen_default_id(struct cbi_element *e, int *count); 
     99const char* cbi_find_prop(struct cbi_element *e, const char *key); 
    84100void cbi_add_property(struct cbi_element *e, const char *name, const char *val, int generated); 
     101void cbi_get_element_id(struct cbi_element *e, char *buffer, int file); 
     102 
    85103 
    86104void cbi_widget_register(char *name, struct cbi_widget *w); 
    87  
    88105#define WIDGET(widget) \ 
    89106void  __attribute__ ((constructor)) \ 
    90107    widget_##widget##_register(void) \ 
    91108    { \ 
    92         struct cbi_widget *w = malloc(sizeof(struct cbi_widget)); \ 
    93         memset(w, 0, sizeof(struct cbi_widget)); \ 
    94         w->name = strdup(#widget); \ 
    95         w->init = widget##_init; \ 
    96         cbi_widget_register(#widget, w); \ 
     109        if(widget.props) widget.prop_count = ARRAY_SIZE(widget##_props);\ 
     110        if(!widget.name) widget.name = strdup(#widget); \ 
     111        cbi_widget_register(#widget, & widget); \ 
    97112    } 
     113 
     114#include "widget.h" 
     115 
    98116#endif 
  • luci2/cbi2/Makefile

    r5664 r5665  
    1111    $(CC) $(CFLAGS) -o $@ $^ 
    1212 
    13 luci: luci.o cbi.o validate.c uvl.o blob.o validator/boolean.o widgets/page.o widgets/form.o widgets/element.o widgets/section.o widgets/option.o  
     13luci: luci.o cbi.o validate.c uvl.o blob.o widget.o validator/boolean.o widgets/page.o widgets/form.o widgets/section.o widgets/option.o widgets/field.o widgets/foreach.o  
    1414    $(CC) $(CFLAGS) -o $@ $^ 
    1515 
  • luci2/cbi2/network.luci

    r5664 r5665  
    1 <luci:page name="internet" uci="network"> 
     1 
     2<luci:page id="internet" uci="network"> 
    23    <luci:title>Page title</luci:title> 
    34    Page text 
    4     <luci:section uci="wan" named="1"> 
     5    <luci:section name="wan" uci="interface"> 
    56        <luci:title>Form title</luci:title> 
    67        Form text 
     
    1516        <luci:option uci="password">Password</luci:option> 
    1617        <luci:option uci="mtu">MTU</luci:option> 
    17         <luci:option name="custom">custom</luci:option> 
     18        <luci:field name="custom">custom</luci:field> 
    1819    </luci:section> 
    1920</luci:page> 
    2021 
    21 <luci:section uci="interface"> 
     22<luci:section package="network" uci="interface"> 
    2223    <luci:title>Lan Configuration</luci:title> 
    2324    Lan Configuration description 
     
    2627</luci:section> 
    2728 
    28 <luci:page> 
    29     <luci:section src="network.interface" name="wan" named="1"></luci:section> 
    30     <luci:section uci="dhcp.dhcp" named="1"> 
     29<luci:page uci="network"> 
     30    <luci:section src="network.interface" name="wan"></luci:section> 
     31    <luci:section package="dhcp" name="dhcp"> 
    3132        <luci:option uci="enable">Enable</luci:option> 
    3233        <luci:option uci="start">start_ip</luci:option> 
    3334        <luci:option uci="stop">stop_ip</luci:option> 
    34         <luci:foreach uci="dhcp.leases" state="1"> 
    35             <luci:element uci="ip">IP</luci:element> 
    36             <luci:element uci="mac">MAC</luci:element> 
     35        <luci:foreach uci="leases"> 
     36            <luci:element name="ip">IP</luci:element> 
     37            <luci:element name="mac">MAC</luci:element> 
    3738        </luci:foreach> 
    3839    </luci:section> 
    3940</luci:page> 
     41<luci:option uci="enable">Enable</luci:option> 
     42 
  • luci2/cbi2/widget.c

    r5664 r5665  
     1#include <stdio.h> 
     2#include "cbi.h" 
     3 
     4static int widget_find_prop(const char *name, struct cbi_widget *w) 
     5{ 
     6    int i; 
     7    for(i = 0; i < w->prop_count; i++) 
     8        if(!strcmp(w->props[i].name, name)) 
     9            return 0; 
     10    return 1; 
     11} 
     12 
     13int widget_verify_props(struct cbi_element *e, struct cbi_widget *w) 
     14{ 
     15    struct list_head *q; 
     16    int i; 
     17    char buf[256]; 
     18    *buf = 0; 
     19    for(i = 0; i < w->prop_count; i++) 
     20    { 
     21        if(w->props[i].type == PROP_REQUIRED) 
     22            if(!cbi_find_prop(e, w->props[i].name)) 
     23            { 
     24                cbi_get_element_id(e, buf, 1); 
     25                printf("%s - missing required property %s\n", buf, w->props[i].name); 
     26                e->broken = 1; 
     27                return 1; 
     28            } 
     29    } 
     30    list_for_each(q, &e->properties) 
     31    { 
     32        struct cbi_property *p = container_of(q, struct cbi_property, list); 
     33        if(widget_find_prop(p->key, w)) 
     34        { 
     35            cbi_get_element_id(e, buf, 1); 
     36            printf("%s - unknown property %s\n", buf, p->key); 
     37            e->broken = 1; 
     38            return 1; 
     39        } 
     40    }   return 0; 
     41} 
     42 
     43int widget_verify_parent_caps(struct cbi_element *e, struct cbi_widget *w) 
     44{ 
     45    char buf[256]; 
     46    *buf = 0; 
     47    if(!w->parent_caps || e->file) 
     48        return 0; 
     49    if(!e->parent) 
     50        goto error; 
     51    if((e->parent->caps & w->parent_caps)) 
     52        return 0; 
     53error: 
     54    e->broken = 1; 
     55    cbi_get_element_id(e, buf, 1); 
     56    printf("%s - parent capabilities were not meet\n", buf); 
     57    return 1; 
     58} 
     59 
     60int widget_verify_uci(struct cbi_element *e, struct cbi_widget *w) 
     61{ 
     62    if(!(w->caps | UCI)) 
     63        return 0; 
     64    if(w->caps & PACKAGE) 
     65    { 
     66    } 
     67    if(w->caps & SECTION) 
     68    { 
     69    } 
     70    if(w->caps & OPTION) 
     71    { 
     72    } 
     73    return 1; 
     74} 
     75 
     76int widget_verify(struct cbi_element *e, struct cbi_widget *w) 
     77{ 
     78    e->caps = w->caps; 
     79    if(widget_verify_parent_caps(e, w)) 
     80        return 1; 
     81    if(widget_verify_props(e, w)) 
     82        return 1; 
     83    if(widget_verify_uci(e, w)) 
     84        return 1; 
     85    return 0; 
     86} 
  • luci2/cbi2/widgets/form.c

    r5664 r5665  
    44{ 
    55    e->caps = SECTION; 
    6     cbi_gen_default_name(e, count); 
     6    cbi_gen_default_id(e, count); 
    77    return 0; 
    88} 
    99 
     10struct cbi_widget_property form_props[] = { 
     11    { "uci", PROP_REQUIRED }, 
     12    { "id", PROP_OPTIONAL }, 
     13}; 
     14 
     15struct cbi_widget form = { 
     16    .caps = PAGE | PACKAGE, 
     17    .props = form_props, 
     18    .init = form_init, 
     19}; 
     20 
    1021WIDGET(form) 
  • luci2/cbi2/widgets/option.c

    r5664 r5665  
    11#include "../cbi.h" 
     2 
     3struct cbi_widget_property option_props[] = { 
     4    { "uci", PROP_REQUIRED }, 
     5    { "section", PROP_OPTIONAL }, 
     6    { "package", PROP_OPTIONAL }, 
     7    { "id", PROP_OPTIONAL }, 
     8}; 
    29 
    310int option_init(struct cbi_ctx *ctx, struct cbi_element *e, int *count) 
    411{ 
    512    e->caps = UCI | OPTION; 
    6     cbi_gen_default_name(e, count); 
     13    cbi_gen_default_id(e, count); 
     14/*  if(widget_verify_parent_caps(e, SECTION)) 
     15        return 1; 
     16    if(widget_verify_props(e, option_props, ARRAY_SIZE(option_props))) 
     17        return 1;*/ 
    718    return 0; 
    819} 
    920 
     21struct cbi_widget option = { 
     22    .caps = UCI | OPTION, 
     23    .parent_caps = SECTION, 
     24    .props = option_props, 
     25    .init = option_init, 
     26}; 
     27 
    1028WIDGET(option) 
  • luci2/cbi2/widgets/page.c

    r5664 r5665  
    33int page_init(struct cbi_ctx *ctx, struct cbi_element *e, int *count) 
    44{ 
    5     const char *uci; 
    6     e->caps = PACKAGE | PAGE; 
    7     cbi_gen_default_name(e, count); 
    8     uci = cbi_find_prop(e, "uci"); 
    9     if(!uci && e->file) 
    10         cbi_add_property(e, "uci", e->file->name, 1); 
    11     else if(!uci) 
    12         cbi_add_property(e, "uci", cbi_find_prop(e, "name"), 1); 
     5    cbi_gen_default_id(e, count); 
    136    return 0; 
    147} 
    158 
     9struct cbi_widget_property page_props[] = { 
     10    { "uci", PROP_REQUIRED }, 
     11    { "id", PROP_OPTIONAL }, 
     12}; 
     13 
     14struct cbi_widget page = { 
     15    .caps = UCI | PAGE | PACKAGE, 
     16    .props = page_props, 
     17    .init = page_init, 
     18}; 
     19 
    1620WIDGET(page) 
  • luci2/cbi2/widgets/section.c

    r5664 r5665  
    44{ 
    55    e->caps = UCI | SECTION; 
    6     cbi_gen_default_name(e, count); 
     6    cbi_gen_default_id(e, count); 
    77    return 0; 
    88} 
    99 
     10struct cbi_widget_property section_props[] = { 
     11    { "uci", PROP_REQUIRED }, 
     12    { "name", PROP_OPTIONAL }, 
     13    { "package", PROP_OPTIONAL }, 
     14    { "id", PROP_OPTIONAL }, 
     15}; 
     16 
     17struct cbi_widget section = { 
     18    .caps = UCI | SECTION, 
     19    .parent_caps = PACKAGE, 
     20    .props = section_props, 
     21    .init = section_init, 
     22}; 
     23 
    1024WIDGET(section)