diff options
| author | Tyge Løvset <[email protected]> | 2020-03-30 20:16:36 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-03-30 20:16:36 +0200 |
| commit | e14d91b1f48c1144b4af099f505d4c75311d5bac (patch) | |
| tree | 9c6fdb9131f297f71dc4679a39879d41d95164de | |
| parent | 982ac98c2bc4fcbbb6e917d2df0490312751d4a4 (diff) | |
| download | STC-modified-e14d91b1f48c1144b4af099f505d4c75311d5bac.tar.gz STC-modified-e14d91b1f48c1144b4af099f505d4c75311d5bac.zip | |
Add files via upload
| -rw-r--r-- | c_lib/cgetopt.h | 155 |
1 files changed, 82 insertions, 73 deletions
diff --git a/c_lib/cgetopt.h b/c_lib/cgetopt.h index d6ed61d8..fb5e0847 100644 --- a/c_lib/cgetopt.h +++ b/c_lib/cgetopt.h @@ -24,30 +24,30 @@ #define CGETOPT__H__
#include <string.h>
+#include <stdbool.h>
enum {
- c_getopt_none = 0,
- c_getopt_required = 1,
- c_getopt_optional = 2
+ copt_no_argument = 0,
+ copt_required_argument = 1,
+ copt_optional_argument = 2
};
typedef struct {
int ind; /* equivalent to optind */
int opt; /* equivalent to optopt */
char *arg; /* equivalent to optarg */
int longidx; /* index of a long option; or -1 if short */
- /* private variables not intended for external uses */
- int i, pos, n_args;
-} c_getopt_t;
+ int _i, _pos, _nargs;
+} copt_t;
-typedef struct {
+struct copt_option {
char *name;
int has_arg;
int val;
-} c_longopt_t;
+};
-static const c_getopt_t c_getopt_init = {1, 0, 0, -1, 1, 0, 0};
+static const copt_t copt_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 _copt_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)
@@ -64,105 +64,114 @@ static void _c_getopt_permute(char *argv[], int j, int n) { /* move argv[j] over // are parsed. In this case, st->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 opt output; must be initialized to copt_init before 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
+// @param shortopts short options string
+// @param longopts long options struct
+// @param permute true: move options ahead of non-option arguments
//
// @return ASCII val for a short option; longopt.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;
+static int copt_getopt(copt_t *opt, int argc, char *argv[],
+ const char *shortopts, const struct copt_option *longopts,
+ bool permute) {
+ int optc = -1, i0, j;
if (permute) {
- while (st->i < argc && (argv[st->i][0] != '-' || argv[st->i][1] == '\0'))
- ++st->i, ++st->n_args;
+ while (opt->_i < argc && (argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0'))
+ ++opt->_i, ++opt->_nargs;
}
- 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;
+ opt->arg = 0, opt->longidx = -1, i0 = opt->_i;
+ if (opt->_i >= argc || argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0') {
+ opt->ind = opt->_i - opt->_nargs;
return -1;
}
- 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;
+ if (argv[opt->_i][0] == '-' && argv[opt->_i][1] == '-') { /* "--" or a long option */
+ if (argv[opt->_i][2] == '\0') { /* a bare "--" */
+ _copt_permute(argv, opt->_i, opt->_nargs);
+ ++opt->_i, opt->ind = opt->_i - opt->_nargs;
return -1;
}
- st->opt = 0, opt = '?', st->pos = -1;
+ opt->opt = 0, optc = '?', opt->_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[st->i][j] != '\0' && argv[st->i][j] != '='; ++j) {} /* find the end of the option name */
+ const struct copt_option *o = 0, *o_exact = 0, *o_partial = 0;
+ for (j = 2; argv[opt->_i][j] != '\0' && argv[opt->_i][j] != '='; ++j) {} /* find the end of the option name */
for (k = 0; longopts[k].name != 0; ++k)
- if (strncmp(&argv[st->i][2], longopts[k].name, j - 2) == 0) {
+ if (strncmp(&argv[opt->_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) {
- 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 */
+ opt->opt = optc = o->val, opt->longidx = o - longopts;
+ if (o->has_arg != copt_no_argument) {
+ if (argv[opt->_i][j] == '=')
+ opt->arg = &argv[opt->_i][j + 1];
+ else if (argv[opt->_i][j] == '\0' && opt->_i < argc - 1 && argv[opt->_i + 1][0] != '-')
+ opt->arg = argv[++opt->_i];
+ else if (o->has_arg == copt_required_argument)
+ optc = ':'; /* missing option argument */
}
}
}
} else { /* a short option */
const char *p;
- if (st->pos == 0) st->pos = 1;
- opt = st->opt = argv[st->i][st->pos++];
- p = strchr((char*)optstr, opt);
+ if (opt->_pos == 0) opt->_pos = 1;
+ optc = opt->opt = argv[opt->_i][opt->_pos++];
+ p = strchr((char *) shortopts, optc);
if (p == 0) {
- opt = '?'; /* unknown option */
+ optc = '?'; /* unknown option */
} else if (p[1] == ':') {
- if (argv[st->i][st->pos] == 0) {
- if (st->i < argc - 1) st->arg = argv[++st->i];
- else opt = ':'; /* missing option argument */
- } else st->arg = &argv[st->i][st->pos];
- st->pos = -1;
+ if (argv[opt->_i][opt->_pos] != '\0')
+ opt->arg = &argv[opt->_i][opt->_pos];
+ else if (opt->_i < argc - 1 && argv[opt->_i + 1][0] != '-')
+ opt->arg = argv[++opt->_i];
+ else if (p[2] != ':')
+ optc = ':'; // missing option argument
+ opt->_pos = -1;
}
}
- 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);
+ if (opt->_pos < 0 || argv[opt->_i][opt->_pos] == 0) {
+ ++opt->_i, opt->_pos = 0;
+ if (opt->_nargs > 0) /* permute */
+ for (j = i0; j < opt->_i; ++j)
+ _copt_permute(argv, j, opt->_nargs);
}
- st->ind = st->i - st->n_args;
- return opt;
+ opt->ind = opt->_i - opt->_nargs;
+ return optc;
}
-/* // demo:
+/* // demo:
int main(int argc, char *argv[])
{
- static c_longopt_t longopts[] = {
- { "foo", c_getopt_none, 301 },
- { "bar", c_getopt_required, 302 },
- { "opt", c_getopt_optional, 303 },
- { NULL, 0, 0 }
- };
- c_getopt_t opt = c_getopt_init;
- int i, c;
- while ((c = c_getopt(&opt, argc, argv, 1, "xy:", longopts)) >= 0) {
- if (c == 'x') printf("-x\n");
- else if (c == 'y') printf("-y %s\n", opt.arg);
- else if (c == 301) printf("--foo\n");
- else if (c == 302) printf("--bar %s\n", opt.arg? opt.arg : "(null)");
- else if (c == 303) printf("--opt %s\n", opt.arg? opt.arg : "(null)");
- else if (c == '?') printf("unknown opt: -%c\n", opt.opt? opt.opt : ':');
- else if (c == ':') printf("missing arg: -%c\n", opt.opt? opt.opt : ':');
- }
- printf("Non-option arguments:");
- for (i = opt.ind; i < argc; ++i)
- printf(" %s", argv[i]);
- putchar('\n');
- return 0;
+ static struct copt_option longopts[] = {
+ {"foo", copt_no_argument, 'f'},
+ {"bar", copt_required_argument, 'b'},
+ {"opt", copt_optional_argument, 'o'},
+ {NULL}
+ };
+ copt_t opt = copt_init;
+ int i = 0, c;
+ const char* optstr = "a:b::c";
+ printf("optstr: %s\n", optstr);
+ while ((c = copt_getopt(&opt, argc, argv, optstr, longopts, true)) != -1) {
+ if (c == '?')
+ opt.opt != 0 ? printf("unknown option: %c\n", opt.opt)
+ : printf("unknown option: %s\n", argv[opt.ind - 1]);
+ else if (c == ':')
+ printf("missing argument for %s\n", argv[opt.ind - 1]);
+ else
+ printf("option: %c %s\n", c, opt.arg ? opt.arg : "");
+ }
+ printf("\nNon-option arguments:");
+ for (i = opt.ind; i < argc; ++i)
+ printf(" %s", argv[i]);
+ putchar('\n');
+ return 0;
}
*/
|
