From 2017066db5d60f017031800c65c3f7dc4bb1c1b0 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 31 Jan 2021 08:28:14 +0100 Subject: Updated libs --- src/liboptions/options.c | 84 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 10 deletions(-) (limited to 'src/liboptions/options.c') diff --git a/src/liboptions/options.c b/src/liboptions/options.c index 4b8f062..d49e698 100644 --- a/src/liboptions/options.c +++ b/src/liboptions/options.c @@ -36,12 +36,37 @@ static option_t *option_head = NULL; static option_t **option_tailp = &option_head; static int first_option = 1; +static struct options_strdup_entry { + struct options_strdup_entry *next; + char s[1]; +} *options_strdup_list = NULL; + +char *options_strdup(const char *s) +{ + struct options_strdup_entry *o; + + o = malloc(sizeof(struct options_strdup_entry) + strlen(s)); + if (!o) { + PDEBUG(DOPTIONS, DEBUG_ERROR, "No mem!\n"); + abort(); + } + o->next = options_strdup_list; + options_strdup_list = o; + strcpy(o->s, s); + + return o->s; +} + void option_add(int short_option, const char *long_option, int parameter_count) { option_t *option; - /* check if option already exists */ + /* check if option already exists or is not allowed */ for (option = option_head; option; option = option->next) { + if (!strcmp(option->long_option, "config")) { + PDEBUG(DOPTIONS, DEBUG_ERROR, "Option '%s' is not allowed to add, please fix!\n", option->long_option); + abort(); + } if (option->short_option == short_option || !strcmp(option->long_option, long_option)) { PDEBUG(DOPTIONS, DEBUG_ERROR, "Option '%s' added twice, please fix!\n", option->long_option); @@ -62,24 +87,32 @@ void option_add(int short_option, const char *long_option, int parameter_count) option_tailp = &(option->next); } -int options_config_file(const char *config_file, int (*handle_options)(int short_option, int argi, char *argv[])) +int options_config_file(int argc, char *argv[], const char *config_file, int (*handle_options)(int short_option, int argi, char *argv[])) { static const char *home; char config[256]; FILE *fp; - char buffer[256], opt[256], param[256], *p, *argv[16]; + char buffer[256], opt[256], param[256], *p, *args[16]; char params[1024]; int line; int rc = 1; int i, j, quote; option_t *option; - /* open config file */ - home = getenv("HOME"); - if (home == NULL) - return 1; - sprintf(config, "%s/%s", home, config_file + 2); + /* select for alternative config file */ + if (argc > 2 && !strcmp(argv[1], "--config")) + config_file = argv[2]; + + /* add home directory */ + if (config_file[0] == '~' && config_file[1] == '/') { + home = getenv("HOME"); + if (home == NULL) + return 1; + sprintf(config, "%s/%s", home, config_file + 2); + } else + strcpy(config, config_file); + /* open config file */ fp = fopen(config, "r"); if (!fp) { PDEBUG(DOPTIONS, DEBUG_INFO, "Config file '%s' seems not to exist, using command line options only.\n", config); @@ -158,7 +191,7 @@ int options_config_file(const char *config_file, int (*handle_options)(int short param[j++] = *p++; } param[j] = '\0'; - argv[i] = strdup(param); + args[i] = options_strdup(param); sprintf(strchr(params, '\0'), " '%s'", param); /* skip white spaces behind option */ while (*p > '\0' && *p <= ' ') @@ -185,7 +218,7 @@ int options_config_file(const char *config_file, int (*handle_options)(int short PDEBUG(DOPTIONS, DEBUG_ERROR, "Given option '%s' in config file '%s' at line %d requires %d parameter(s), use '-h' for help!\n", opt, config_file, line, option->parameter_count); return -EINVAL; } - rc = handle_options(option->short_option, 0, argv); + rc = handle_options(option->short_option, 0, args); if (rc <= 0) goto done; first_option = 0; @@ -206,6 +239,19 @@ int options_command_line(int argc, char *argv[], int (*handle_options)(int short int rc; for (argi = 1; argi < argc; argi++) { + /* --config */ + if (!strcmp(argv[argi], "--config")) { + if (argi > 1) { + PDEBUG(DOPTIONS, DEBUG_ERROR, "Given command line option '%s' must be the first option specified, use '-h' for help!\n", argv[argi]); + return -EINVAL; + } + if (argc <= 2) { + PDEBUG(DOPTIONS, DEBUG_ERROR, "Given command line option '%s' requires 1 parameter, use '-h' for help!\n", argv[argi]); + return -EINVAL; + } + argi += 1; + continue; + } if (argv[argi][0] == '-') { if (argv[argi][1] != '-') { if (strlen(argv[argi]) != 2) { @@ -273,3 +319,21 @@ int option_is_first(void) return first_option; } +void options_free(void) +{ + while (options_strdup_list) { + struct options_strdup_entry *o; + o = options_strdup_list; + options_strdup_list = o->next; + free(o); + } + + while (option_head) { + option_t *o; + o = option_head; + option_head = o->next; + free(o); + } + option_tailp = &option_head; +} + -- cgit v1.2.3