Arkanjo 0.2
A tool for find code duplicated functions in codebases
Loading...
Searching...
No Matches
parser_options.cpp
Go to the documentation of this file.
2
3#include <iostream>
4#include <memory>
5
6static option* build_longopts(const std::vector<CliOption>& options) {
7 size_t n = options.size();
8 option* opts = new option[n + 1];
9
10 size_t j = 0;
11 for (size_t i = 0; i < n; ++i) {
12 if (options[i].has_arg == PositionalArgument) continue;
13
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;
18 j++;
19 }
20
21 opts[j] = {nullptr,0,nullptr,0};
22
23 return opts;
24}
25
26std::string build_shortopts(const std::vector<CliOption>& options) {
27 std::string shortopts;
28
29 for (const auto& opt : options) {
30 if (opt.has_arg == PositionalArgument) continue;
31
32 if (opt.short_name > 0) {
33 shortopts += static_cast<char>(opt.short_name);
34
35 if (opt.has_arg == required_argument)
36 shortopts += ":";
37 else if (opt.has_arg == optional_argument)
38 shortopts += "::";
39 }
40 }
41
42 return shortopts;
43}
44
45bool parse_options(int argc, char* argv[], const std::vector<CliOption>& options, ParsedOptions& ctx_options) {
46 ctx_options.extra_args.clear();
47
48 int option_index = 0;
49 int opt;
50
51 std::unique_ptr<option[]> long_opts(build_longopts(options));
52 std::string shortopts = build_shortopts(options);
53
54 while ((opt = getopt_long(argc, argv, shortopts.c_str(), long_opts.get(), &option_index)) != -1) {
55 if (opt == '?') {
56 std::string cerr = "invalid option: ";
57 if (optopt) {
58 cerr += "-";
59 cerr += char(optopt);
60 } else {
61 cerr += argv[optind - 1];
62 }
63 cerr += "\nTry '--help' for usage.";
64 throw CLIError(cerr);
65 return false;
66 }
67
68 std::string name;
69
70 if (opt == 0) { // long option
71 name = long_opts[option_index].name;
72 } else { // short option
73 name = std::string(1, static_cast<char>(opt));
74
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;
78 break;
79 }
80 }
81 }
82
83 ctx_options.args[name] = (optarg ? optarg : "");
84 }
85
86 for (int i = optind; i < argc; i++)
87 ctx_options.extra_args.push_back(argv[i]);
88
89#ifdef DEBUG
90 std::cout << "[DEBUG] Parsed options:\n";
91 for (auto& kv : ctx_options.args)
92 std::cout << kv.first << " = " << kv.second << "\n";
93 for (auto& a : ctx_options.extra_args)
94 std::cout << "[DEBUG] Extra arg: " << a << "\n";
95#endif
96
97 return true;
98}
Base class for CLI-related errors.
Definition cli_error.hpp:10
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)
@ PositionalArgument
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.