From a3162e91014e0dda7370a6a4fc165f231dcb9a64 Mon Sep 17 00:00:00 2001 From: Tyge Løvset <60263450+tylo-work@users.noreply.github.com> Date: Sun, 29 Mar 2020 20:31:30 +0200 Subject: Add files via upload --- c_lib/cgetopt.h | 130 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 55 deletions(-) diff --git a/c_lib/cgetopt.h b/c_lib/cgetopt.h index 58917fc8..08613f62 100644 --- a/c_lib/cgetopt.h +++ b/c_lib/cgetopt.h @@ -1,5 +1,27 @@ -#ifndef CGETOPT_H -#define CGETOPT_H +// MIT License +// +// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef CGETOPT__H__ +#define CGETOPT__H__ #include @@ -25,8 +47,7 @@ typedef struct { static const c_getopt_t c_getopt_init = {1, 0, 0, -1, 1, 0, 0}; -static void c_getopt_permute(char *argv[], int j, int n) /* move argv[j] over n elements to the left */ -{ +static void c_getopt_permute(char *argv[], int j, int n) { /* move argv[j] over n elements to the left */ int k; char *p = argv[j]; for (k = 0; k < n; ++k) @@ -34,87 +55,86 @@ static void c_getopt_permute(char *argv[], int j, int n) /* move argv[j] over n argv[j - k] = p; } -/** - * Parse command-line options and arguments - * - * This fuction has a similar interface to GNU's getopt_long(). Each call - * parses one option and returns the option name. s->arg points to the option - * argument if present. The function returns -1 when all command-line arguments - * are parsed. In this case, s->ind is the index of the first non-option - * argument. - * - * @param s status; shall be initialized to c_getopt_init on the first call - * @param argc length of argv[] - * @param argv list of command-line arguments; argv[0] is ignored - * @param permute non-zero to move options ahead of non-option arguments - * @param ostr option string - * @param longopts long options - * - * @return ASCII for a short option; c_longopt_t::val for a long option; -1 if - * argv[] is fully processed; '?' for an unknown option or an ambiguous - * long option; ':' if an option argument is missing - */ -static int c_getopt(c_getopt_t *s, int argc, char *argv[], int permute, const char *ostr, const c_longopt_t *longopts) -{ + +// Parse command-line options and arguments +// +// This fuction has a similar interface to GNU's getopt_long(). Each call +// parses one option and returns the option name. s->arg points to the option +// argument if present. The function returns -1 when all command-line arguments +// are parsed. In this case, s->ind is the index of the first non-option +// argument. +// +// @param st status; shall be initialized to c_getopt_init on the first call +// @param argc length of argv[] +// @param argv list of command-line arguments; argv[0] is ignored +// @param permute non-zero to move options ahead of non-option arguments +// @param optstr option string +// @param longopts long options +// +// @return ASCII for a short option; c_longopt_t::val for a long option; +// -1 if argv[] is fully processed; '?' for an unknown option or +// an ambiguous long option; ':' if an option argument is missing +// +static int c_getopt(c_getopt_t *st, int argc, char *argv[], int permute, const char *optstr, const c_longopt_t *longopts) { int opt = -1, i0, j; if (permute) { - while (s->i < argc && (argv[s->i][0] != '-' || argv[s->i][1] == '\0')) - ++s->i, ++s->n_args; + while (st->i < argc && (argv[st->i][0] != '-' || argv[st->i][1] == '\0')) + ++st->i, ++st->n_args; } - s->arg = 0, s->longidx = -1, i0 = s->i; - if (s->i >= argc || argv[s->i][0] != '-' || argv[s->i][1] == '\0') { - s->ind = s->i - s->n_args; + st->arg = 0, st->longidx = -1, i0 = st->i; + if (st->i >= argc || argv[st->i][0] != '-' || argv[st->i][1] == '\0') { + st->ind = st->i - st->n_args; return -1; } - if (argv[s->i][0] == '-' && argv[s->i][1] == '-') { /* "--" or a long option */ - if (argv[s->i][2] == '\0') { /* a bare "--" */ - c_getopt_permute(argv, s->i, s->n_args); - ++s->i, s->ind = s->i - s->n_args; + if (argv[st->i][0] == '-' && argv[st->i][1] == '-') { /* "--" or a long option */ + if (argv[st->i][2] == '\0') { /* a bare "--" */ + c_getopt_permute(argv, st->i, st->n_args); + ++st->i, st->ind = st->i - st->n_args; return -1; } - s->opt = 0, opt = '?', s->pos = -1; + st->opt = 0, opt = '?', st->pos = -1; if (longopts) { /* parse long options */ int k, n_exact = 0, n_partial = 0; const c_longopt_t *o = 0, *o_exact = 0, *o_partial = 0; - for (j = 2; argv[s->i][j] != '\0' && argv[s->i][j] != '='; ++j) {} /* find the end of the option name */ + for (j = 2; argv[st->i][j] != '\0' && argv[st->i][j] != '='; ++j) {} /* find the end of the option name */ for (k = 0; longopts[k].name != 0; ++k) - if (strncmp(&argv[s->i][2], longopts[k].name, j - 2) == 0) { + if (strncmp(&argv[st->i][2], longopts[k].name, j - 2) == 0) { if (longopts[k].name[j - 2] == 0) ++n_exact, o_exact = &longopts[k]; else ++n_partial, o_partial = &longopts[k]; } 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) { - s->opt = opt = o->val, s->longidx = o - longopts; - if (argv[s->i][j] == '=') s->arg = &argv[s->i][j + 1]; - if (o->has_arg == 1 && argv[s->i][j] == '\0') { - if (s->i < argc - 1) s->arg = argv[++s->i]; + st->opt = opt = o->val, st->longidx = o - longopts; + if (argv[st->i][j] == '=') st->arg = &argv[st->i][j + 1]; + if (o->has_arg == 1 && argv[st->i][j] == '\0') { + if (st->i < argc - 1) st->arg = argv[++st->i]; else opt = ':'; /* missing option argument */ } } } } else { /* a short option */ const char *p; - if (s->pos == 0) s->pos = 1; - opt = s->opt = argv[s->i][s->pos++]; - p = strchr((char*)ostr, opt); + if (st->pos == 0) st->pos = 1; + opt = st->opt = argv[st->i][st->pos++]; + p = strchr((char*)optstr, opt); if (p == 0) { opt = '?'; /* unknown option */ } else if (p[1] == ':') { - if (argv[s->i][s->pos] == 0) { - if (s->i < argc - 1) s->arg = argv[++s->i]; + if (argv[st->i][st->pos] == 0) { + if (st->i < argc - 1) st->arg = argv[++st->i]; else opt = ':'; /* missing option argument */ - } else s->arg = &argv[s->i][s->pos]; - s->pos = -1; + } else st->arg = &argv[st->i][st->pos]; + st->pos = -1; } } - if (s->pos < 0 || argv[s->i][s->pos] == 0) { - ++s->i, s->pos = 0; - if (s->n_args > 0) /* permute */ - for (j = i0; j < s->i; ++j) - c_getopt_permute(argv, j, s->n_args); + if (st->pos < 0 || argv[st->i][st->pos] == 0) { + ++st->i, st->pos = 0; + if (st->n_args > 0) /* permute */ + for (j = i0; j < st->i; ++j) + c_getopt_permute(argv, j, st->n_args); } - s->ind = s->i - s->n_args; + st->ind = st->i - st->n_args; return opt; } -- cgit v1.2.3