summaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2022-07-28 19:46:53 -0300
committermrb0nk500 <b0nk@b0nk.xyz>2022-07-28 19:46:53 -0300
commitc8f5ba65044992deb3175e9b89792e13a8af4539 (patch)
tree8bc5dc0a43386c0b47fab89cbe5426f51de77e36 /config.c
parentb46091ed2d79aacc0c44417ac2e3f85663f750af (diff)
config: Make use of `keyword` for parsing config files
This get's rid of the old `config_opt` parser, which was way too specific for parsing config files.
Diffstat (limited to 'config.c')
-rw-r--r--config.c74
1 files changed, 28 insertions, 46 deletions
diff --git a/config.c b/config.c
index 1755ad3..012ed3d 100644
--- a/config.c
+++ b/config.c
@@ -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);