commit 394aa9e76ad447d967bf40ddef9eecd1fef06735
parent a23c8139cf1ef9d4141701edc0385ab26b07cebd
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Thu, 6 Jun 2024 14:25:22 +0200
Options with optional arguments
* Long options with optional argument require '='
* Short options with optional argument cannot be ganged together
Diffstat:
2 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/args.hpp b/args.hpp
@@ -13,6 +13,13 @@ class Parser {
const char *name;
const char key;
const char *arg;
+ const uint8_t options;
+ };
+
+ enum Option {
+ ARG_OPTIONAL = 0x1,
+ HIDDEN = 0x2,
+ ALIAS = 0x3,
};
struct argp_t {
@@ -58,11 +65,10 @@ class Parser {
const char *arg = nullptr;
if (option->arg) {
- if (opt[j + 1] == 0) {
+ if (opt[j + 1] != 0) arg = opt + j + 1;
+ else if ((option->options & ARG_OPTIONAL) == 0) {
if (i == argc) goto missing;
arg = argv[++i];
- } else {
- arg = opt + j + 1;
}
}
@@ -82,12 +88,13 @@ class Parser {
const auto *option = options[key - 'a'];
const char *arg = nullptr;
- if (eq) {
- if (!option->arg) goto excess;
- arg = eq + 1;
- } else if (option->arg) {
- if (i == argc) goto missing;
- arg = argv[++i];
+ if (!option->arg && eq) goto excess;
+ if (option->arg) {
+ if (eq) arg = eq + 1;
+ else if ((option->options & ARG_OPTIONAL) == 0) {
+ if (i == argc) goto missing;
+ arg = argv[++i];
+ }
}
argp->parser(key, arg, input);
diff --git a/demo.cpp b/demo.cpp
@@ -29,7 +29,7 @@ int parse_opt(int key, const char *arg, void *input) {
if (arguments->hex) error("cannot mix -hex and -relocatable");
arguments->relocatable = true;
break;
- case 'o': arguments->output_file = arg; break;
+ case 'o': arguments->output_file = arg ? arg : "stdout"; break;
case 'i': arguments->input_file = arg; break;
default: arguments->args.push_back(arg);
}
@@ -37,13 +37,15 @@ int parse_opt(int key, const char *arg, void *input) {
return 0;
}
+using enum Parser::Option;
+
// clang-format off
static const Parser::option_t options[] = {
- { 0, 'o', "file"},
- { "input", 'i', "file"},
- { "debug", 'd', 0},
- { "hex", 'h', 0},
- {"relocatable", 'r', 0},
+ { "output", 'o', "file", ARG_OPTIONAL},
+ { 0, 'i', "file", 0},
+ { "debug", 'd', 0, 0},
+ { "hex", 'h', 0, 0},
+ {"relocatable", 'r', 0, 0},
{0},
};
// clang-format on