diff options
author | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-04-08 13:45:39 +0200 |
---|---|---|
committer | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2010-04-08 13:45:39 +0200 |
commit | 12f1f7d7301fcb06f9e7f5f5f116e7cfad19574d (patch) | |
tree | d47baef2dc1a35681643b5060511ff9f072dfcde | |
parent | b74f0b4baa0098899e0bfec4db981cd76ec3fd0f (diff) | |
download | latrace-12f1f7d7301fcb06f9e7f5f5f116e7cfad19574d.tar.gz latrace-12f1f7d7301fcb06f9e7f5f5f116e7cfad19574d.tar.xz latrace-12f1f7d7301fcb06f9e7f5f5f116e7cfad19574d.zip |
fixed enum handling (strtol failure)
added support for enum string refference definition
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/args.c | 98 | ||||
-rw-r--r-- | src/config.h | 1 |
3 files changed, 94 insertions, 9 deletions
@@ -1,3 +1,7 @@ +2009-04-08 Jiri Olsa <olsajiri@gmail.com> + * fixed enum handling (strtol failure) + * added support for enum string refference definition + 2009-03-01 Jiri Olsa <olsajiri@gmail.com> * Akos Pasztory <akos.pasztory@gmail.com> * added checks for asciidoc and xmlto @@ -280,6 +280,22 @@ static struct lt_enum_elem* get_enumelem(struct lt_config_shared *cfg, sizeof(struct lt_enum_elem), enum_comp); } +static struct lt_enum_elem* find_enumelem(struct lt_config_shared *cfg, + char *name, struct lt_enum *en) +{ + struct lt_enum_elem *elem; + int i; + + for(i = 0; en->cnt; i++) { + elem = &en->elems[i]; + + if (!strcmp(elem->name, name)) + return elem; + } + + return NULL; +} + int lt_args_add_enum(struct lt_config_shared *cfg, char *name, struct lt_list_head *h) { @@ -325,26 +341,77 @@ int lt_args_add_enum(struct lt_config_shared *cfg, char *name, if (NULL == (en->elems = malloc(sizeof(struct lt_enum_elem) * en->cnt))) return -1; - PRINT_VERBOSE(cfg, 3, "enum %s (%d elems)\n", + PRINT_VERBOSE(cfg, 3, "enum %s (%d elems) not fixed\n", en->name, en->cnt); + /* + * The enum element can be: + * + * 1) defined + * 2) undefined + * 3) defined via string reference + * + * ad 1) no work + * ad 2) value of previous element is used + * ad 3) we look for the string reference in defined elements' names + * + * This being said, following actions will happen now: + * + * - copy all the values to the prepared array + * - fix the values based on the above + * - sort the array + */ + lt_list_for_each_entry(elem, h, list) { - if (elem->undef) { + PRINT_VERBOSE(cfg, 3, "\t %s = %d/%s\n", + elem->name, elem->val, elem->strval); + + en->elems[i++] = *elem; + } + + PRINT_VERBOSE(cfg, 3, "enum %s (%d elems) fixed\n", + en->name, en->cnt); + + /* fixup values */ + for(i = 0; i < en->cnt; i++) { + elem = &en->elems[i]; + + if (!elem->undef) { + last = elem; + continue; + } + + if (elem->strval) { + /* undefined text value, try to find it in + * previous enum definitions */ + + struct lt_enum_elem *e; + + e = find_enumelem(cfg, elem->strval, en); + if (!e) { + printf("failed to find '%s=%s' enum definition\n", + elem->name, elem->strval); + return -1; + } + + elem->val = e->val; + + } else { + /* undefined value -> take last defined + 1 */ if (!last) elem->val = 0; else elem->val = last->val + 1; - elem->undef = 0; } PRINT_VERBOSE(cfg, 3, "\t %s = %d\n", elem->name, elem->val); - en->elems[i++] = *elem; last = elem; } + /* finaly sort the array */ qsort(en->elems, en->cnt, sizeof(struct lt_enum_elem), enum_comp); return 0; } @@ -361,19 +428,32 @@ struct lt_enum_elem* lt_args_get_enum(struct lt_config_shared *cfg, elem->undef = 1; if (val) { - long num = strtol(val, (char **) NULL, 10); + long num; + char *endptr; + + errno = 0; + num = strtol(val, &endptr, 10); + + /* parse errors */ if ((errno == ERANGE && (num == LONG_MAX || num == LONG_MIN)) || (errno != 0 && num == 0)) return NULL; - elem->val = num; - elem->undef = 0; + if (endptr != val) { + elem->val = num; + elem->undef = 0; + } else { + /* if no digits were found, we assume the + * value is set by string reference */ + elem->strval = strdup(val); + } + } elem->name = strdup(name); - PRINT_VERBOSE(cfg, 3, "enum elem %s = %d, undef = %d\n", - elem->name, elem->val, elem->undef); + PRINT_VERBOSE(cfg, 3, "enum elem %s = %d, strval %s, undef = %d\n", + elem->name, elem->val, elem->strval, elem->undef); return elem; } diff --git a/src/config.h b/src/config.h index 93e6196..bacc107 100644 --- a/src/config.h +++ b/src/config.h @@ -281,6 +281,7 @@ enum { struct lt_enum_elem { char *name; + char *strval; long val; int undef; struct lt_list_head list; |