GitHub - docopt/docopt.cpp: C++11 port of docopt
Pythonとかの情報はあるのだがC++はあんまりないので書いとく。
Docoptはgetoptやprogram_optionsのようなCLIから実行するときのコマンドやオプションを解析してくれるパーサなのだが、とにかく使い方がエレガントだ。注意点はGCC4.8だとなんかいろいろ大変ってことだろうか。GCC4.8を使っている場合については後述。
基本
かきかたはgithubにも書いてあるし、ここにもあるが、違うサンプルでかいてみる。
#include <docopt.h> //別にコードと同じ階層にdocoptのライブラリをコピーしてきても良いが綺麗じゃないのでわけた #include <iostream> //USAGEで定義する文字列の中にUsage: Options: でUsageとOptionsを指定するだけであとはよろしくやってくれる //exampleではなぜかcharを使っているが実装はstd::stringだった。いやまぁ暗黙で変換してくれるけどさ… static const std::string USAGE = R"(test Usage: test start (o <option> -p <option2> | -q <option3> [-d dir -v] test stop [now] test (-h | --help) test --version Options: -o option Set option -p option2 Set option2 -q option3 Set option3 -d dir Set directory -v Debug print -h --help Print help --version Print version )"; int main(int argc, const char** argv) { //コマンドラインで指定する引数を最初のバイナリ名だけは飛ばして最後までvectorに格納するらしい std::vector<std::string> arg {argv + 1, argv + argc}; //最後の引数に表示するバージョンスクリプトを指定 std::map<std::string, docopt::value> args = docopt::docopt(USAGE, arg, true, "SampleProgram v0.0.1"); //mapのキーはOptionsで指定したオプション名。値を取らないオプションの場合、docopt::valueはboolになる。それ以外はstd::string //helpとversionは特に実装しなくていいが、それ以外のオプションについては以降で処理を記述する //例 if(args["start"].asBool() == true) { std::cout << "stat" << std::endl; if((std::string)args["-o"].asString() != "") { //do something } } return 0; }
Usageを書けばそれにそってパースしてくれるというのがスマートでよい。コンパイルする場合はlibdocopt.aをリンクしよう。
GCC4.9以上が普通に入ってる場合
$ g++ -o test test.cpp -I<docoptdir> -ldocopt
GCC4.8以下の場合でGCC4.9を無理やり入れた場合は
$ g++-4.9 -o test test.cpp -I<docoptdir> -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -lstdc++ -ldocopt
libstdc++のリンクをしないといけない。
GCC4.9を無理やり入れてGCC4.9でdocoptをコンパイルする方法
C++11 regex using g++ | GeekWentFreak
ここにかいてあるとおりやればよい。
$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test $ sudo apt-get update $ sudo apt-get install g++-4.9
無理にgcc4.9を使うのでCMakeList.txtをいじってもいいけど自分でコンパイルすることにする(cmakeはよくわからん)
$ g++-4.9 --std=c++11 -D__cplusplus=201103L -D__GXX_EXPERIMENTAL_CXX0X__ -o docopt.o docopt.cpp docopt.h docopt_value.h docopt_util.h docopt_private.h $ ar -r "libdocopt.a" ./docopt.o
あれ?これでいいのかな?まぁEclipseで適当に設定してShared Libraryを作ってください
これでできたlibdocopt.aを使わないとregex関係のリンクが上手くできない
ちなみにgcc4.9以上が入っててもCMake3.2未満だとコンパイルできないのでとりあえずcmake3.2は入れる。
$ sudo apt-get install build-essential $ wget http://www.cmake.org/files/v3.2/cmake-3.2.2.tar.gz $ tar xf cmake-3.2.2.tar.gz $ cd cmake-3.2.2 $ ./configure $ make $ sudo apt-get install checkinstall $ sudo checkinstall $ sudo make install
そんでおもむろにライブラリを作る。
$ cmake . $ make
一度つかえるようになればかなり相当楽になる。