New cmp funtion to get sorted integer arrays

This commit is contained in:
7u83 2022-08-08 23:11:27 +02:00
parent 8db182a303
commit 7d28858a70
2 changed files with 351 additions and 183 deletions

View File

@ -7,28 +7,82 @@
#include "cfg.h" #include "cfg.h"
#include "val.h" #include "val.h"
static int cmp(const void *k1,const void*k2){ static const char *nextc(const char *s)
struct cw_Cfg_entry * e1,*e2; {
e1=(struct cw_Cfg_entry *)k1; while (isdigit(*s))
e2=(struct cw_Cfg_entry *)k2; s++;
return strcmp(e1->key,e2->key); 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) static void del(void *ptr)
{ {
struct cw_Cfg_entry * e; struct cw_Cfg_entry *e;
e=(struct cw_Cfg_entry *)ptr; e = (struct cw_Cfg_entry *) ptr;
free(e->key); free((void *) e->key);
free(e->val); 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)); 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; struct cw_Cfg_entry e;
int replaced; int replaced;
@ -37,12 +91,12 @@ int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val)
if (!e.key) if (!e.key)
return 0; return 0;
e.val = cw_strdup(val); e.val = cw_strdup(val);
if (!e.val){ if (!e.val) {
free(e.key); free((void *) e.key);
return 0; return 0;
} }
void * rc = mavl_replace(cfg,&e,&replaced); void *rc = mavl_replace(cfg, &e, &replaced);
if (!rc){ if (!rc) {
del(&e); del(&e);
return 0; return 0;
} }
@ -52,32 +106,27 @@ int cw_cfg_set(cw_Cfg_t * cfg,const char *key, const char *val)
return -1; 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; e.key = key;
r = mavl_get(cfg,&e); r = mavl_get(cfg, &e);
if (!r) if (!r)
return def; return def;
return r->val; 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; mavliter_t it;
struct cw_Cfg_entry *e; struct cw_Cfg_entry *e;
mavliter_init(&it,cfg); mavliter_init(&it, cfg);
mavliter_foreach(&it){ mavliter_foreach(&it) {
e = mavliter_get(&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); //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) static int get_char(struct parser *p)
{ {
int c; int c;
c = fgetc (p->f); c = fgetc(p->f);
p->pos++; p->pos++;
if (c=='\n'){ if (c == '\n') {
p->prevpos=p->pos; p->prevpos = p->pos;
p->line ++; p->line++;
p->pos=0; p->pos = 0;
} }
return c; return c;
} }
static void unget_char(struct parser *p,int c){ static void unget_char(struct parser *p, int c)
ungetc(c,p->f); {
if (c=='\n'){ ungetc(c, p->f);
if (c == '\n') {
p->line--; p->line--;
p->pos=p->prevpos; p->pos = p->prevpos;
} } else
else
p->pos--; p->pos--;
} }
@ -123,67 +172,67 @@ static int get_char_q(struct parser *p)
{ {
int c; int c;
while(1) { while (1) {
c = get_char(p); c = get_char(p);
if (c==EOF || c=='\n') if (c == EOF || c == '\n')
return c; return c;
if(c=='"' && !p->quote){ if (c == '"' && !p->quote) {
p->quote=1; p->quote = 1;
continue; continue;
} }
if(c=='"' && p->quote){ if (c == '"' && p->quote) {
p->quote=0; p->quote = 0;
continue; continue;
} }
break; break;
} }
if (!p->quote) if (!p->quote)
return c; return c;
if (c!='\\') if (c != '\\')
return c; return c;
c = get_char(p); c = get_char(p);
switch(c){ switch (c) {
case EOF: case EOF:
return c; return c;
case 'n': case 'n':
return '\n'; return '\n';
case '\\': case '\\':
return '\\'; return '\\';
case '"': case '"':
return '"'; return '"';
default: default:
unget_char(p,c); unget_char(p, c);
return '\\'; return '\\';
} }
/* We will never reach here */ /* 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; int c;
while ( (c = get_char (p)) != EOF) { while ((c = get_char(p)) != EOF) {
if (strchr (chars, c)) if (strchr(chars, c))
continue; continue;
return c; return c;
} }
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; int c;
while ( (c = get_char (p)) != EOF) { while ((c = get_char(p)) != EOF) {
if (strchr (chars, c)) if (strchr(chars, c))
return c; return 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 { do {
c = skip_chars (p, " \t\n\a\v"); c = skip_chars(p, " \t\n\a\v");
if (c == '#') { if (c == '#') {
c = skip_to_chars (p, "\n\a"); c = skip_to_chars(p, "\n\a");
} else { } else {
break; break;
} }
} while (c != EOF); } while (c != EOF);
unget_char(p,c);
c=get_char_q(p);
n=0; unget_char(p, c);
while(c!=EOF && n<max_len){ c = get_char_q(p);
if (!p->quote && !isalnum(c) && !strchr("._/-()@#|{}[]\\",c)/*strchr(": \t\n\a",c)*/){
unget_char(p,c); 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; break;
} }
key[n]=c; key[n] = c;
c=get_char_q(p); c = get_char_q(p);
n++; n++;
} }
key[n]=0; key[n] = 0;
return n; return n;
} }
static int skip_to_colon(FILE *f,struct parser * p) static int skip_to_colon(FILE * f, struct parser *p)
{ {
int c; int c;
c = skip_chars (p, " \t"); c = skip_chars(p, " \t");
if (c!=':'){ if (c != ':') {
if (c=='\n'){ if (c == '\n') {
unget_char(p,c); unget_char(p, c);
sprintf(p->error,"Error at line %d, pos %d: Unexpected EOL, collon expected.", p->line, p->pos); sprintf(p->error,
"Error at line %d, pos %d: Unexpected EOL, collon expected.",
p->line, p->pos);
return 0; 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 0;
} }
return 1; 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){ static int read_val(struct parser *p, char *val, int max_len)
int c,n,quote; {
if (!skip_to_colon(p->f,p)) int c, n, quote;
if (!skip_to_colon(p->f, p))
return -1; return -1;
c = skip_chars (p, " \t"); c = skip_chars(p, " \t");
if (c=='"'){ if (c == '"') {
quote=1; quote = 1;
c=get_char(p); c = get_char(p);
} else {
quote = 0;
} }
else{ n = 0;
quote=0; while (c != EOF && n < max_len) {
} if (quote && c == '"') {
n=0;
while(c!=EOF && n<max_len){
if (quote && c=='"'){
break; break;
} }
if (c=='\n'){ if (c == '\n') {
break; break;
} }
if (quote){ if (quote) {
if (c=='\\'){ if (c == '\\') {
c = get_char(p); c = get_char(p);
switch(c){ switch (c) {
case 'n': case 'n':
c='\n'; c = '\n';
break; break;
case '\\': case '\\':
break; break;
case '"': case '"':
break; break;
default: default:
unget_char(p,c); unget_char(p, c);
c='\\'; c = '\\';
} }
} }
} }
val[n++]=c; val[n++] = c;
c=get_char(p); c = get_char(p);
} }
if(!quote && n>0){ if (!quote && n > 0) {
while(n>0){ while (n > 0) {
if (isspace(val[n-1])) if (isspace(val[n - 1]))
n--; n--;
else else
break; break;
} }
} }
val[n]=0; val[n] = 0;
return n; 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; int n;
n = read_key (p,key,CW_CFG_MAX_KEY_LEN); n = read_key(p, key, CW_CFG_MAX_KEY_LEN);
if (n==0) if (n == 0)
return 1; return 1;
if (n==-1){ if (n == -1) {
return -1; return -1;
} }
n = read_val (p,val,CW_CFG_MAX_KEY_LEN); n = read_val(p, val, CW_CFG_MAX_KEY_LEN);
if (n==-1){ if (n == -1) {
return -1; return -1;
} }
return 0; return 0;
@ -328,45 +381,45 @@ int cw_cfg_read_from_file(FILE * f, cw_Cfg_t * cfg)
char val[2048]; char val[2048];
struct parser p; struct parser p;
p.line=1; p.line = 1;
p.pos=0; p.pos = 0;
p.prevpos=0; p.prevpos = 0;
p.quote=0; p.quote = 0;
p.f=f; p.f = f;
int rc; int rc;
int errs=0; int errs = 0;
do { do {
rc = cw_cfg_read_line(f,&p,key,val); rc = cw_cfg_read_line(f, &p, key, val);
if (rc==-1){ if (rc == -1) {
fprintf(stderr,"Error: %s\n",p.error); fprintf(stderr, "Error: %s\n", p.error);
errs++; errs++;
} }
if (rc != 0){ if (rc != 0) {
continue; continue;
} }
cw_cfg_set(cfg,key,val); cw_cfg_set(cfg, key, val);
} while (rc == 0);
}while(rc==0);
return errs; 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; int errs;
FILE *f = fopen(filename,"rb"); FILE *f = fopen(filename, "rb");
if (!f) if (!f)
return errno; return errno;
errs = cw_cfg_read_from_file(f,cfg); errs = cw_cfg_read_from_file(f, cfg);
fclose(f); fclose(f);
if (errs) 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) static int cw_cfg_get_next_idx(cw_Cfg_t * cfg, const char *key, int n)
{ {
char ikey[CW_CFG_MAX_KEY_LEN]; char ikey[CW_CFG_MAX_KEY_LEN];
struct cw_Cfg_entry search, * result; struct cw_Cfg_entry search, *result;
char *d; const char *d;
int i; int i;
sprintf(ikey,"%s.%d",key,n);
search.key=ikey;
result = mavl_get_first(cfg,&search);
printf("KEY: %s\n",search.key); sprintf(ikey, "%s.%d", key, n);
printf("NNNNN: %s\n",result->key);
search.key = ikey;
if (result==NULL) result = mavl_get_first(cfg, &search);
printf("KEY: %s\n", search.key);
printf("NNNNN: %s\n", result->key);
if (result == NULL)
return -1; return -1;
d=NULL;
for (i = strlen(ikey); i>=0; i--){
if (ikey[i]=='.'){ d = NULL;
d = result->key+i; for (i = strlen(ikey); i >= 0; i--) {
if (ikey[i] == '.') {
d = result->key + i;
break; break;
} }
} }
if (d==NULL){ if (d == NULL) {
return -1; return -1;
} }
if(result->key[i]!='.'){ if (result->key[i] != '.') {
return -1; return -1;
} }
if (strncmp(result->key,ikey,i)!=0) if (strncmp(result->key, ikey, i) != 0)
return -1; return -1;
printf("TRANSFER %s\n",result->key+i+1); printf("TRANSFER %s\n", result->key + i + 1);
return atoi(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"); printf("Iterate\n");
struct cw_Cfg_entry *e; struct cw_Cfg_entry *e;
struct cw_Cfg_entry search; struct cw_Cfg_entry search;
search.key="actube/listen"; search.key = key;
struct mavliter it;
struct mavlnode *first;
int i=0; mavl_print(cfg,pcb,180);
i = cw_cfg_get_next_idx(cfg,"actube/listen",i);
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); while ((kee = cw_cfg_iter_next(&cfi, NULL)) != NULL) {
printf("we have key: %s.%d\n","actube/listen",i); printf("KEY===%s\n", kee);
printf("Next=%d\n",i); }
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++; i++;
}; };
@ -443,11 +580,30 @@ void cw_cfg_iterate(cw_Cfg_t * cfg)
e = mavl_get_first(cfg,&search); e = mavl_get_first(cfg, &search);
if (!e){ if (!e) {
printf("NULL\n"); printf("NULL\n");
return; 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;
}

View File

@ -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); int cw_cfg_load(const char *filename,cw_Cfg_t * cfg);
struct cw_Cfg_entry{ struct cw_Cfg_entry{
char *key; const char *key;
char *val; 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 #endif