30

プログラムにサブコマンドを実装したいと思います。また、サブコマンドごとに異なる引数オプションを使用する機能も必要です。Boost.Program_options を使用してこれを行う最善の方法は何ですか?

サブコマンドは、svn、git、apt-get などのプログラムで使用されます。

たとえば、GIT で使用可能なサブコマンドの一部は次のとおりです。

git status  
git push  
git add  
git pull  

私の質問は基本的にこの男の質問と同じです: http://boost.2283326.n4.nabble.com/subcommands-with-program-options-like-svn-command-td2585537.html

4

2 に答える 2

52

私が問題を正しく理解している場合は、次の形式のコマンド ライン オプションを解析する必要があります。

[--generic-option ...] cmd [--cmd-specific-option ... ] 

これが私の解決策の例です。わかりやすくするために、検証コードは省略しますが、非常に簡単に追加する方法を理解していただければ幸いです。

この例では、「ls」サブコマンドと、場合によっては他のサブコマンドがあります。各サブコマンドにはいくつかの特定のオプションがあり、さらに一般的なオプションがあります。それでは、一般的なオプションとコマンド名を解析することから始めましょう。

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);

コマンド名に対して 1 つの定位置オプションを作成し、コマンド オプションに対して複数の定位置オプションを作成したことに注意してください。

次に、関連するコマンド名で分岐し、再解析します。argc元のオプションを渡す代わりにargv、認識されないオプションを文字列の配列の形式で渡します。関数はこれcollect_unrecognizedを提供できます - 私たちがしなければならないのは、(位置の) コマンド名を削除し、関連する で再解析することだけ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);

variables_mapコマンド固有のオプションには、一般的なオプションと同じものを使用したことに注意してください。これから、関連するアクションを実行できます。

ここに示すコード フラグメントは、いくつかの単体テストを含むコンパイル可能なソース ファイルから取得したものです。gist here で見つけることができます。ぜひダウンロードして遊んでみてください。

于 2014-04-16T03:42:15.657 に答える
3

位置オプションを使用して、コマンド ラインからサブコマンド名を削除できます。このチュートリアルを参照してください。

サブコマンドの組み込みサポートはないようですallow_unregistered。最上位のパーサーでオプションを設定し、コマンド名を見つけてから、サブコマンド固有のオプションを取得するために 2 番目のパーサーを実行する必要があります。

于 2013-04-20T00:41:43.517 に答える