author | Olivier Brunel
<jjk@jjacky.com> 2023-04-02 14:44:48 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:06:34 UTC |
parent | 4121821a398ca90b1183d3009d2ec3dfbb30e4f6 |
src/doc/loadopt.h.0.md | +0 | -4 |
src/doc/loadopt.h/loadopt.3.md | +17 | -17 |
src/doc/parseopt.h.0.md | +2 | -3 |
src/doc/parseopt.h/parseopt.3.md | +14 | -17 |
src/liblimb/include/limb/loadopt.h | +3 | -12 |
src/liblimb/include/limb/parseopt.h | +3 | -7 |
src/liblimb/loadopt.h/loadopt.c | +22 | -22 |
src/liblimb/loadopt.h/loadopt_handle_noconfig.c | +3 | -2 |
src/liblimb/parseopt.h/parseopt.c | +11 | -10 |
diff --git a/src/doc/loadopt.h.0.md b/src/doc/loadopt.h.0.md index 4697e5e..3b7bcbb 100644 --- a/src/doc/loadopt.h.0.md +++ b/src/doc/loadopt.h.0.md @@ -24,10 +24,6 @@ The following constants are defined : : *OPT_REQ* :: Set an option to be required -: *LOADOPT_ERR_FILE*, *LOADOPT_ERR_MISSINGOPT*, *LOADOPT_ERR_MISSINGARG* -: *LOADOPT_ERR_TOOMANY* -:: Possible return values for [loadopt](3) - ## Macros The following macros are defined : diff --git a/src/doc/loadopt.h/loadopt.3.md b/src/doc/loadopt.h/loadopt.3.md index 73ee23c..25ba818 100644 --- a/src/doc/loadopt.h/loadopt.3.md +++ b/src/doc/loadopt.h/loadopt.3.md @@ -99,7 +99,7 @@ argument. The important member is `arg` which is treated as defining whether the argument is required (*ARG_REQ*) or optional (*ARG_OPT*). If required and no argument was given on command-line, an error occurs. If optional and not -specified, `loadopt`() successfully ends, returning -1. +specified, `loadopt`() successfully ends, returning 0. Finally, after all such argument definitions in the array `options`, you must terminate it with either one of the macros *LOADOPT_DONE_OPEN* and @@ -117,33 +117,33 @@ In other words, *LOADOPT_DONE* is the same as *OPTION_DONE* as described from # RETURN VALUE -If an option was successfully found, `loadopt`() returns the option `id` if +If an option was successfully found, `loadopt`() returns the option's `id` if non-zero, else its `shortopt`. When all options, and, optionally, arguments, -have been successfully parsed -1 is returned. +have been successfully parsed it returns 0. -If an error occurs, a warning is emitted to *stderr* and a negative value (other -than -1) is returned, depending on the error. +If an error occurs, a warning is emitted to *stderr* and it returns -1, setting +`errno` to indicate the error. -## Warnings - -The warnings are actually written out using one of the [warn](3) family of -functions. Refer to it for more on how and where data is being written to. +! INFO: +! The warnings are actually written out using one of the [warn](3) family of +! functions. Refer to it for more on how and where data is being written to, or +! how to silence them. # ERRORS -The `loadopt`() function may fail and return : +The `loadopt`() function may fail if : -: *LOADOPT_ERR_FILE* -:: Unable to open/read the configuration file +: *ENOMEM* +:: Not enough memory to load configuration file -: *LOADOPT_ERR_MISSINGOPT* +: *ENOKEY* :: A required option was missing/not specified -: *LOADOPT_ERR_MISSINGARG* +: *ENODATA* :: A required argument was missing/not specified -: *LOADOPT_ERR_TOOMANY* +: *ETOOMANYREFS* :: Too many arguments were specified -The `loadopt`() function may also fail and return any of the errors specified -for [parseopt](3). +The `loadopt`() function may also fail for any of the errors specified for +[parseopt](3), [openslurpclose](3) save for *ENOENT*. diff --git a/src/doc/parseopt.h.0.md b/src/doc/parseopt.h.0.md index df8bc0f..d0eca19 100644 --- a/src/doc/parseopt.h.0.md +++ b/src/doc/parseopt.h.0.md @@ -27,9 +27,8 @@ The following constants are defined : : *PARSEOPT_IS_LONG*, *PARSEOPT_STRICT* :: Flags that can be passed to [parseopt](3). -: *PARSEOPT_DONE*, *PARSEOPT_ERR_NONAME*, *PARSEOPT_ERR_UNKNOWN*, -: *PARSEOPT_ERR_ARGREQ* -:: Possible return values for [parseopt](3) +: *ID_SHORTOPT* +:: Special ID for an option, meaning to return its `shortopt` instead. ## Structures diff --git a/src/doc/parseopt.h/parseopt.3.md b/src/doc/parseopt.h/parseopt.3.md index a9e9d48..620ca56 100644 --- a/src/doc/parseopt.h/parseopt.3.md +++ b/src/doc/parseopt.h/parseopt.3.md @@ -44,7 +44,7 @@ Additionally its member `idx` is set to the index of said option within abbreviated long options (and more than one option did match), the first-matching option. -When `parseopt`() returns -1, its member `cur` is the index in `argv` of the +When `parseopt`() returns 0, its member `cur` is the index in `argv` of the first non-option element. In that way, it is similar to the global `optind` from [getopt](3). @@ -57,15 +57,13 @@ followed by a second dash, then a long option name is expected to follow, else a short option character. An element of "--" has special meaning, indicating the end of options and -stopping parsing, i.e. `parseopt`() will return -1 when encountered. +stopping parsing, i.e. `parseopt`() will return 0 when encountered. When an option has been identified, `parseopt`() will return its `id` if it is non-zero, else its `shortopt` (see [[Options]] below). -When the first non-option element is encountered, or an element "--", parsing -stops and -1 is returned. - -On error, another negative value is returned, see [[ERRORS]] below for more. +Parsing stops when the first non-option element is encountered, or an element +"--" is met. ## Options @@ -137,27 +135,26 @@ constructed as a bitwise-inclusive OR of flags from the following list : # RETURN VALUE -If an option was successfully found, `parseopt`() returns the option `id` if -non-zero, else its `shortopt`. When all command-line options have been parsed -1 -is returned. +If an option was successfully found, `parseopt`() returns the option's `id` if +non-zero, else its `shortopt`. When all command-line options have been parsed it +returns 0. -If an error occurs, a negative value (other than -1) is returned, depending on -the error. +If an error occurs, it returns -1 and sets `errno` to indicate the error. ! NOTE: ! Unlike [getopt](3), `parseopt`() will not print any warning/error messages. -! The indication of the error is sent through its return value, and it is up to -! the caller to inform the user of what failed. +! The indication of the error is sent through `errno` and it is up to the +! caller to inform the user of what failed. # ERRORS -The `parseopt`() function may fail and return : +The `parseopt`() function may fail if : -: *PARSEOPT_ERR_NONAME* +: *EINVAL* :: Option name was missing, i.e. the element was "-" only -: *PARSEOPT_ERR_UNKNOWN* +: *ENOENT* :: Unknown option -: *PARSEOPT_ERR_ARGREQ* +: *ENOMSG* :: An option requiring an argument was found, but no argument was specified. diff --git a/src/liblimb/include/limb/loadopt.h b/src/liblimb/include/limb/loadopt.h index 0374da3..035cd87 100644 --- a/src/liblimb/include/limb/loadopt.h +++ b/src/liblimb/include/limb/loadopt.h @@ -17,18 +17,9 @@ enum { OPT_REQ = 1 << 3, /* must be specified */ }; -#define LOADOPT_ARGUMENTS { 0, 0, ARG_REQ, OPT_DONE } -#define LOADOPT_DONE_OPEN { 0, 0, ARG_OPT, OPT_DONE } -#define LOADOPT_DONE { 0, 0, ARG_NONE, OPT_DONE } - - -enum { - LOADOPT_ERR_FILE = -6, - LOADOPT_ERR_MISSINGOPT = -7, - LOADOPT_ERR_MISSINGARG = -8, - LOADOPT_ERR_TOOMANY = -9, - LOADOPT_ERR_INVALIDARG = -10, -}; +#define LOADOPT_ARGUMENTS { 0, 0, ARG_REQ, OPT_DONE, 0 } +#define LOADOPT_DONE_OPEN { 0, 0, ARG_OPT, OPT_DONE, 0 } +#define LOADOPT_DONE { 0, 0, ARG_NONE, OPT_DONE, 0 } struct loadopt { /* struct parseopt */ diff --git a/src/liblimb/include/limb/parseopt.h b/src/liblimb/include/limb/parseopt.h index 94a4a05..31cbce9 100644 --- a/src/liblimb/include/limb/parseopt.h +++ b/src/liblimb/include/limb/parseopt.h @@ -15,6 +15,9 @@ enum { /* last element in struct option[] to indicate the end */ #define OPTION_DONE { .flags = 1 } +/* special ID meaning to return shortopt instead */ +#define ID_SHORTOPT 0 + struct option { const char shortopt; const char *longopt; @@ -30,13 +33,6 @@ enum { PARSEOPT_STRICT = 1 << 1, }; -enum { - PARSEOPT_DONE = -1, /* success, all done */ - PARSEOPT_ERR_NONAME = -2, /* option name missing (i.e. "-") */ - PARSEOPT_ERR_UNKNOWN = -3, /* unknown option */ - PARSEOPT_ERR_ARGREQ = -4, /* argument required */ -}; - struct parseopt { /* private */ u16 cur; /* public when done : index of first argument in argv */ diff --git a/src/liblimb/loadopt.h/loadopt.c b/src/liblimb/loadopt.h/loadopt.c index 1743d41..c18d97d 100644 --- a/src/liblimb/loadopt.h/loadopt.c +++ b/src/liblimb/loadopt.h/loadopt.c @@ -31,14 +31,14 @@ static void parseopt_warn(int c, const char **argv, const struct option *options, const struct parseopt *ctx) { - if (c >= 0 || c == PARSEOPT_DONE) + if (c >= 0) return; - switch (c) { - case PARSEOPT_ERR_NONAME: + switch (errno) { + case EINVAL: warn("option name missing"); break; - case PARSEOPT_ERR_UNKNOWN: + case ENOENT: if (!strncmp(argv[ctx->cur], "--", 2)) { warn("unknown option: ", argv[ctx->cur]); } else { @@ -46,7 +46,7 @@ parseopt_warn(int c, const char **argv, const struct option *options, warn("unknown option: ", buf); } break; - case PARSEOPT_ERR_ARGREQ: + case ENOMSG: { char buf[2] = { options[ctx->idx].shortopt, 0 }; warn("option --", options[ctx->idx].longopt, @@ -63,7 +63,7 @@ loadopt_handle(int c, const char **argv, const struct option *options, if (!from_file && c >= 0 && options[ctx->idx].id == LOADOPT_ID_NOCONFIG) return loadopt_handle_noconfig(ctx->idx, options, (struct loadopt *) ctx); - if (c == PARSEOPT_ERR_UNKNOWN && ctx->idx >= 0) { + 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); @@ -95,17 +95,17 @@ nextopt: int c; c = parseopt(argc, argv, options, poflags, (struct parseopt *) ctx); - if (c >= 0) + if (c > 0) add_optflags(ctx->optflags, ctx->idx, OPT_SET); else parseopt_warn(c, argv, options, (struct parseopt *) ctx); - if (c != PARSEOPT_DONE) { + if (c) { c = loadopt_handle(c, argv, options, 0, (struct parseopt *) ctx); - if (c == PARSEOPT_DONE) + if (!c) goto nextopt; } - if (c != PARSEOPT_DONE) + if (c) return c; ctx->state = STATE_CMDLINE; } @@ -138,7 +138,7 @@ nextopt: ctx->state = STATE_CONFIG; if (errno != ENOENT) { warnusys("read ", ESC, file, ESC); - return LOADOPT_ERR_FILE; + return -1; } } else { ctx->state = STATE_FILE; @@ -203,30 +203,30 @@ nextfileopt: struct parseopt po = { 0 }; const char *argv[] = { "", ctx->sa.s + ctx->saoff }; - int c; - c = parseopt(2, argv, options, PARSEOPT_IS_LONG | PARSEOPT_STRICT, &po); + errno = 0; + int c = parseopt(2, argv, options, PARSEOPT_IS_LONG | PARSEOPT_STRICT, &po); /* seek past the line */ ctx->saoff = o + 1; /* ignore already set option, and "argument required" error for * already set option */ - if ((c >= 0 || c == PARSEOPT_ERR_ARGREQ) + if ((c > 0 || errno == ENOMSG) && (get_optflags(ctx->optflags, po.idx) & OPT_SET)) { goto nextfileopt; } - if (c >= 0) + if (c > 0) add_optflags(ctx->optflags, po.idx, OPT_SET); else parseopt_warn(c, argv, options, &po); - if (c != PARSEOPT_DONE) { + if (c) { c = loadopt_handle(c, argv, options, 1, &po); - if (c == PARSEOPT_DONE) + if (!c) goto nextfileopt; } - if (c != PARSEOPT_DONE) { + if (c) { /* adjust returned value */ ctx->arg = po.arg; ctx->idx = po.idx; @@ -246,7 +246,7 @@ nextfileopt: if ((get_optflags(ctx->optflags, i) & (OPT_REQ | OPT_SET)) == OPT_REQ) { char buf[2] = { options[i].shortopt, 0 }; warn("option --", options[i].longopt, (*buf) ? "/-" : "", buf, " missing"); - return LOADOPT_ERR_MISSINGOPT; + return (errno = ENOKEY, -1); } } /* re-use off as the current argument's index from w/in options */ @@ -263,7 +263,7 @@ nextfileopt: if (arg->flags & OPT_DONE) { if (arg->arg == ARG_NONE && ctx->cur < argc) { warn("too many arguments"); - return LOADOPT_ERR_TOOMANY; + return (errno = ETOOMANYREFS, -1); } else if (arg->arg == ARG_REQ) { ++ctx->off; continue; @@ -274,7 +274,7 @@ nextfileopt: if (arg->arg == ARG_REQ && ctx->cur == argc) { warn("argument ", ESC, arg->longopt, ESC," missing"); - return LOADOPT_ERR_MISSINGARG; + return (errno = ENODATA, -1); } /* next argument from command line */ @@ -293,5 +293,5 @@ nextfileopt: ctx->state = STATE_DONE; /* this is the end... */ - return PARSEOPT_DONE; + return 0; } diff --git a/src/liblimb/loadopt.h/loadopt_handle_noconfig.c b/src/liblimb/loadopt.h/loadopt_handle_noconfig.c index 626d3a7..723fe02 100644 --- a/src/liblimb/loadopt.h/loadopt_handle_noconfig.c +++ b/src/liblimb/loadopt.h/loadopt_handle_noconfig.c @@ -1,6 +1,7 @@ /* This file is part of limb https://lila.oss/limb * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ /* SPDX-License-Identifier: GPL-2.0-only */ +#include <errno.h> #include <limb/loadopt.h> #include <limb/output.h> #include "loadopt.h" @@ -25,10 +26,10 @@ loadopt_handle_noconfig(int idx, const struct option *options, struct loadopt *c char buf[2] = { options[idx].shortopt, 0 }; warn("invalid argument to option --", options[idx].longopt, (*buf) ? "/-" : "", buf, ": ", ctx->arg); - return LOADOPT_ERR_INVALIDARG; + return (errno = EINVAL, -1); } } } - return PARSEOPT_DONE; + return 0; } diff --git a/src/liblimb/parseopt.h/parseopt.c b/src/liblimb/parseopt.h/parseopt.c index d1d843f..c922c54 100644 --- a/src/liblimb/parseopt.h/parseopt.c +++ b/src/liblimb/parseopt.h/parseopt.c @@ -1,6 +1,7 @@ /* This file is part of limb https://lila.oss/limb * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ /* SPDX-License-Identifier: GPL-2.0-only */ +#include <errno.h> #include <stddef.h> /* offsetof() */ #include <limb/bytestr.h> #include <limb/parseopt.h> @@ -18,19 +19,19 @@ parseopt(int argc, const char **argv, const struct option *options, ctx->idx = -1; again: if (ctx->cur == argc) - return PARSEOPT_DONE; + return 0; arg = argv[ctx->cur] + ctx->off; if (flags & PARSEOPT_IS_LONG) { is_long = arg_long = 1; if (!*arg) - return PARSEOPT_ERR_NONAME; + return (errno = EINVAL, -1); } else { if (ctx->off == 0) { if (*arg != '-') /* not an option, so no more options */ - return PARSEOPT_DONE; + return 0; /* move on to the option */ ++ctx->off; ++arg; @@ -38,7 +39,7 @@ again: if (!*arg) { if (ctx->off == 1) - return PARSEOPT_ERR_NONAME; + return (errno = EINVAL, -1); /* next argument */ ++ctx->cur; ctx->off = 0; @@ -59,7 +60,7 @@ again: if (!l) { /* marker "--" for end of options */ ++ctx->cur; - return PARSEOPT_DONE; + return 0; } if (flags & PARSEOPT_STRICT) { @@ -69,11 +70,11 @@ again: break; if (!options[ctx->idx].longopt) { ctx->idx = -1; - return PARSEOPT_ERR_UNKNOWN; + return (errno = ENOENT, -1); } } else if (byte_get_match_full(&ctx->idx, arg, end, options, offsetof(struct option, longopt), sizeof(*options)) < 0) { - return PARSEOPT_ERR_UNKNOWN; + return (errno = ENOENT, -1); } /* --option-name=value : don't look for optarg on the next arg */ @@ -87,7 +88,7 @@ again: break; if (!options[ctx->idx].longopt) { ctx->idx = -1; - return PARSEOPT_ERR_UNKNOWN; + return (errno = ENOENT, -1); } } @@ -96,11 +97,11 @@ again: if (arg_long) { ++ctx->cur; if (ctx->cur == argc) - return PARSEOPT_ERR_ARGREQ; + return (errno = ENOMSG, -1); ctx->arg = argv[ctx->cur]; } else { if (!arg[1]) - return PARSEOPT_ERR_ARGREQ; + return (errno = ENOMSG, -1); ctx->arg = arg + 1; } } else if (options[ctx->idx].arg == ARG_OPT) {