From d5864c05f08357a8849d1e928dcb57f16cc0f920 Mon Sep 17 00:00:00 2001 From: Tyge Date: Fri, 24 Apr 2020 22:49:25 +0200 Subject: Updated docs, renamed bad to faulty --- stc/copt.h | 83 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/stc/copt.h b/stc/copt.h index 3dda284f..d911df52 100644 --- a/stc/copt.h +++ b/stc/copt.h @@ -20,15 +20,45 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - -/* Inspired by https://attractivechaos.wordpress.com/2018/08/31/a-survey-of-argument-parsing-libraries-in-c-c - * Fixed major bugs with option arguments (both long and short), and shows a useful demo of the features. - * Has a more consistent API, added arg->bad output field, written in C99. - */ - #ifndef COPT__H__ #define COPT__H__ +/* Inspired by https://attractivechaos.wordpress.com/2018/08/31/a-survey-of-argument-parsing-libraries-in-c-c + Fixed major bugs with option arguments (both long and short). + Added arg->faulty output field, and has a more consistent API. + + copt_getopt() has a very similar interface to GNU's getopt_long(). Each call + parses one option and returns the option name. opt->arg points to the option + argument if present. The function returns -1 when all command-line arguments + are parsed. In this case, opt->ind is the index of the first non-option argument. +Example: + int main(int argc, char *argv[]) + { + struct copt_option longopts[] = { + {"foo", copt_no_argument, 'f'}, + {"bar", copt_required_argument, 'b'}, + {"opt", copt_optional_argument, 'o'}, + {NULL} + }; + const char* optstr = "xy:z::123"; + printf("program -x -y ARG -z [ARG] -1 -2 -3 --foo --bar ARG --opt [ARG] [ARGUMENTS]\n"); + int c; + copt_t opt = copt_init; + while ((c = copt_getopt(&opt, argc, argv, optstr, longopts, false)) != -1) { + switch (c) { + case '?': printf("error: unknown option: %s\n", opt.faulty); break; + case ':': printf("error: missing argument for %s\n", opt.faulty); break; + default: printf("option: %c [%s]\n", c, opt.arg ? opt.arg : ""); break; + } + } + printf("\nNon-option arguments:"); + for (int i = opt.ind; i < argc; ++i) + printf(" %s", argv[i]); + putchar('\n'); + return 0; + } +*/ + #include #include @@ -41,10 +71,10 @@ typedef struct { int ind; /* equivalent to optind */ int opt; /* equivalent to optopt */ char *arg; /* equivalent to optarg */ - char *bad; /* points to the faulty option */ + char *faulty; /* points to the faulty option */ int longindex; /* idx of long option; or -1 if short */ int _i, _pos, _nargs; - char _bad[4]; + char _faulty[4]; } copt_t; struct copt_option { @@ -63,10 +93,7 @@ static void _copt_permute(char *argv[], int j, int n) { /* move argv[j] over n e argv[j - k] = p; } - -/* Parse command-line options and arguments - * - * This fuction has a similar interface to GNU's getopt_long(). Each call +/* This fuction has a very similar interface to GNU's getopt_long(). Each call * parses one option and returns the option name. opt->arg points to the option * argument if present. The function returns -1 when all command-line arguments * are parsed. In this case, opt->ind is the index of the first non-option @@ -108,7 +135,7 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[], if (longopts[k].name[j - 2] == 0) ++n_exact, o_exact = &longopts[k]; else ++n_partial, o_partial = &longopts[k]; } - opt->bad = argv[opt->_i]; + opt->faulty = argv[opt->_i]; if (n_exact > 1 || (n_exact == 0 && n_partial > 1)) return '?'; o = n_exact == 1? o_exact : n_partial == 1? o_partial : 0; if (o) { @@ -128,7 +155,7 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[], const char *p; if (opt->_pos == 0) opt->_pos = 1; optc = opt->opt = argv[opt->_i][opt->_pos++]; - opt->_bad[1] = optc, opt->bad = opt->_bad; + opt->_faulty[1] = optc, opt->faulty = opt->_faulty; p = strchr((char *) shortopts, optc); if (p == 0) { optc = '?'; /* unknown option */ @@ -152,32 +179,4 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[], return optc; } -/* // demo: - int main(int argc, char *argv[]) - { - struct copt_option longopts[] = { - {"foo", copt_no_argument, 'f'}, - {"bar", copt_required_argument, 'b'}, - {"opt", copt_optional_argument, 'o'}, - {NULL} - }; - const char* optstr = "xy:z::123"; - printf("program -x -y ARG -z [ARG] -1 -2 -3 --foo --bar ARG --opt [ARG] [ARGUMENTS]\n"); - int c; - copt_t opt = copt_init; - while ((c = copt_getopt(&opt, argc, argv, optstr, longopts, false)) != -1) { - switch (c) { - case '?': printf("error: unknown option: %s\n", opt.bad); break; - case ':': printf("error: missing argument for %s\n", opt.bad); break; - default: printf("option: %c [%s]\n", c, opt.arg ? opt.arg : ""); break; - } - } - printf("\nNon-option arguments:"); - for (int i = opt.ind; i < argc; ++i) - printf(" %s", argv[i]); - putchar('\n'); - return 0; - } -*/ - #endif -- cgit v1.2.3