author | Olivier Brunel
<jjk@jjacky.com> 2023-04-05 18:06:12 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:06:35 UTC |
parent | dd77362234e044cf541fc46c163abaa61ee61563 |
src/doc/loadopt.h.0.md | +7 | -0 |
src/doc/loadopt.h/loadopt_auto_noconfig.3.md | +50 | -0 |
src/doc/parseopt.h/parseopt.3.md | +1 | -1 |
src/include/loadopt.h | +1 | -3 |
src/liblimb/include/limb/loadopt.h | +4 | -4 |
src/liblimb/loadopt.h/loadopt.c | +0 | -31 |
src/liblimb/loadopt.h/{loadopt_handle_noconfig.c => loadopt_auto_noconfig.c} | +15 | -12 |
diff --git a/src/doc/loadopt.h.0.md b/src/doc/loadopt.h.0.md index 45d6378..d6663b5 100644 --- a/src/doc/loadopt.h.0.md +++ b/src/doc/loadopt.h.0.md @@ -35,6 +35,10 @@ The following macros are defined : :: To define required or optional argument in a *struct option* array to be :: checked by [loadopt](3) +: *AUTOOPT_NOCONFIG* +:: To define the option to disable loading (specified) options from +:: configuration + ## Structures The following structure are defined : @@ -48,3 +52,6 @@ The following functions are defined : : [loadopt](3) :: To parse options from command-line & optionally configuration file + +: [loadopt_auto_noconfig](3) +:: To parse the "noconfig" option automatically diff --git a/src/doc/loadopt.h/loadopt_auto_noconfig.3.md b/src/doc/loadopt.h/loadopt_auto_noconfig.3.md new file mode 100644 index 0000000..2ce1581 --- /dev/null +++ b/src/doc/loadopt.h/loadopt_auto_noconfig.3.md @@ -0,0 +1,50 @@ +% limb manual +% loadopt_auto_noconfig(3) + +# NAME + +loadopt\_auto\_noconfig - automatic handling of the "noconfig" option + +# SYNOPSIS + + #include <limb/autoopt.h> + +```pre hl +AUTOOPT_NOCONFIG(<em>shortopt</em>, <em>longopt</em>, <em>flags</em>, <em>id</em>) + +int loadopt_auto_noconfig(int <em>idx</em>, const struct option *<em>options</em>, struct loadopt *<em>ctx</em>) +``` + +# DESCRIPTION + +The `loadopt_auto_noconfig`() function is intended to be used during parsing of +command-line options via [loadopt](3), to handle automatically a "noconfig" +option. + +This option can be used on command-line to disable the loading of (specified) +default values from configuration file, and accepts an optional argument. + +You can define such an option through the convenience macro *AUTOOPT_NOCONFIG*. + +The `idx` argument must be the index of the option to be processed inside the +array `options`. The `ctx` argument must be a pointer to the same structure that +is being used with [loadopt](3). + +If no argument was given to the option, it will disable loading options from the +configuration file altogether. Else, the argument is expected to be a +coma-separated list of option names (`longopt`) to be disabled. Partial names +are accepted only when they are unique to one option. + +# RETURN VALUE + +The `loadopt_auto_noconfig`() function returns 0 on success. Otherwise, it +returns -1 and sets `errno` to indicate the error. It also emits a warning +(through the [warn](3) family of functions), similar to what [loadopt](3) does. + +# ERRORS + +The `loadopt_auto_noconfig`() function may fail i: + +: *EINVAL* +:: The argument contained at least one unknown option (or partial match to more +:: than a single option). diff --git a/src/doc/parseopt.h/parseopt.3.md b/src/doc/parseopt.h/parseopt.3.md index 942621e..6cbfdbb 100644 --- a/src/doc/parseopt.h/parseopt.3.md +++ b/src/doc/parseopt.h/parseopt.3.md @@ -171,4 +171,4 @@ The `parseopt`() function may fail if : # SEE ALSO -[autoopt](3) +[loadopt](3), [autoopt](3) diff --git a/src/include/loadopt.h b/src/include/loadopt.h index 393bf91..6103b1f 100644 --- a/src/include/loadopt.h +++ b/src/include/loadopt.h @@ -4,8 +4,8 @@ #ifndef LIMB_LIMB_LOADOPT_H #define LIMB_LIMB_LOADOPT_H -#include <limb/parseopt.h> #include <limb/gccattributes.h> +#include <limb/loadopt.h> enum state { STATE_NONE = 0, @@ -29,6 +29,4 @@ enum { void add_optflags(u8 *optflags, int idx, u8 val) gccattr_hidden; u8 get_optflags(const u8 *optflags, int idx) gccattr_hidden; -int loadopt_handle_noconfig(int idx, const struct option *options, struct loadopt *ctx) gccattr_hidden; - #endif /* LIMB_LIMB_LOADOPT_H */ diff --git a/src/liblimb/include/limb/loadopt.h b/src/liblimb/include/limb/loadopt.h index d484333..9fadd92 100644 --- a/src/liblimb/include/limb/loadopt.h +++ b/src/liblimb/include/limb/loadopt.h @@ -45,12 +45,12 @@ struct loadopt { u16 from_file : 1; }; -enum { - LOADOPT_ID_NOCONFIG = 1, -}; - extern int loadopt(int argc, const char **argv, const struct option *options, const char *file, const char *section, unsigned int poflags, struct loadopt *ctx); +/* dont load (specified) options fro config file */ +#define AUTOOPT_NOCONFIG(s,l,f,i) OPTION_ARG_OPT( s, l, OPT_SKIP | f, i) +extern int loadopt_auto_noconfig(int idx, const struct option *options, struct loadopt *ctx); + #endif /* LIMB_LOADOPT_H */ diff --git a/src/liblimb/loadopt.h/loadopt.c b/src/liblimb/loadopt.h/loadopt.c index bcd4b21..7de2984 100644 --- a/src/liblimb/loadopt.h/loadopt.c +++ b/src/liblimb/loadopt.h/loadopt.c @@ -64,26 +64,6 @@ parseopt_warn(int c, const char **argv, const struct option *options, } } -static int -loadopt_handle(int c, const char **argv, const struct option *options, - int from_file, struct parseopt *ctx) -{ - if (!from_file && c >= 0 && options[ctx->idx].id == LOADOPT_ID_NOCONFIG) - return loadopt_handle_noconfig(ctx->idx, options, (struct loadopt *) ctx); - - if (errno == ENOENT && ctx->idx >= 0) { - const char *s = argv[ctx->cur] + ctx->off; - size_t l = byte_chr(s, strlen(s), '='); - adde("did you mean --", options[ctx->idx].longopt); - for (int i = ctx->idx + 1; options[i].longopt; ++i) - if (!strncmp(s, options[i].longopt, l)) - adde(" or --", options[i].longopt); - err(" ?"); - } - - return c; -} - int loadopt(int argc, const char **argv, const struct option *options, const char *file, const char *section, unsigned int poflags, @@ -98,7 +78,6 @@ loadopt(int argc, const char **argv, const struct option *options, } /* init is done, parse options from command line */ -nextopt: if (ctx->state == STATE_INIT) { int c; c = parseopt(argc, argv, options, poflags, (struct parseopt *) ctx); @@ -108,11 +87,6 @@ nextopt: else parseopt_warn(c, argv, options, (struct parseopt *) ctx); - if (c) { - c = loadopt_handle(c, argv, options, 0, (struct parseopt *) ctx); - if (!c) - goto nextopt; - } if (c) return c; ctx->state = STATE_CMDLINE; @@ -229,11 +203,6 @@ nextfileopt: else parseopt_warn(c, argv, options, &po); - if (c) { - c = loadopt_handle(c, argv, options, 1, &po); - if (!c) - goto nextfileopt; - } if (c) { /* adjust returned value */ ctx->arg = po.arg; diff --git a/src/liblimb/loadopt.h/loadopt_handle_noconfig.c b/src/liblimb/loadopt.h/loadopt_auto_noconfig.c similarity index 50% rename from src/liblimb/loadopt.h/loadopt_handle_noconfig.c rename to src/liblimb/loadopt.h/loadopt_auto_noconfig.c index 723fe02..46f85fb 100644 --- a/src/liblimb/loadopt.h/loadopt_handle_noconfig.c +++ b/src/liblimb/loadopt.h/loadopt_auto_noconfig.c @@ -2,12 +2,13 @@ * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ /* SPDX-License-Identifier: GPL-2.0-only */ #include <errno.h> -#include <limb/loadopt.h> +#include <stddef.h> /* offsetof() */ +#include <limb/bytestr.h> #include <limb/output.h> #include "loadopt.h" int -loadopt_handle_noconfig(int idx, const struct option *options, struct loadopt *ctx) +loadopt_auto_noconfig(int idx, const struct option *options, struct loadopt *ctx) { if (!ctx->arg) { for (int i = 0; options[i].longopt; ++i) @@ -15,21 +16,23 @@ loadopt_handle_noconfig(int idx, const struct option *options, struct loadopt *c add_optflags(ctx->optflags, i, OPT_SKIP); } else { for (char *s = strtok((char *) ctx->arg, ","); s; s = strtok(NULL, ",")) { - int i; - for (i = 0; options[i].longopt; ++i) { - if (!strcmp(s, options[i].longopt)) { - add_optflags(ctx->optflags, i, OPT_SKIP); - break; - } - } - if (!options[i].longopt) { + size_t l= strlen(s); + int first = -1, i; + i = byte_get_match_full(&first, s, l, options, + offsetof(struct option, longopt), sizeof(*options)); + if (i < 0) { char buf[2] = { options[idx].shortopt, 0 }; warn("invalid argument to option --", options[idx].longopt, (*buf) ? "/-" : "", buf, ": ", ctx->arg); - return (errno = EINVAL, -1); + if (first >= 0) + list_matches_full(err_putmsg, OLVL_NORMAL, "did you mean ", + "--", " or ", " ?", s, l, first, options, + offsetof(struct option, longopt), sizeof(*options)); + return (errno = EINVAL, 0); } + add_optflags(ctx->optflags, i, OPT_SKIP); } } - return 0; + return 1; }