Jeśli rozumiem problemu poprawnie, chcesz zanalizować opcji wiersza poleceń z poniższego formularza:
[--generic-option ...] cmd [--cmd-specific-option ... ]
Oto mój przykład rozwiązanie. Dla jasności będę pomijał kod walidacyjny, ale mam nadzieję, że zobaczysz, jak zostałby dodany dość prosto.
W tym przykładzie mamy podkomendę "ls" i prawdopodobnie inne. Każda podkomenda ma określone opcje, a ponadto dostępne są opcje ogólne. Zacznijmy od analizowania ogólnych opcji i nazwy polecenia.
po::options_description global("Global options");
global.add_options()
("debug", "Turn on debug output")
("command", po::value<std::string>(), "command to execute")
("subargs", po::value<std::vector<std::string> >(), "Arguments for command");
po::positional_options_description pos;
pos.add("command", 1).
add("subargs", -1);
po::variables_map vm;
po::parsed_options parsed = po::command_line_parser(argc, argv).
options(global).
positional(pos).
allow_unregistered().
run();
po::store(parsed, vm);
Zauważ, że utworzyliśmy pojedynczą opcję pozycyjną dla nazwy polecenia oraz wiele opcji pozycyjnych dla opcji polecenia.
Teraz rozgałęziamy na odpowiednią nazwę polecenia i ponownie analizujemy. Zamiast podawać oryginalne argc
i argv
, teraz przekazujemy nierozpoznane opcje w postaci tablicy łańcuchów. Może to zapewnić funkcja collect_unrecognized
- wystarczy, że usuniemy (pozycyjną) nazwę polecenia i ponownie przeanalizujemy odpowiedni numer options_description
.
std::string cmd = vm["command"].as<std::string>();
if (cmd == "ls")
{
// ls command has the following options:
po::options_description ls_desc("ls options");
ls_desc.add_options()
("hidden", "Show hidden files")
("path", po::value<std::string>(), "Path to list");
// Collect all the unrecognized options from the first pass. This will include the
// (positional) command name, so we need to erase that.
std::vector<std::string> opts = po::collect_unrecognized(parsed.options, po::include_positional);
opts.erase(opts.begin());
// Parse again...
po::store(po::command_line_parser(opts).options(ls_desc).run(), vm);
Zauważ, że użyliśmy tego samego variables_map
dla opcji polecenia specyficzne jak dla tych generycznych. Z tego możemy wykonać odpowiednie działania.
Fragmenty kodu pochodzą z kompilacyjnego pliku źródłowego zawierającego niektóre testy jednostkowe. Można go znaleźć na gist here. Pobierz i graj z nim.
Doskonała odpowiedź, z pełnym przykładem do rozruchu. Dziękuję Ci! --DD – ddevienne
Niesamowita odpowiedź! –