diff options
| author | Tyge Løvset <[email protected]> | 2020-03-30 21:41:38 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-03-30 21:41:38 +0200 |
| commit | 0e6df6e921c94390a2386b54941baa53cc67d7d7 (patch) | |
| tree | a1704feffacef4a327df5ec8ee7e3703c26a5a0a | |
| parent | 17c850ae9704f4d64817ec2f749aa38e5ecfab10 (diff) | |
| download | STC-modified-0e6df6e921c94390a2386b54941baa53cc67d7d7.tar.gz STC-modified-0e6df6e921c94390a2386b54941baa53cc67d7d7.zip | |
Add files via upload
| -rw-r--r-- | c_lib/cgetopt.h | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/c_lib/cgetopt.h b/c_lib/cgetopt.h index ae154603..1013cd05 100644 --- a/c_lib/cgetopt.h +++ b/c_lib/cgetopt.h @@ -20,6 +20,10 @@ // 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, written in C99.
+
#ifndef CGETOPT__H__
#define CGETOPT__H__
@@ -32,10 +36,10 @@ enum { 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 */
+ 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
int _i, _pos, _nargs;
} copt_t;
@@ -47,7 +51,7 @@ struct copt_option { static const copt_t copt_init = {1, 0, 0, -1, 1, 0, 0};
-static void _copt_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)
@@ -57,20 +61,15 @@ static void _copt_permute(char *argv[], int j, int n) { /* move argv[j] over n e // 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. st->arg points to the option
+// 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, st->ind is the index of the first non-option
+// are parsed. In this case, opt->ind is the index of the first non-option
// argument.
//
-// @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 shortopts short options string
-// @param longopts long options struct
+// @param opt output; must be initialized to copt_init on first call
// @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
@@ -88,17 +87,17 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[], opt->ind = opt->_i - opt->_nargs;
return -1;
}
- if (argv[opt->_i][0] == '-' && argv[opt->_i][1] == '-') { /* "--" or a long option */
- if (argv[opt->_i][2] == '\0') { /* a bare "--" */
+ 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;
}
opt->opt = 0, optc = '?', opt->_pos = -1;
- if (longopts) { /* parse long options */
+ if (longopts) { // parse long options
int k, n_exact = 0, n_partial = 0;
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 (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[opt->_i][2], longopts[k].name, j - 2) == 0) {
if (longopts[k].name[j - 2] == 0) ++n_exact, o_exact = &longopts[k];
@@ -114,30 +113,30 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[], 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 */
+ optc = ':'; // missing option argument
}
}
}
- } else { /* a short option */
+ } else { // a short option
const char *p;
if (opt->_pos == 0) opt->_pos = 1;
optc = opt->opt = argv[opt->_i][opt->_pos++];
p = strchr((char *) shortopts, optc);
if (p == 0) {
- optc = '?'; /* unknown option */
+ optc = '?'; // unknown option
} else if (p[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
+ optc = ':';
opt->_pos = -1;
}
}
if (opt->_pos < 0 || argv[opt->_i][opt->_pos] == 0) {
++opt->_i, opt->_pos = 0;
- if (opt->_nargs > 0) /* permute */
+ if (opt->_nargs > 0) // permute
for (j = i0; j < opt->_i; ++j)
_copt_permute(argv, j, opt->_nargs);
}
@@ -154,8 +153,8 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[], {"opt", copt_optional_argument, 'o'},
{NULL}
};
- const char* optstr = "a:b::c";
- printf("program -a arg -b [arg] -c --opt [arg] --foo --bar arg [arguments]\n");
+ const char* optstr = "ab:c::";
+ printf("program -a -b ARG -c [ARG] --foo --bar ARG --opt [ARG] [ARGUMENTS]\n");
int c;
copt_t opt = copt_init;
while ((c = copt_getopt(&opt, argc, argv, optstr, longopts, true)) != -1) {
@@ -176,5 +175,4 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[], }
*/
-
#endif
|
