# HG changeset patch # User John Tsiombikas # Date 1469585145 -10800 # Node ID a6f127f3408dbbd0066d05f08b45edbfdd369b43 # Parent f971dfa66076cbecc1260e507aaae76021c38bf1 implemented -no- and -disable- prefixes diff -r f971dfa66076 -r a6f127f3408d src/optcfg.c --- a/src/optcfg.c Wed Jul 27 04:31:40 2016 +0300 +++ b/src/optcfg.c Wed Jul 27 05:05:45 2016 +0300 @@ -22,6 +22,7 @@ /* argument parsing state */ char **argv; int argidx; + int disable_opt; /* config file parsing state */ const char *cfg_fname; @@ -29,7 +30,7 @@ char *cfg_value; }; -static int get_opt(struct optcfg *oc, const char *s); +static int get_opt(struct optcfg *oc, const char *s, int *disable_opt); static char *skip_spaces(char *s); static void strip_comments(char *s); static void strip_trailing_spaces(char *s); @@ -86,9 +87,10 @@ if(argv[i][0] == '-') { if(oc->opt_func) { - int o = get_opt(oc, argv[i]); + int o = get_opt(oc, argv[i], &oc->disable_opt); if(o == -1 || oc->opt_func(oc, o, oc->opt_cls) == -1) { if(oc->err_abort) { + fprintf(stderr, "unexpected option: %s\n", argv[i]); return -1; } } @@ -102,6 +104,7 @@ if(oc->arg_func) { if(oc->arg_func(oc, argv[i], oc->arg_cls) == -1) { if(oc->err_abort) { + fprintf(stderr, "unexpected argument: %s\n", argv[i]); return -1; } } @@ -173,7 +176,7 @@ return -1; } oc->cfg_value = val; - if((opt = get_opt(oc, start)) == -1) { + if((opt = get_opt(oc, start, 0)) == -1) { fprintf(stderr, "error parsing %s line %d: unknown option: %s\n", oc->cfg_fname ? oc->cfg_fname : "", oc->cfg_nline, start); return -1; @@ -191,7 +194,7 @@ int optcfg_enabled_value(struct optcfg *oc, int *enabledp) { if(oc->argidx) { - *enabledp = 1; /* TODO take -no- prefix into account */ + *enabledp = ~oc->disable_opt & 1; } else { char *val = optcfg_next_value(oc); if(optcfg_bool_value(val, enabledp) == -1) { @@ -270,17 +273,27 @@ -static int get_opt(struct optcfg *oc, const char *arg) +static int get_opt(struct optcfg *oc, const char *arg, int *disable_opt) { int i, ndashes = 0; while(*arg && *arg == '-') { - ndashes++; - arg++; + ++ndashes; + ++arg; } if(ndashes > 2) { arg -= ndashes; + ndashes = 0; + } + + if(disable_opt) { + if(ndashes && (strstr(arg, "no-") == arg || strstr(arg, "disable-") == arg)) { + *disable_opt = 1; + arg = strchr(arg, '-') + 1; /* guaranteed to exist at this point */ + } else { + *disable_opt = 0; + } } if(arg[1]) { /* match long options */ diff -r f971dfa66076 -r a6f127f3408d src/optcfg.h --- a/src/optcfg.h Wed Jul 27 04:31:40 2016 +0300 +++ b/src/optcfg.h Wed Jul 27 05:05:45 2016 +0300 @@ -7,10 +7,10 @@ struct optcfg; struct optcfg_option { - char c; /* short (optional): used only for argument parsing */ - char *s; /* long: used for long options and config files */ - int opt; /* the corresponding option enumeration */ - char *desc; /* text description for printing usage information */ + char c; /* short (optional): used only for argument parsing */ + const char *s; /* long: used for long options and config files */ + int opt; /* the corresponding option enumeration */ + const char *desc; /* text description for printing usage information */ }; #define OPTCFG_OPTIONS_END {0, 0, -1, 0} @@ -63,7 +63,7 @@ * optcfg_bool_value in sequence. * For argument parsing however, it doesn't consume further arguments. Merely * the presence of the option makes it enabled, and its presence with a -no- - * prefix disables it. (TODO the second part of this) + * or -disable- prefix disables it. */ int optcfg_enabled_value(struct optcfg *oc, int *enabledp);