#はじめに
コマンドラインのプログラムを簡単にするクロスプラットフォームで動作するライブラリ(mibase)を作成しました.このライブラリは,プログラムの作成で面倒な箇所を簡単に記述する方法を提供します.たとえば,普通のプログラムであれば,入力ファイル名,出力ファイル名,各種パラメータを入力としますが,何も使わないと最大最小などの条件チェックでif文だらけのプログラムになります.このライブラリは,このような面倒な処理を行うクラス群を用意しています.その結果,可読性の高いコードを書けるようになります.わたしは,これを自分の研究用途で利用しています.
##できること
このライブラリは,クロスプラットフォームで動作することを想定しています.具体的なターゲットは,MacとWindowsですが,Linuxでも動くとおもわれます.提供している機能は以下の通りです.
- 引数を解析し,各引数について諸条件(最大,最小など)を設定する.
- 文字列をスペースなどで分解する
- 簡単な並列処理を行う (スレッドの管理,std::for_each()の並列版)
- 時間計測,システム情報の取得,ピークメモリ使用量を取得
- その他
##ダウンロード&コンパイル
GitHubにて公開しています.ライセンスはMITライセンスです.
コンパイルは,CMakeを使っています.Unix系でしたら以下でインストールできます.
% cd mibase
% mkdir build
% cd build
% cmake ..
% make
% make install
Visual StudioなどでしたらCMakeからVisual Studioのソリューションファイルを作成できます.
いずれの方法でも共有ライブラリが作成されます.
#サンプル
以下の3つのプログラムは,最も単純なコマンドです.2つの文字列と浮動小数点1個を引数としたプログラムです.各行の意味は読めばわかるとおもいます.ファイルは,mibase/sampleにあります.CMakeLists.txtにリンクの方法などが記載されています.
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <mi/CommandTemplate.hpp>
#include <mi/AttributeSet.hpp>
#include <mi/SystemInfo.hpp>
class ExampleCommand : public mi::CommandTemplate
{
private:
std::string _input_file;
std::string _output_file;
double _param0;
public:
ExampleCommand ( void ) ;
~ExampleCommand ( void ) ;
bool init ( const mi::Argument& arg ) ;
bool run ( void );
bool term ( void );
};
ExampleCommand::ExampleCommand ( void ) : mi::CommandTemplate( )
{
mi::AttributeSet &attrSet = this->getAttributeSet();
attrSet.createStringAttribute( "-i", this->_input_file, "input file" ).setMandatory();
attrSet.createStringAttribute( "-o", this->_output_file, "output file" ).setMandatory();
attrSet.createNumericAttribute( "-p", this->_param0, "value").setMin(-10).setMax(10).setDefaultValue(0);
return;
}
ExampleCommand::~ExampleCommand ( void )
{
std::cerr<<"ExampleCommand::~ExampleCommand() was called."<<std::endl;
std::cerr<<"peak memory : "<<mi::SystemInfo::getPeakMemorySize( mi::MI_KILO_BYTE )<<"[kb]"<<std::endl;
return;
}
bool
ExampleCommand::init ( const mi::Argument& arg )
{
mi::AttributeSet &attrSet = this->getAttributeSet();
if( !attrSet.parse( arg ) ) {
attrSet.printError();
return false;
}
attrSet.print();
return true;
}
bool
ExampleCommand:: run ( void )
{
std::cerr<<"ExampleCommand::run() was called."<<std::endl;
return true;
}
bool
ExampleCommand:: term ( void )
{
std::cerr<<"ExampleCommand::term() was called."<<std::endl;
return true;
}
int main ( int argc, char** argv )
{
mi::Argument arg( argc, argv );
ExampleCommand cmd;
if ( !cmd.init( arg ) ) {
std::cerr<<"initalization failed."<<std::endl;
return -1;
}
if ( !cmd.run() ) {
std::cerr<<"execution failed."<<std::endl;
return -2;
}
if ( !cmd.term() ) {
std::cerr<<"terminiation failed."<<std::endl;
return -3;
}
return 0;
}
#クラスの説明
- CommandTemplate: コマンドを作るベースとなるクラス
- Argument: 引数を解析
- Attribute: 属性を解析する基底クラス
- BooleanAttribute: ブール値属性を解析するクラス
- NumericAttribute: 数値属性を解析するクラス
- StringAttribute: 文字列属性を解析するクラス