diff options
Diffstat (limited to 'keyword.c')
-rw-r--r-- | keyword.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/keyword.c b/keyword.c new file mode 100644 index 0000000..8b92191 --- /dev/null +++ b/keyword.c @@ -0,0 +1,81 @@ +#include <time.h> +#include "keyword.h" + +keyword_val get_keyword_value(const keyword *key, char *value, int *error) { + keyword_val val = {0}; + int dummy = 0; + error = (error != NULL) ? error : &dummy; + *error = 0; + + switch (key->type) { + case TYPE_INT : + case TYPE_BOOL : val.i = strtol(value, NULL, 0); break; + case TYPE_TIME : + if (key->time_fmt != NULL) { + struct tm tm = {0}; + if (strptime(value, key->time_fmt, &tm) != NULL) { + val.t = mktime(&tm); + } else { + *error = 3; + } + } else { + *error = 4; + } + break; + case TYPE_STRING: val.str = make_str(value); break; + case TYPE_FLOAT : val.f = strtof(value, NULL); break; + default : *error = 2; break; + } + return val; +} + +void set_keyword(const keyword *key, keyword_val val, void *ret, void *ctx) { + if (key->callback != NULL) { + key->callback(ctx, ret, key, val); + } else { + char *tmp_ret = (char *)ret; + size_t offset = -1; + for (int i = 0; (int64_t)key->offsets[i] >= 0; ++i) { + if ((int64_t)offset >= 0) { + tmp_ret = *(char **)(tmp_ret+key->offsets[i]); + } + offset = key->offsets[i]; + } + + switch (type) { + case TYPE_INT : + case TYPE_BOOL : *(int *)(tmp_ret+offset) = val.i; break; + case TYPE_TIME : *(time_t *)(tmp_ret+offset) = val.t; break; + case TYPE_STRING: *(char **)(tmp_ret+offset) = val.str; break; + case TYPE_FLOAT : *(float *)(tmp_ret+offset) = val.f; break; + default : break; + } + } +} + +keyword_val parse_keyword(const keyword *key, char *key_str, char *value, int *error) { + int dummy = 0; + error = (error != NULL) ? error : &dummy; + if (!strcmp(key->key, key_str)) { + return get_keyword_value(key, value, error); + } else { + *error = 1; + return (keyword_val){0}; + } +} + + +int parse_keywords(const keyword **keys, char *key, char *value, void *ret, void *ctx) { + keyword_val val = {0}; + int error = 0; + + for (int i = 0; keys[i] != NULL; ++i) { + val = parse_keyword(keys[i], key, value, &error); + + if (!error) { + set_keyword(keys[i], val, ret, ctx); + return 0; + } + } + return error; +} |