パスワードを忘れた? アカウント作成
494123 journal

yhtの日記: boost.program_option~2

日記 by yht

前のboost::program_option~1ではコマンドライン・オプションを読み込む簡単な例を見たが, オプションにデフォルト値を与えたり、色々な型のオプションを使えたりすると便利なので、 ちょっとした応用編。

例によって、boost.orgのドキュメントを参照の事。この例の全ソースはlibs/program_options/example/options_description.cpp

以下は、直訳・意訳・妄想・実験結果等。

前回と同様、

#include <boost/program_options.hpp>

using namespace boost;
namespace po = boost::program_options;

#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;

とお約束から始まる。

次に、前回と同様にpo::options_descriptionクラスの変数を用意してサポートするオプションを登録してゆくのだが、今回は少し変えてある。

  int opt;
  po::options_description desc("Allowed options");
    desc.add_options()
      ("help", "produce help message")
      ("optimization", po::value<int>(&opt)->default_value(10), "optimization level")
      ("include-path,I", po::value< vector<string> >(), "include path")
      ("input-file", po::value< vector<string> >(), "input file");

「help」オプションは、前回と同じ。どんな場合でもこのオプションを加えておくのがよい。

「optimization」オプションは、前回の「compression」と次の2点で異なる。
1. 変数のアドレス(&opt)を指定している。この変数の中にオプションの値が入っていく。
2. ユーザーが指定しなかった場合のオプションのデフォルト値10を指定している。

「include-path」オプションはinclude pathをコマンドラインから読み込み(複数可)、 std::vector<std::string>に入れる。別名として、短縮形「-I」でも受け付ける。 また、options_descriptionクラスのインターフェースが一つのソース(コマンドライン)だけ から読み込む唯一の例になっている。

「input-file」オプションは、処理すべきファイルのリストで、

compiler --input-file=a.cpp

というように使うことになり、

compiler a.cpp

という標準的な使い方と比べると少し変だが、初めてだからよいだろう。

上の例のように、オプションの名前の無いコマンドライン・トークンを、 このライブラリでは``positional options''と呼び、この種類のものも 読み込む事が出来る。ユーザーの若干の骨折りで、``a.cpp'' が ``--input-file=a.cpp''であることをライブラリに教えてやればよい。 その為に必要なコードは

  po::positional_options_description p;
  p.add("input-file", -1);

  po::variables_map vm;
  po::store(po::command_line_parser(ac, av).
    options(desc).positional(p).run(), vm);
  po::notify(vm);

の最初の2行。後半4行でコマンドラインからvmへオプションを読み込んでいる。 前回はpo::parse_command_line()函数で読み込んだ(簡素な読み込みルールの場合は こちらが便利)が、より詳しい情報をやり取りする必要があり、po::command_line_parser クラスを利用する。

これでオプションの読み込みが済んだので、コンパイラの実装は省略し、オプションの 表示のみをする。

  if (vm.count("help")) {
    cout << "Usage: options_description [options]\n";
    cout << desc;
    return 0;
  }

  if (vm.count("include-path"))
  {
    cout << "Include paths are: "
      << vm["include-path"].as< vector<string> >() << "\n";
  }

  if (vm.count("input-file"))
  {
    cout << "Input files are: "
      << vm["input-file"].as< vector<string> >() << "\n";
  }

  cout << "Optimization level is " << opt << "\n";

必要なコードは実装したので、コンパイルと実行。

%g++ -o odesc -O2 options_description.cpp -lboost_program_options-mt
%

でコンパイル。-lboost_program_optionsでもよい。

%./odesc --help
Usage: options_description [options]
Allowed options:
  --help                    produce help message
  --optimization arg (=10)  optimization level
  -I [ --include-path ] arg include path
  --input-file arg          input file
%./odesc -I /usr/local/include a.cpp
Include paths are: /usr/local/include
Input files are: a.cpp
Optimization level is 10
%./odesc -I /usr/local/include a.cpp --optimization 15
Include paths are: /usr/local/include
Input files are: a.cpp
Optimization level is 15
%

さて、上の例でまだちょっとした問題が残っている。 それは``--input-file''オプションを指定できることと、表示されていること。 オプションを隠すのは次の例まで待ってほしい。

typodupeerror

あと、僕は馬鹿なことをするのは嫌いですよ (わざとやるとき以外は)。-- Larry Wall

読み込み中...