diff options
Diffstat (limited to 'config.c')
-rw-r--r-- | config.c | 74 |
1 files changed, 28 insertions, 46 deletions
@@ -7,42 +7,31 @@ #include "macros.h" #include "misc.h" -config_val parse_option_value(const config_opt *opt, char *value) { - config_val val = {0}; - - switch (opt->type) { - case TYPE_INT : - case TYPE_BOOL : val.i = strtol(value, NULL, 0); break; - case TYPE_STRING: val.str = make_str(value); break; - case TYPE_FLOAT : val.f = strtof(value, NULL); break; - default : break; - } - - return val; -} - -void set_config_opt(config *conf, config_type type, size_t offset, config_val val) { - char *cfg = (char *)conf; - switch (type) { - case TYPE_INT : - case TYPE_BOOL : *(int *)(cfg+offset) = val.i; break; - case TYPE_STRING: *(char **)(cfg+offset) = val.str; break; - case TYPE_FLOAT : *(float *)(cfg+offset) = val.f; break; - default : break; - } -} - void cleanup_config(config *conf) { - char *cfg = (char *)conf; - for (const config_opt *opt = config_opts; opt->name != NULL; opt++) { + for (int i = 0; config_keywords[i] != NULL; ++i) { + /* Get the pointer to the config option. */ + void *cfg = get_keyword_offset_ptr(config_keywords[i], conf); /* Is this config option's type a string, and is the string of that config option in conf not NULL? */ - if (opt->type == TYPE_STRING && *(char **)(cfg+opt->offset) != NULL) { - free(*(char **)(cfg+opt->offset)); + if (config_keywords[i]->type == TYPE_STRING && *(void **)cfg != NULL) { + free(*(void **)cfg); } } free(conf); } +int check_port(void *ctx, void *ret, const keyword *key, keyword_val val) { + if (key->type == TYPE_INT) { + if (val.i > 0 || val.i <= 65535) { + return 0; + } else { + log(LOG_ERR, "Invalid port %d. (Valid port must be between 1, and 65535.)", val.i); + } + } else { + log(LOG_ERR, "Keyword \"%s\" doesn't return an integer.", key->key); + } + return -1; +} + config *parse_config(const char *filename) { /* Size of the file, in bytes. */ long filesize = 0; @@ -69,25 +58,18 @@ config *parse_config(const char *filename) { char *line = get_line(&tmp); char *value; char *name = strtok_r(line, "=", &value); - const config_opt *opt; - - /* Check to see if the config option name we got is valid. */ - for (opt = config_opts; opt->name != NULL && strcmp(name, opt->name); opt++); + int error; - /* Is the config option valid? */ - if (opt->name != NULL) { - config_val val = parse_option_value(opt, value); - if (opt->offset == offsetof(config, port)) { - const int port = strtol(val.str, NULL, 0); - if (port <= 0 || port > 65535) { - log(LOG_ERR, "Invalid port %d. (Valid port must be between 1, and 65535.)", port); - cleanup_config(cfg); - free(line); - free(buf); - return NULL; - } + /* Did we fail to parse the config option? */ + if (error = parse_keywords(config_keywords, name, value, cfg, NULL)) { + if (error == 5) { + cleanup_config(cfg); + free(line); + free(buf); + return NULL; + } else { + log(LOG_WARNING, "Failed to parse config option \"%s\". Error code: %i", name, error); } - set_config_opt(cfg, opt->type, opt->offset, val); } free(line); |