parse FORMAT from config file
This commit is contained in:
@@ -8,8 +8,11 @@ typedef struct {
|
|||||||
char *name;
|
char *name;
|
||||||
char *desc;
|
char *desc;
|
||||||
char **groups;
|
char **groups;
|
||||||
int size;
|
int gsize;
|
||||||
int id;
|
char **arg_type;
|
||||||
|
char **arg_name;
|
||||||
|
int asize;
|
||||||
|
int id;
|
||||||
} id;
|
} id;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -129,7 +132,10 @@ id *add_id(database *r, char *idname, int i)
|
|||||||
if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); }
|
if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); }
|
||||||
r->i[r->isize].desc = NULL;
|
r->i[r->isize].desc = NULL;
|
||||||
r->i[r->isize].groups = NULL;
|
r->i[r->isize].groups = NULL;
|
||||||
r->i[r->isize].size = 0;
|
r->i[r->isize].gsize = 0;
|
||||||
|
r->i[r->isize].arg_type = NULL;
|
||||||
|
r->i[r->isize].arg_name = NULL;
|
||||||
|
r->i[r->isize].asize = 0;
|
||||||
r->i[r->isize].id = i;
|
r->i[r->isize].id = i;
|
||||||
r->isize++;
|
r->isize++;
|
||||||
qsort(r->i, r->isize, sizeof(id), id_cmp);
|
qsort(r->i, r->isize, sizeof(id), id_cmp);
|
||||||
@@ -172,16 +178,16 @@ void group_add_id(group *g, char *id)
|
|||||||
|
|
||||||
void id_add_group(id *i, char *group)
|
void id_add_group(id *i, char *group)
|
||||||
{
|
{
|
||||||
char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp);
|
char *g = bsearch(&group, i->groups, i->gsize, sizeof(char *), string_cmp);
|
||||||
if (g != NULL) return;
|
if (g != NULL) return;
|
||||||
|
|
||||||
if ((i->size & 1023) == 0) {
|
if ((i->gsize & 1023) == 0) {
|
||||||
i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *));
|
i->groups = realloc(i->groups, (i->gsize+1024) * sizeof(char *));
|
||||||
if (i->groups == NULL) abort();
|
if (i->groups == NULL) abort();
|
||||||
}
|
}
|
||||||
i->groups[i->size] = group;
|
i->groups[i->gsize] = group;
|
||||||
i->size++;
|
i->gsize++;
|
||||||
qsort(i->groups, i->size, sizeof(char *), string_cmp);
|
qsort(i->groups, i->gsize, sizeof(char *), string_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_groups(database *r, id *i, char *groups)
|
void add_groups(database *r, id *i, char *groups)
|
||||||
@@ -216,6 +222,76 @@ void add_desc(id *i, char *desc)
|
|||||||
i->desc = strdup(desc); if (i->desc == NULL) abort();
|
i->desc = strdup(desc); if (i->desc == NULL) abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *format_get_next_token(char **cur)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
char *end;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
start = *cur;
|
||||||
|
|
||||||
|
/* remove spaces */
|
||||||
|
while (*start && isspace(*start)) start ++;
|
||||||
|
if (*start == 0) return NULL;
|
||||||
|
|
||||||
|
/* special cases: ',' and ':' */
|
||||||
|
if (*start == ',' || *start == ':') { end = start + 1; goto special; }
|
||||||
|
|
||||||
|
end = start;
|
||||||
|
|
||||||
|
/* go to end of token */
|
||||||
|
while (*end && !isspace(*end) && *end != ',' && *end != ':') end++;
|
||||||
|
|
||||||
|
special:
|
||||||
|
ret = malloc(end-start+1); if (ret == NULL) abort();
|
||||||
|
memcpy(ret, start, end-start);
|
||||||
|
ret[end-start] = 0;
|
||||||
|
|
||||||
|
*cur = end;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_format(id *id, char *format)
|
||||||
|
{
|
||||||
|
char *cur = format;
|
||||||
|
char *type;
|
||||||
|
char *name;
|
||||||
|
char *sep;
|
||||||
|
while (1) {
|
||||||
|
/* parse next type/name: expected " <type> , <name> :" */
|
||||||
|
/* get type */
|
||||||
|
type = format_get_next_token(&cur);
|
||||||
|
if (type == NULL) break;
|
||||||
|
/* get comma */
|
||||||
|
sep = format_get_next_token(&cur);
|
||||||
|
if (sep == NULL || strcmp(sep, ",") != 0) goto error;
|
||||||
|
free(sep);
|
||||||
|
/* get name */
|
||||||
|
name = format_get_next_token(&cur);
|
||||||
|
if (name == NULL) goto error;
|
||||||
|
/* if there is a next token it has to be : */
|
||||||
|
sep = format_get_next_token(&cur);
|
||||||
|
if (sep != NULL && strcmp(sep, ":") != 0) goto error;
|
||||||
|
free(sep);
|
||||||
|
|
||||||
|
/* add type/name */
|
||||||
|
if (id->asize % 64 == 0) {
|
||||||
|
id->arg_type = realloc(id->arg_type, (id->asize + 64) * sizeof(char *));
|
||||||
|
if (id->arg_type == NULL) abort();
|
||||||
|
id->arg_name = realloc(id->arg_name, (id->asize + 64) * sizeof(char *));
|
||||||
|
if (id->arg_name == NULL) abort();
|
||||||
|
}
|
||||||
|
id->arg_type[id->asize] = type;
|
||||||
|
id->arg_name[id->asize] = name;
|
||||||
|
id->asize++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
printf("bad format '%s'\n", format);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
void *parse_database(char *filename)
|
void *parse_database(char *filename)
|
||||||
{
|
{
|
||||||
FILE *in;
|
FILE *in;
|
||||||
@@ -241,6 +317,7 @@ void *parse_database(char *filename)
|
|||||||
if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; }
|
if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; }
|
||||||
if (!strcmp(name, "GROUP")) add_groups(r, last_id, value);
|
if (!strcmp(name, "GROUP")) add_groups(r, last_id, value);
|
||||||
if (!strcmp(name, "DESC")) add_desc(last_id, value);
|
if (!strcmp(name, "DESC")) add_desc(last_id, value);
|
||||||
|
if (!strcmp(name, "FORMAT")) add_format(last_id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(in);
|
fclose(in);
|
||||||
@@ -260,9 +337,18 @@ void dump_database(void *_d)
|
|||||||
int j;
|
int j;
|
||||||
printf("ID %s [%s] [in %d group%s]\n",
|
printf("ID %s [%s] [in %d group%s]\n",
|
||||||
d->i[i].name, d->i[i].desc ? d->i[i].desc : "",
|
d->i[i].name, d->i[i].desc ? d->i[i].desc : "",
|
||||||
d->i[i].size, d->i[i].size > 1 ? "s" : "");
|
d->i[i].gsize, d->i[i].gsize > 1 ? "s" : "");
|
||||||
for (j = 0; j < d->i[i].size; j++)
|
for (j = 0; j < d->i[i].gsize; j++)
|
||||||
printf(" in GROUP: %s\n", d->i[i].groups[j]);
|
printf(" in GROUP: %s\n", d->i[i].groups[j]);
|
||||||
|
if (d->i[i].asize == 0) printf(" no FORMAT\n");
|
||||||
|
else {
|
||||||
|
int j;
|
||||||
|
printf(" FORMAT: ");
|
||||||
|
for (j = 0; j < d->i[i].asize; j++)
|
||||||
|
printf("'%s' , '%s' %s", d->i[i].arg_type[j], d->i[i].arg_name[j],
|
||||||
|
j == d->i[i].asize-1 ? "" : " : ");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < d->gsize; i++) {
|
for (i = 0; i < d->gsize; i++) {
|
||||||
int j;
|
int j;
|
||||||
|
|||||||
Reference in New Issue
Block a user