diff --git a/src/cw/cfg.c b/src/cw/cfg.c index 20311bce..dde783b4 100644 --- a/src/cw/cfg.c +++ b/src/cw/cfg.c @@ -7,28 +7,82 @@ #include "cfg.h" #include "val.h" -static int cmp(const void *k1,const void*k2){ - struct cw_Cfg_entry * e1,*e2; - e1=(struct cw_Cfg_entry *)k1; - e2=(struct cw_Cfg_entry *)k2; - return strcmp(e1->key,e2->key); +static const char *nextc(const char *s) +{ + while (isdigit(*s)) + s++; + return s; +} + +static int cmp0(const char *s1, const char *s2) +{ + + const char *d1, *d2; + int i1, i2, i; + + d1 = strchr(s1, '.'); + if (d1 == NULL) + return strcmp(s1, s2); + + d2 = strchr(s2, '.'); + if (d2 == NULL) + return strcmp(s1, s2); + + if ((d1 - s1) != (d2 - s2)) + return strcmp(s1, s2); + + if (strncmp(s1, s2, (d1 - s1)) != 0) + return strcmp(s1, s2); + + + + if (isdigit(d1[1])) { + i1 = atoi(d1 + 1); + } else { + return cmp0(d1 + 1, d2 + 1); + } + + if (isdigit(d2[1])) { + i2 = atoi(d2 + 1); + } else { + return cmp0(d1 + 1, d2 + 1); + } + + i = i1 - i2; + if (i == 0) { + return cmp0(nextc(d1 + 1), nextc(d2 + 1)); + } + return i; + + +} + +static int cmp(const void *k1, const void *k2) +{ + struct cw_Cfg_entry *e1, *e2; + e1 = (struct cw_Cfg_entry *) k1; + e2 = (struct cw_Cfg_entry *) k2; + + + return cmp0(e1->key, e2->key); +/* return strcmp(e1->key,e2->key);*/ } static void del(void *ptr) { - struct cw_Cfg_entry * e; - e=(struct cw_Cfg_entry *)ptr; - free(e->key); - free(e->val); + struct cw_Cfg_entry *e; + e = (struct cw_Cfg_entry *) ptr; + free((void *) e->key); + free((void *) e->val); } -cw_Cfg_t * cw_cfg_create() +cw_Cfg_t *cw_cfg_create() { return mavl_create(cmp, del, sizeof(struct cw_Cfg_entry)); -} +} -int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val) +int cw_cfg_set(cw_Cfg_t * cfg, const char *key, const char *val) { struct cw_Cfg_entry e; int replaced; @@ -37,12 +91,12 @@ int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val) if (!e.key) return 0; e.val = cw_strdup(val); - if (!e.val){ - free(e.key); + if (!e.val) { + free((void *) e.key); return 0; } - void * rc = mavl_replace(cfg,&e,&replaced); - if (!rc){ + void *rc = mavl_replace(cfg, &e, &replaced); + if (!rc) { del(&e); return 0; } @@ -52,32 +106,27 @@ int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val) return -1; } -const char * cw_cfg_get(cw_Cfg_t * cfg, char *key, const char *def) +const char *cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def) { - struct cw_Cfg_entry e,*r; + struct cw_Cfg_entry e, *r; e.key = key; - r = mavl_get(cfg,&e); + r = mavl_get(cfg, &e); if (!r) return def; return r->val; } -uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key) -{ -} - - -void cw_cfg_dump(cw_Cfg_t *cfg) +void cw_cfg_dump(cw_Cfg_t * cfg) { mavliter_t it; struct cw_Cfg_entry *e; - mavliter_init(&it,cfg); - mavliter_foreach(&it){ - + mavliter_init(&it, cfg); + mavliter_foreach(&it) { + e = mavliter_get(&it); - printf("%s: '%s'\n",e->key,e->val); + printf("%s: '%s'\n", e->key, e->val); //cw_dbg(dbglevel,"%s%s :%s: %s",prefix,data->key,type->get_type_name(data), value); } } @@ -97,23 +146,23 @@ struct parser { static int get_char(struct parser *p) { int c; - c = fgetc (p->f); + c = fgetc(p->f); p->pos++; - if (c=='\n'){ - p->prevpos=p->pos; - p->line ++; - p->pos=0; + if (c == '\n') { + p->prevpos = p->pos; + p->line++; + p->pos = 0; } return c; } -static void unget_char(struct parser *p,int c){ - ungetc(c,p->f); - if (c=='\n'){ +static void unget_char(struct parser *p, int c) +{ + ungetc(c, p->f); + if (c == '\n') { p->line--; - p->pos=p->prevpos; - } - else + p->pos = p->prevpos; + } else p->pos--; } @@ -123,67 +172,67 @@ static int get_char_q(struct parser *p) { int c; - while(1) { + while (1) { c = get_char(p); - if (c==EOF || c=='\n') + if (c == EOF || c == '\n') return c; - - if(c=='"' && !p->quote){ - p->quote=1; + + if (c == '"' && !p->quote) { + p->quote = 1; continue; } - if(c=='"' && p->quote){ - p->quote=0; + if (c == '"' && p->quote) { + p->quote = 0; continue; } break; } - - + + if (!p->quote) return c; - - if (c!='\\') + + if (c != '\\') return c; - + c = get_char(p); - switch(c){ + switch (c) { case EOF: return c; case 'n': return '\n'; - + case '\\': return '\\'; case '"': return '"'; default: - unget_char(p,c); + unget_char(p, c); return '\\'; } - + /* We will never reach here */ - /* return c;*/ + /* return c; */ } -static int skip_chars (struct parser *p, const char * chars) +static int skip_chars(struct parser *p, const char *chars) { int c; - - while ( (c = get_char (p)) != EOF) { - if (strchr (chars, c)) + + while ((c = get_char(p)) != EOF) { + if (strchr(chars, c)) continue; return c; } return c; } -static int skip_to_chars (struct parser *p, const char *chars) +static int skip_to_chars(struct parser *p, const char *chars) { int c; - - while ( (c = get_char (p)) != EOF) { - if (strchr (chars, c)) + + while ((c = get_char(p)) != EOF) { + if (strchr(chars, c)) return c; } return c; @@ -191,52 +240,56 @@ static int skip_to_chars (struct parser *p, const char *chars) -static int read_key (struct parser *p, char *key, int max_len) +static int read_key(struct parser *p, char *key, int max_len) { - int c,n; + int c, n; do { - c = skip_chars (p, " \t\n\a\v"); + c = skip_chars(p, " \t\n\a\v"); if (c == '#') { - c = skip_to_chars (p, "\n\a"); - + c = skip_to_chars(p, "\n\a"); + } else { break; } } while (c != EOF); - - unget_char(p,c); - c=get_char_q(p); - n=0; - while(c!=EOF && nquote && !isalnum(c) && !strchr("._/-()@#|{}[]\\",c)/*strchr(": \t\n\a",c)*/){ - unget_char(p,c); + unget_char(p, c); + c = get_char_q(p); + + n = 0; + while (c != EOF && n < max_len) { + if (!p->quote && !isalnum(c) + && !strchr("._/-()@#|{}[]\\", c) /*strchr(": \t\n\a",c) */ ) { + unget_char(p, c); break; } - key[n]=c; + key[n] = c; - c=get_char_q(p); + c = get_char_q(p); n++; } - key[n]=0; + key[n] = 0; return n; } -static int skip_to_colon(FILE *f,struct parser * p) +static int skip_to_colon(FILE * f, struct parser *p) { int c; - c = skip_chars (p, " \t"); - if (c!=':'){ - if (c=='\n'){ - unget_char(p,c); - sprintf(p->error,"Error at line %d, pos %d: Unexpected EOL, collon expected.", p->line, p->pos); + c = skip_chars(p, " \t"); + if (c != ':') { + if (c == '\n') { + unget_char(p, c); + sprintf(p->error, + "Error at line %d, pos %d: Unexpected EOL, collon expected.", + p->line, p->pos); return 0; } - sprintf(p->error,"Error at line %d, pos %d: Collon expected.", p->line, p->pos); + sprintf(p->error, "Error at line %d, pos %d: Collon expected.", + p->line, p->pos); return 0; } return 1; @@ -244,58 +297,58 @@ static int skip_to_colon(FILE *f,struct parser * p) -static int read_val(struct parser *p, char *val, int max_len){ - int c,n,quote; - if (!skip_to_colon(p->f,p)) +static int read_val(struct parser *p, char *val, int max_len) +{ + int c, n, quote; + if (!skip_to_colon(p->f, p)) return -1; - c = skip_chars (p, " \t"); - if (c=='"'){ - quote=1; - c=get_char(p); + c = skip_chars(p, " \t"); + if (c == '"') { + quote = 1; + c = get_char(p); + } else { + quote = 0; } - else{ - quote=0; - } - n=0; - while(c!=EOF && n0){ - while(n>0){ - if (isspace(val[n-1])) + + + if (!quote && n > 0) { + while (n > 0) { + if (isspace(val[n - 1])) n--; else break; } } - - val[n]=0; + + val[n] = 0; return n; @@ -303,20 +356,20 @@ static int read_val(struct parser *p, char *val, int max_len){ -int cw_cfg_read_line (FILE *f, struct parser *p, char * key, char *val) +int cw_cfg_read_line(FILE * f, struct parser *p, char *key, char *val) { int n; - - n = read_key (p,key,CW_CFG_MAX_KEY_LEN); - if (n==0) + + n = read_key(p, key, CW_CFG_MAX_KEY_LEN); + if (n == 0) return 1; - if (n==-1){ + if (n == -1) { return -1; } - n = read_val (p,val,CW_CFG_MAX_KEY_LEN); - if (n==-1){ + n = read_val(p, val, CW_CFG_MAX_KEY_LEN); + if (n == -1) { return -1; } return 0; @@ -328,45 +381,45 @@ int cw_cfg_read_from_file(FILE * f, cw_Cfg_t * cfg) char val[2048]; struct parser p; - p.line=1; - p.pos=0; - p.prevpos=0; - p.quote=0; - p.f=f; - - int rc; - int errs=0; + p.line = 1; + p.pos = 0; + p.prevpos = 0; + p.quote = 0; + p.f = f; + + int rc; + int errs = 0; + - do { - rc = cw_cfg_read_line(f,&p,key,val); - if (rc==-1){ - fprintf(stderr,"Error: %s\n",p.error); + rc = cw_cfg_read_line(f, &p, key, val); + if (rc == -1) { + fprintf(stderr, "Error: %s\n", p.error); errs++; } - if (rc != 0){ + if (rc != 0) { continue; } - cw_cfg_set(cfg,key,val); - + cw_cfg_set(cfg, key, val); + + + } while (rc == 0); - }while(rc==0); - return errs; } -int cw_cfg_load(const char *filename,cw_Cfg_t * cfg) +int cw_cfg_load(const char *filename, cw_Cfg_t * cfg) { int errs; - FILE *f = fopen(filename,"rb"); + FILE *f = fopen(filename, "rb"); if (!f) return errno; - errs = cw_cfg_read_from_file(f,cfg); + errs = cw_cfg_read_from_file(f, cfg); fclose(f); if (errs) @@ -378,64 +431,148 @@ int cw_cfg_load(const char *filename,cw_Cfg_t * cfg) static int cw_cfg_get_next_idx(cw_Cfg_t * cfg, const char *key, int n) { char ikey[CW_CFG_MAX_KEY_LEN]; - struct cw_Cfg_entry search, * result; - char *d; + struct cw_Cfg_entry search, *result; + const char *d; int i; - - sprintf(ikey,"%s.%d",key,n); - - search.key=ikey; - result = mavl_get_first(cfg,&search); - printf("KEY: %s\n",search.key); - printf("NNNNN: %s\n",result->key); + sprintf(ikey, "%s.%d", key, n); - - if (result==NULL) + search.key = ikey; + result = mavl_get_first(cfg, &search); + + printf("KEY: %s\n", search.key); + printf("NNNNN: %s\n", result->key); + + + if (result == NULL) return -1; - - d=NULL; - for (i = strlen(ikey); i>=0; i--){ - if (ikey[i]=='.'){ - d = result->key+i; + d = NULL; + for (i = strlen(ikey); i >= 0; i--) { + + if (ikey[i] == '.') { + d = result->key + i; break; } } - - if (d==NULL){ + + if (d == NULL) { return -1; } - - if(result->key[i]!='.'){ + + if (result->key[i] != '.') { return -1; } - - if (strncmp(result->key,ikey,i)!=0) + + if (strncmp(result->key, ikey, i) != 0) return -1; - - printf("TRANSFER %s\n",result->key+i+1); - return atoi(result->key+i+1); + + printf("TRANSFER %s\n", result->key + i + 1); + return atoi(result->key + i + 1); } -void cw_cfg_iterate(cw_Cfg_t * cfg) + + +static void pcb(char *dst, struct mavlnode *node) +{ + struct cw_Cfg_entry *e = mavlnode_dataptr(node); + sprintf(dst, "%s", e->key); +} + + +void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base) +{ + struct cw_Cfg_entry search; + search.key = base; + + mavliter_init(&(cfi->it), cfg); + mavliter_seek(&(cfi->it), &search, 0); + cfi->base = base; +} + + +const char *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *key) +{ + struct cw_Cfg_entry *e; + int bl, kl; + const char *d; + + e = mavliter_get(&(cfi->it)); + if (e == NULL) + return NULL; + + + bl = strlen(cfi->base); + kl = strlen(e->key); + + if (bl > kl) + return NULL; + + if (bl == kl) { + if (strcmp(cfi->base, e->key) != 0) + return NULL; + else { + mavliter_next(&(cfi->it)); + return e->val; + } + + } + d = strchr(e->key, '.'); + if (d == NULL) + return NULL; + + if (d - e->key != bl) + return NULL; + + if (strncmp(cfi->base, e->key, bl) != 0) + return NULL; + + mavliter_next(&(cfi->it)); + return e->val; +} + +void cw_cfg_iterate(cw_Cfg_t * cfg, const char *key) { printf("Iterate\n"); struct cw_Cfg_entry *e; struct cw_Cfg_entry search; - search.key="actube/listen"; + search.key = key; + struct mavliter it; + struct mavlnode *first; - int i=0; - i = cw_cfg_get_next_idx(cfg,"actube/listen",i); + mavl_print(cfg,pcb,180); - printf("This i %d\n",i); + printf("SEEK TO %s\n", search.key); - while ( (i = cw_cfg_get_next_idx(cfg,"actube/listen",i))!=-1) { + struct cw_Cfg_iter cfi; + cw_cfg_iter_init(cfg, &cfi, key); + const char *kee; - printf("Here i %d\n",i); - printf("we have key: %s.%d\n","actube/listen",i); - printf("Next=%d\n",i); + while ((kee = cw_cfg_iter_next(&cfi, NULL)) != NULL) { + printf("KEY===%s\n", kee); + } + + + + return; + + + mavliter_init(&it, cfg); + mavliter_seek(&it, &search, 0); + struct cw_Cfg_entry *en; + return; + + int i = 0; + i = cw_cfg_get_next_idx(cfg, "actube/listen", i); + + printf("This i %d\n", i); + + while ((i = cw_cfg_get_next_idx(cfg, "actube/listen", i)) != -1) { + + printf("Here i %d\n", i); + printf("we have key: %s.%d\n", "actube/listen", i); + printf("Next=%d\n", i); i++; }; @@ -443,11 +580,30 @@ void cw_cfg_iterate(cw_Cfg_t * cfg) - e = mavl_get_first(cfg,&search); - if (!e){ + e = mavl_get_first(cfg, &search); + if (!e) { printf("NULL\n"); return; } - printf("%s : %s\n",e->key,e->val); + printf("%s : %s\n", e->key, e->val); } + + +int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, const char *def) +{ + struct cw_Val v; + const char *s = cw_cfg_get(cfg,key,def); + CW_TYPE_BOOL->from_str(&v,s); + return v.val.boolean; +} + +uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key, const char * def) +{ + struct cw_Val v; + const char *s = cw_cfg_get(cfg,key,def); + CW_TYPE_WORD->from_str(&v,s); + return v.val.word; +} + + diff --git a/src/cw/cfg.h b/src/cw/cfg.h index 70443dd9..6109c0aa 100644 --- a/src/cw/cfg.h +++ b/src/cw/cfg.h @@ -14,11 +14,23 @@ int cw_cfg_read_from_file(FILE * file, cw_Cfg_t * cfg); int cw_cfg_load(const char *filename,cw_Cfg_t * cfg); struct cw_Cfg_entry{ - char *key; - char *val; + const char *key; + const char *val; }; -const char * cw_cfg_get(cw_Cfg_t * cfg, char *key, const char *def); + +struct cw_Cfg_iter{ + struct mavliter it; + const char *base; +}; + +const char * cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def); + +const char *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *key); +void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base); + +int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, const char *def); +uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key, const char * def); #endif