6static option* build_longopts(
const std::vector<CliOption>& options) {
7 size_t n = options.size();
8 option* opts =
new option[n + 1];
11 for (
size_t i = 0; i < n; ++i) {
14 opts[j].name = options[i].long_name;
15 opts[j].has_arg = options[i].has_arg;
16 opts[j].flag =
nullptr;
17 opts[j].val = options[i].short_name;
21 opts[j] = {
nullptr,0,
nullptr,0};
27 std::string shortopts;
29 for (
const auto& opt : options) {
32 if (opt.short_name > 0) {
33 shortopts +=
static_cast<char>(opt.short_name);
35 if (opt.has_arg == required_argument)
37 else if (opt.has_arg == optional_argument)
51 std::unique_ptr<option[]> long_opts(build_longopts(options));
54 while ((opt = getopt_long(argc, argv, shortopts.c_str(), long_opts.get(), &option_index)) != -1) {
56 std::string cerr =
"invalid option: ";
61 cerr += argv[optind - 1];
63 cerr +=
"\nTry '--help' for usage.";
71 name = long_opts[option_index].name;
73 name = std::string(1,
static_cast<char>(opt));
75 for (
size_t i = 0; long_opts[i].name !=
nullptr; i++) {
76 if (long_opts[i].val == opt) {
77 name = long_opts[i].name;
83 ctx_options.
args[name] = (optarg ? optarg :
"");
86 for (
int i = optind; i < argc; i++)
90 std::cout <<
"[DEBUG] Parsed options:\n";
91 for (
auto& kv : ctx_options.
args)
92 std::cout << kv.first <<
" = " << kv.second <<
"\n";
94 std::cout <<
"[DEBUG] Extra arg: " << a <<
"\n";
Base class for CLI-related errors.
bool parse_options(int argc, char *argv[], const std::vector< CliOption > &options, ParsedOptions &ctx_options)
Analyzes command-line arguments and populates ParsedOptions.
std::string build_shortopts(const std::vector< CliOption > &options)
std::vector< std::string > extra_args
List of extra arguments that are not options.
std::map< std::string, std::string > args
Map from option name to value.