This commit is contained in:
lltcggie 2015-05-29 01:47:26 +09:00
parent b272b6fec0
commit 91c3d4c4b1
58 changed files with 9005 additions and 1 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "rapidjson"]
path = rapidjson
url = https://github.com/miloyip/rapidjson.git

166
README.md
View File

@ -1,2 +1,166 @@
# waifu2x-caffe
waifu2xのCaffe版
本ソフトは、画像変換ソフトウェア「[waifu2x](https://github.com/nagadomi/waifu2x)」の変換機能のみを、
[Caffe](http://caffe.berkeleyvision.org/)を用いて書き直したソフトです。
要求環境
----------
このソフトを動作させるには最低でも以下の環境が必要です。
* OS : Windows Vista以降 64bit (32bit用exeはありません)
* メモリ : 空きメモリ1GB以上 (ただし、変換する画像サイズによる)
* Visual C++ 2013 再頒布可能パッケージがインストールされていること(必須)
- 上記パッケージは[こちら](https://www.microsoft.com/ja-jp/download/details.aspx?id=40784)
- `ダウンロード` ボタンを押した後、`vcredist_x64.exe`を選択し、ダウンロード・インストールを行って下さい。
- 見つからない場合は、「Visual C++ 2013 再頒布可能パッケージ」で検索してみて下さい。
cuDNNで変換する場合はさらに
* GPU : Compute Capability 3.0 以上のNVIDIA製GPU
自分のGPUのCompute Capabilityが知りたい場合は[こちらのページ](https://developer.nvidia.com/cuda-gpus)で調べて下さい。
cuDNNについて
--------
cuDNNはNVIDIA製GPUでのみつかえる高速な機械学習向けのライブラリです。
cuDNNを使うと使わない場合に比べて大きな画像を高速に変換することが出来ますが(cuDNNを使わなくてもGPUで変換出来ます)、
ライセンスの関係上動作に必要なファイルを配布することが出来ません。
なので、cuDNNを使いたい人は[こちらのページ](https://developer.nvidia.com/cuDNN)でWindows向けバイナリをダウンロードし、
「cudnn64_65.dll」をwaifu2x-caffeのフォルダに入れて下さい。
(cuDNNをダウンロードするにはNVIDIA Developerへの登録とCUDA Registered Developersへの登録が必要です。
CUDA Registered Developersはおそらく(簡単な)審査があるっぽいので登録してもすぐにcuDNNをダウンロード出来るわけではありません。)
使い方
--------
「waifu2x-caffe.exe」はGUIソフトです。ダブルクリックで起動します。
「入力」欄に画像かフォルダをドラッグ&ドロップで放り込むと「出力」欄が自動で設定されます。
出力先を変えたい場合は「出力」欄を変更して下さい。
好みに合わせて変換設定を変更することが出来ます。
「変換モード」
変換モードを指定します。
* ノイズ除去 : ノイズ除去を行います
* 拡大 : 拡大を行います
* ノイズ除去と拡大 : ノイズ除去と拡大を行います
* ノイズ除去(自動判別)と拡大 : 拡大を行います。入力がJPEG画像の場合のみイズ除去も行います
「JPEGイズ除去レベル」
ノイズ除去レベルを指定します。
「拡大率」
拡大率を指定します
「出力拡張子」
出力拡張子を指定します
「プロセッサー」
変換を行うプロセッサーを指定します
* CPU : CPUのみを使って変換を行います
* GPU(使えたらcuDNN) : GPUを使って変換を行います(cuDNNが使えるならcuDNNが使われます)
「cuDNNチェック」ボタンを押すとcuDNNが使えるか調べることが出来ます。
が、cuDNNが動く環境でしか動かしていないためうまくチェック出来るかは不明です。
「実行」ボタンを押すと変換が始まります。
途中でキャンセルしたい場合は「キャンセル」ボタンを押します。
ただし、実際に停止するまでタイムラグがあります。
「waifu2x-caffe-cui.exe」はコマンドラインツールです。
`コマンドプロンプト` を立ち上げ、次のようにコマンドを打ち込み、使用して下さい。
以下のコマンドは、使い方を画面に出力します。
```
waifu2x-caffe-cui.exe --help
```
以下のコマンドは、画像変換を実行するコマンドの例です。
```
waifu2x-caffe-cui.exe -i mywaifu.png -m noise_scale -j 8 --scale_ratio 1.6 --noise_level 2
```
以上を実行すると、`mywaifu(noise_scale)(Level2)(x1.600000).png`に変換結果が保存されます。
本ソフトでは、以下のオプションを指定することが出来ます。
-i <文字列>, --input_file <文字列>
(必須) 変換する画像へのパス
フォルダを指定した場合、そのフォルダ以下の画像ファイルを全て変換してoutput_fileで指定したフォルダへ出力します。
-o <string>, --output_file <string>
変換された画像を保存するファイルへのパス
(input_fileがフォルダの場合)変換された画像を保存するフォルダへのパス
(input_fileが画像ファイルの場合)拡張子(最後の.pngなど)は必ず入力するようにして下さい。
指定しなかった場合は自動でファイル名を決定し、そのファイルに保存します。
ファイル名の決定ルールは、
`[元の画像ファイル名]``(モード名)``(ノイズ除去レベル(ノイズ除去モードの場合))``(拡大率(拡大モードの場合))``.png`
のようになっています。
保存される場所は、基本的には入力画像と同じディレクトリになります。
-l <文字列>, --input_extention_list <文字列>
input_fileがフォルダの場合の、フォルダ内の変換する画像の拡張子を指定します。
デフォルト値は`png:jpg:bmp`です。
また、区切り文字は`:`です。
例. png:jpg:bmp
-l <文字列>, --input_extention_list <文字列>
input_fileがフォルダの場合の、出力画像の拡張子を指定します。
デフォルト値は`png`です。
-m <noise|scale|noise_scale>, --mode <noise|scale|noise_scale>
変換モードを指定します。指定しなかった場合は`noise_scale`が選択されます。
* noise : ノイズ除去を行います (正確には、ノイズ除去用のモデルを用いて画像変換を行います)
* scale : 拡大を行います (正確には、既存アルゴリズムで拡大した後に、拡大画像補完用のモデルを用いて画像変換を行います)
* noise_scale : ノイズ除去と拡大を行います (ノイズ除去を行った後に、引き続き拡大処理を行います)
* auto_scale : 拡大を行います。入力がJPEG画像の場合のみイズ除去も行います
-s <小数点付き数値>, --scale_ratio <小数点付き数値>
何倍に拡大するかを指定します。デフォルト値は`2.0`ですが、2.0倍以外も指定できます。
2.0以外の数値を指定すると、次のような処理を行います。
* まず、指定された倍率を必要十分にカバーするように、2倍拡大を繰り返し行います。
* 2の累乗以外の数値がしてされている場合は、指定倍率になるように拡大した画像を線形フィルタで縮小します。
-n <1|2>, --noise_level <1|2>
イズ除去レベルを指定します。イズ除去用のモデルはレベル1とレベル2のみ用意されているので、
1 もしくは 2 を指定して下さい。
デフォルト値は`1`です。
--model_dir <文字列>
モデルが格納されているディレクトリへのパスを指定します。デフォルト値は`models`です。
基本的には指定しなくても大丈夫です。独自のモデルを使用する時などに指定して下さい。
--, --ignore_rest
このオプションが指定された後の全てのオプションを無視します。
スクリプト・バッチファイル用です。
--version
バージョン情報を出力し、終了します。
-h, --help
使い方を表示し、終了します。
手軽に使い方を確認したい時などにどうぞ。
おことわり
------------
本ソフトは無保証です。
利用者の判断の下に使用して下さい。
制作者はいかなる義務も負わないものとします。
謝辞
------
オリジナルのwaifu2x、及びモデルの制作を行い、MITライセンスの下で公開して下さった ultraistさん、
オリジナルのwaifu2xを元にwaifu2x-converterを作成して下さった アミーゴさん(READMEやLICENSE.txtの書き方、OpenCVの使い方等かなり参考にさせていただきました)
に、感謝します。

583
common/waifu2x.cpp Normal file
View File

@ -0,0 +1,583 @@
#include "waifu2x.h"
#include <caffe/caffe.hpp>
#include <cudnn.h>
#include <mutex>
#include <opencv2/opencv.hpp>
#include <rapidjson/document.h>
#include <tclap/CmdLine.h>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#if defined(WIN32) || defined(WIN64)
#include <Windows.h>
#endif
#ifdef _MSC_VER
#ifdef _DEBUG
#pragma comment(lib, "libcaffed.lib")
#pragma comment(lib, "libprotobufd.lib")
#else
#pragma comment(lib, "libcaffe.lib")
#pragma comment(lib, "libprotobuf.lib")
#endif
#pragma comment(lib, "libprotoc.lib")
#endif
const auto block_size = 128;
const auto offset = 0;
const auto layer_num = 7;
const auto output_size = block_size - offset * 2;
const int ConvertMode = CV_RGB2YUV;
const int ConvertInverseMode = CV_YUV2RGB;
std::once_flag waifu2x_once_flag;
std::once_flag waifu2x_cudnn_once_flag;
// cuDNNが使えるかチェック。現状Windowsのみ
bool can_use_cuDNN()
{
static bool cuDNNFlag = false;
std::call_once(waifu2x_cudnn_once_flag, [&]()
{
#if defined(WIN32) || defined(WIN64)
HMODULE hModule = LoadLibrary(TEXT("cudnn64_65.dll"));
if (hModule != NULL)
{
typedef cudnnStatus_t(*cudnnCreateType)(cudnnHandle_t *);
typedef cudnnStatus_t(*cudnnDestroyType)(cudnnHandle_t);
cudnnCreateType cudnnCreateFunc = (cudnnCreateType)GetProcAddress(hModule, "cudnnCreate");
cudnnDestroyType cudnnDestroyFunc = (cudnnDestroyType)GetProcAddress(hModule, "cudnnDestroy");
if (cudnnCreateFunc != nullptr && cudnnDestroyFunc != nullptr)
{
cudnnHandle_t h;
if (cudnnCreateFunc(&h) == CUDNN_STATUS_SUCCESS)
{
if (cudnnDestroyFunc(h) == CUDNN_STATUS_SUCCESS)
cuDNNFlag = true;
}
}
FreeLibrary(hModule);
}
#endif
});
return cuDNNFlag;
}
// 画像を読み込んで値を0.0f1.0fの範囲に変換
eWaifu2xError LoadImage(cv::Mat &float_image, const std::string &input_file)
{
cv::Mat original_image = cv::imread(input_file, cv::IMREAD_COLOR);
if (original_image.empty())
return eWaifu2xError_FailedOpenInputFile;
original_image.convertTo(float_image, CV_32F, 1.0 / 255.0);
original_image.release();
return eWaifu2xError_OK;
}
// 画像から輝度の画像を取り出す
eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im)
{
cv::Mat converted_color;
cv::cvtColor(float_image, converted_color, ConvertMode);
std::vector<cv::Mat> planes;
cv::split(converted_color, planes);
im = planes[0];
planes.clear();
return eWaifu2xError_OK;
}
// 入力画像の(Photoshopでいう)キャンバスサイズをoutput_sizeの倍数に変更
// 画像は左上配置、余白はcv::BORDER_REPLICATEで埋める
eWaifu2xError PaddingImage(const cv::Mat &input, cv::Mat &output)
{
const auto h_blocks = (int)floor(input.size().width / output_size) + (input.size().width % output_size == 0 ? 0 : 1);
const auto w_blocks = (int)floor(input.size().height / output_size) + (input.size().height % output_size == 0 ? 0 : 1);
const auto height = offset + h_blocks * output_size + offset;
const auto width = offset + w_blocks * output_size + offset;
const auto pad_h1 = offset;
const auto pad_w1 = offset;
const auto pad_h2 = (height - offset) - input.size().width;
const auto pad_w2 = (width - offset) - input.size().height;
cv::copyMakeBorder(input, output, pad_w1, pad_w2, pad_h1, pad_h2, cv::BORDER_REPLICATE);
return eWaifu2xError_OK;
}
// 画像をcv::INTER_NEARESTで二倍に拡大して、PaddingImage()でパディングする
eWaifu2xError Zoom2xAndPaddingImage(const cv::Mat &input, cv::Mat &output, cv::Size_<int> &zoom_size)
{
zoom_size = input.size();
zoom_size.width *= 2;
zoom_size.height *= 2;
cv::Mat zoom_image;
cv::resize(input, zoom_image, zoom_size, 0.0, 0.0, cv::INTER_NEAREST);
return PaddingImage(zoom_image, output);
}
// 入力画像をzoom_sizeの大きさにcv::INTER_CUBICで拡大し、色情報のみを残す
eWaifu2xError CreateZoomColorImage(const cv::Mat &float_image, const cv::Size_<int> &zoom_size, std::vector<cv::Mat> &cubic_planes)
{
cv::Mat zoom_cubic_image;
cv::resize(float_image, zoom_cubic_image, zoom_size, 0.0, 0.0, cv::INTER_CUBIC);
cv::Mat converted_cubic_image;
cv::cvtColor(zoom_cubic_image, converted_cubic_image, ConvertMode);
zoom_cubic_image.release();
cv::split(converted_cubic_image, cubic_planes);
converted_cubic_image.release();
// このY成分は使わないので解放
cubic_planes[0].release();
return eWaifu2xError_OK;
}
// 学習したパラメータをファイルから読み込む
eWaifu2xError LoadParameter(boost::shared_ptr<caffe::Net<float>> net, const std::string &param_path)
{
rapidjson::Document d;
std::vector<char> jsonBuf;
try
{
FILE *fp = fopen(param_path.c_str(), "rb");
if (fp == nullptr)
return eWaifu2xError_FailedOpenModelFile;
fseek(fp, 0, SEEK_END);
const auto size = ftell(fp);
fseek(fp, 0, SEEK_SET);
jsonBuf.resize(size + 1);
fread(jsonBuf.data(), 1, size, fp);
fclose(fp);
jsonBuf[jsonBuf.size() - 1] = '\0';
d.Parse(jsonBuf.data());
}
catch (...)
{
return eWaifu2xError_FailedParseModelFile;
}
std::vector<boost::shared_ptr<caffe::Layer<float>>> list;
auto &v = net->layers();
for (auto &l : v)
{
auto lk = l->type();
auto &bv = l->blobs();
if (bv.size() > 0)
list.push_back(l);
}
try
{
int count = 0;
for (auto it = d.Begin(); it != d.End(); ++it)
{
const auto &weight = (*it)["weight"];
const auto nInputPlane = (*it)["nInputPlane"].GetInt();
const auto nOutputPlane = (*it)["nOutputPlane"].GetInt();
const auto kW = (*it)["kW"].GetInt();
const auto &bias = (*it)["bias"];
auto leyer = list[count];
auto &b0 = leyer->blobs()[0];
auto &b1 = leyer->blobs()[1];
float *b0Ptr = nullptr;
float *b1Ptr = nullptr;
if (caffe::Caffe::mode() == caffe::Caffe::CPU)
{
b0Ptr = b0->mutable_cpu_data();
b1Ptr = b1->mutable_cpu_data();
}
else
{
b0Ptr = b0->mutable_gpu_data();
b1Ptr = b1->mutable_gpu_data();
}
const auto WeightSize1 = weight.Size();
const auto WeightSize2 = weight[0].Size();
const auto KernelHeight = weight[0][0].Size();
const auto KernelWidth = weight[0][0][0].Size();
if (!(b0->count() == WeightSize1 * WeightSize2 * KernelHeight * KernelWidth))
return eWaifu2xError_FailedConstructModel;
if (!(b1->count() == bias.Size()))
return eWaifu2xError_FailedConstructModel;
size_t weightCount = 0;
std::vector<float> weightList;
for (auto it2 = weight.Begin(); it2 != weight.End(); ++it2)
{
for (auto it3 = (*it2).Begin(); it3 != (*it2).End(); ++it3)
{
for (auto it4 = (*it3).Begin(); it4 != (*it3).End(); ++it4)
{
for (auto it5 = (*it4).Begin(); it5 != (*it4).End(); ++it5)
weightList.push_back((float)it5->GetDouble());
}
}
}
caffe::caffe_copy(b0->count(), weightList.data(), b0Ptr);
std::vector<float> biasList;
for (auto it2 = bias.Begin(); it2 != bias.End(); ++it2)
biasList.push_back((float)it2->GetDouble());
caffe::caffe_copy(b1->count(), biasList.data(), b1Ptr);
count++;
}
}
catch (...)
{
return eWaifu2xError_FailedConstructModel;
}
return eWaifu2xError_OK;
}
// モデルファイルからネットワークを構築
// processでcudnnが指定されなかった場合はcuDNNが呼び出されないように変更する
eWaifu2xError ConstractNet(boost::shared_ptr<caffe::Net<float>> &net, const std::string &model_path, const std::string &process)
{
caffe::NetParameter param;
if (!caffe::ReadProtoFromTextFile(model_path, &param))
return eWaifu2xError_FailedOpenModelFile;
param.mutable_state()->set_phase(caffe::TEST);
for (int i = 0; i < param.layer_size(); i++)
{
caffe::LayerParameter *layer_param = param.mutable_layer(i);
const std::string& type = layer_param->type();
if (type == "Convolution")
{
if (process == "cudnn")
layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CUDNN);
else
layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CAFFE);
}
else if (type == "ReLU")
{
if (process == "cudnn")
layer_param->mutable_relu_param()->set_engine(caffe::ReLUParameter_Engine_CUDNN);
else
layer_param->mutable_relu_param()->set_engine(caffe::ReLUParameter_Engine_CAFFE);
}
}
net = boost::shared_ptr<caffe::Net<float>>(new caffe::Net<float>(param));
return eWaifu2xError_OK;
}
// ネットワークを使って画像を再構築する
eWaifu2xError ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat &im, const waifu2xProgressFunc func)
{
const auto Height = im.size().height;
const auto Width = im.size().width;
const auto Line = im.step1();
assert(im.channels() == 1);
float *imptr = (float *)im.data;
try
{
const auto input_layer =
boost::dynamic_pointer_cast<caffe::MemoryDataLayer<float>>(
net->layer_by_name("image_input_layer"));
assert(input_layer);
const auto conv7_layer =
boost::dynamic_pointer_cast<caffe::ConvolutionLayer<float>>(
net->layer_by_name("conv7_layer"));
assert(conv7_layer);
// ネットワークに入力する画像のサイズ(出力画像の幅はlayer_num * 2だけ小さくなる)
const int block_width = block_size + layer_num * 2;
std::vector<float> block(block_width * block_width, 0.0f);
std::vector<float> dummy_data(block.size(), 0.0f);
// 画像は(消費メモリの都合上)output_size*output_sizeに分けて再構築する
for (int h = 0; h < Height; h += output_size)
{
for (int w = 0; w < Width; w += output_size)
{
if (w + block_size <= Width && h + block_size <= Height)
{
{
cv::Mat someimg = im(cv::Rect(w, h, block_size, block_size));
cv::Mat someborderimg;
// 画像を中央にパディング。余白はcv::BORDER_REPLICATEで埋める
cv::copyMakeBorder(someimg, someborderimg, layer_num, layer_num, layer_num, layer_num, cv::BORDER_REPLICATE);
someimg.release();
// 画像を直列に変換
{
float *fptr = block.data();
const float *uptr = (const float *)someborderimg.data;
const auto Line = someborderimg.step1();
for (int i = 0; i < block_width; i++)
memcpy(fptr + i * block_width, uptr + i * Line, block_width * sizeof(float));
}
}
// ネットワークに画像を入力
input_layer->Reset(block.data(), dummy_data.data(), block.size());
// 計算
auto out = net->ForwardPrefilled(nullptr);
auto b = out[0];
assert(b->count() == block_size * block_size);
const float *ptr = nullptr;
if (caffe::Caffe::mode() == caffe::Caffe::CPU)
ptr = b->cpu_data();
else
ptr = b->gpu_data();
// 結果を入力画像にコピー(後に処理する部分とここで上書きする部分は被らないから、入力画像を上書きしても大丈夫)
for (int i = 0; i < block_size; i++)
caffe::caffe_copy(block_size, ptr + i * block_size, imptr + (h + i) * Line + w);
}
}
}
}
catch (...)
{
return eWaifu2xError_FailedProcessCaffe;
}
return eWaifu2xError_OK;
}
eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPair> &file_paths,
const std::string &mode, const int noise_level, const double scale_ratio, const std::string &model_dir, const std::string &process,
std::vector<PathAndErrorPair> &errors, const waifu2xCancelFunc cancel_func, const waifu2xProgressFunc progress_func)
{
if (scale_ratio <= 0.0)
return eWaifu2xError_InvalidParameter;
eWaifu2xError ret;
std::call_once(waifu2x_once_flag, [argc, argv]()
{
assert(argc >= 1);
int tmpargc = 1;
char* tmpargvv[] = { argv[0] };
char** tmpargv = tmpargvv;
// glog等の初期化
caffe::GlobalInit(&tmpargc, &tmpargv);
});
std::string process_fix(process);
if (process_fix == "gpu")
{
// cuDNNが使えそうならcuDNNを使う
if (can_use_cuDNN())
process_fix = "cudnn";
}
boost::filesystem::path mode_dir_path(model_dir);
if (!mode_dir_path.is_absolute()) // model_dirが相対パスなら絶対パスに直す
{
// まずはカレントディレクトリ下にあるか探す
mode_dir_path = boost::filesystem::absolute(model_dir);
if (!boost::filesystem::exists(mode_dir_path) && argc >= 1) // 無かったらargv[0]から実行ファイルのあるフォルダを推定し、そのフォルダ下にあるか探す
{
boost::filesystem::path a0(argv[0]);
if (a0.is_absolute())
mode_dir_path = a0.branch_path() / model_dir;
}
}
if (!boost::filesystem::exists(mode_dir_path))
return eWaifu2xError_FailedOpenModelFile;
if (process_fix == "cpu")
caffe::Caffe::set_mode(caffe::Caffe::CPU);
else
caffe::Caffe::set_mode(caffe::Caffe::GPU);
boost::shared_ptr<caffe::Net<float>> net_noise;
boost::shared_ptr<caffe::Net<float>> net_scale;
if (mode == "noise" || mode == "noise_scale" || mode == "auto_scale")
{
const std::string model_path = (mode_dir_path / "srcnn.prototxt").string();
const std::string param_path = (mode_dir_path / ("noise" + std::to_string(noise_level) + "_model.json")).string();
ret = ConstractNet(net_noise, model_path, process);
if (ret != eWaifu2xError_OK)
return ret;
ret = LoadParameter(net_noise, param_path);
if (ret != eWaifu2xError_OK)
return ret;
}
if (mode == "scale" || mode == "noise_scale" || mode == "auto_scale")
{
const std::string model_path = (mode_dir_path / "srcnn.prototxt").string();
const std::string param_path = (mode_dir_path / "scale2.0x_model.json").string();
ret = ConstractNet(net_scale, model_path, process);
if (ret != eWaifu2xError_OK)
return ret;
ret = LoadParameter(net_scale, param_path);
if (ret != eWaifu2xError_OK)
return ret;
}
int fileCount = 0;
for (const auto &p : file_paths)
{
progress_func(file_paths.size(), fileCount);
if (cancel_func())
return eWaifu2xError_Cancel;
const auto &input_file = p.first;
const auto &output_file = p.second;
cv::Mat float_image;
ret = LoadImage(float_image, input_file);
if (ret != eWaifu2xError_OK)
{
errors.emplace_back(p, ret);
continue;
}
cv::Mat im;
CreateBrightnessImage(float_image, im);
cv::Size_<int> image_size = im.size();
const boost::filesystem::path ip(input_file);
const boost::filesystem::path ipext(ip.extension());
const bool isJpeg = boost::iequals(ipext.string(), ".jpg") || boost::iequals(ipext.string(), ".jpeg");
const bool isReconstructNoise = mode == "noise" || mode == "noise_scale" || (mode == "auto_scale" && isJpeg);
const bool isReconstructScale = mode == "scale" || mode == "noise_scale";
if (isReconstructNoise)
{
PaddingImage(im, im);
ret = ReconstructImage(net_noise, im, progress_func);
if (ret != eWaifu2xError_OK)
{
errors.emplace_back(p, ret);
continue;
}
// パディングを取り払う
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
}
if (cancel_func())
return eWaifu2xError_Cancel;
const int scale2 = ceil(log2(scale_ratio));
const double shrinkRatio = scale_ratio / std::pow(2.0, (double)scale2);
if (isReconstructScale)
{
bool isError = false;
for (int i = 0; i < scale2; i++)
{
Zoom2xAndPaddingImage(im, im, image_size);
ret = ReconstructImage(net_scale, im, progress_func);
if (ret != eWaifu2xError_OK)
{
errors.emplace_back(p, ret);
isError = true;
break;
}
// パディングを取り払う
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
}
if (isError)
continue;
}
if (cancel_func())
return eWaifu2xError_Cancel;
// 再構築した輝度画像とCreateZoomColorImage()で作成した色情報をマージして通常の画像に変換し、書き込む
std::vector<cv::Mat> color_planes;
CreateZoomColorImage(float_image, image_size, color_planes);
float_image.release();
color_planes[0] = im;
im.release();
cv::Mat converted_image;
cv::merge(color_planes, converted_image);
color_planes.clear();
cv::Mat process_image;
cv::cvtColor(converted_image, process_image, ConvertInverseMode);
converted_image.release();
const cv::Size_<int> ns(image_size.width * shrinkRatio, image_size.height * shrinkRatio);
if (image_size.width != ns.width || image_size.height != ns.height)
cv::resize(process_image, process_image, ns, 0.0, 0.0, cv::INTER_LINEAR);
cv::Mat write_iamge;
process_image.convertTo(write_iamge, CV_8U, 255.0);
process_image.release();
if (!cv::imwrite(output_file, write_iamge))
{
errors.emplace_back(p, eWaifu2xError_FailedOpenOutputFile);
continue;
}
write_iamge.release();
fileCount++;
}
progress_func(file_paths.size(), fileCount);
return eWaifu2xError_OK;
}

32
common/waifu2x.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include <string>
#include <vector>
#include <utility>
#include <functional>
enum eWaifu2xError
{
eWaifu2xError_OK = 0,
eWaifu2xError_Cancel,
eWaifu2xError_InvalidParameter,
eWaifu2xError_FailedOpenInputFile,
eWaifu2xError_FailedOpenOutputFile,
eWaifu2xError_FailedOpenModelFile,
eWaifu2xError_FailedParseModelFile,
eWaifu2xError_FailedConstructModel,
eWaifu2xError_FailedProcessCaffe,
};
typedef std::pair<std::string, std::string> InputOutputPathPair;
typedef std::pair<InputOutputPathPair, eWaifu2xError> PathAndErrorPair;
typedef std::function<bool()> waifu2xCancelFunc;
typedef std::function<void(const int ProgressFileMax, const int ProgressFileNow)> waifu2xProgressFunc;
bool can_use_cuDNN();
// mode: noise or scale or noise_scale or auto_scale
// process: cpu or gpu or cudnn
eWaifu2xError waifu2x(int argc, char** argv,
const std::vector<InputOutputPathPair> &file_paths, const std::string &mode, const int noise_level, const double scale_ratio, const std::string &model_dir, const std::string &process,
std::vector<PathAndErrorPair> &errors, const waifu2xCancelFunc cancel_func = nullptr, const waifu2xProgressFunc progress_func = nullptr);

697
include/tclap/Arg.h Normal file
View File

@ -0,0 +1,697 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: Arg.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_ARGUMENT_H
#define TCLAP_ARGUMENT_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#define HAVE_SSTREAM
#endif
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <iomanip>
#include <cstdio>
#if defined(HAVE_SSTREAM)
#include <sstream>
typedef std::istringstream istringstream;
#elif defined(HAVE_STRSTREAM)
#include <strstream>
typedef std::istrstream istringstream;
#else
#error "Need a stringstream (sstream or strstream) to compile!"
#endif
#include <tclap/ArgException.h>
#include <tclap/Visitor.h>
#include <tclap/CmdLineInterface.h>
#include <tclap/ArgTraits.h>
#include <tclap/StandardTraits.h>
namespace TCLAP {
/**
* A virtual base class that defines the essential data for all arguments.
* This class, or one of its existing children, must be subclassed to do
* anything.
*/
class Arg
{
private:
/**
* Prevent accidental copying.
*/
Arg(const Arg& rhs);
/**
* Prevent accidental copying.
*/
Arg& operator=(const Arg& rhs);
/**
* Indicates whether the rest of the arguments should be ignored.
*/
static bool& ignoreRestRef() { static bool ign = false; return ign; }
/**
* The delimiter that separates an argument flag/name from the
* value.
*/
static char& delimiterRef() { static char delim = ' '; return delim; }
static bool &ignoreMismatchedRef() { static bool ign = false; return ign; }
protected:
/**
* The single char flag used to identify the argument.
* This value (preceded by a dash {-}), can be used to identify
* an argument on the command line. The _flag can be blank,
* in fact this is how unlabeled args work. Unlabeled args must
* override appropriate functions to get correct handling. Note
* that the _flag does NOT include the dash as part of the flag.
*/
std::string _flag;
/**
* A single work namd indentifying the argument.
* This value (preceded by two dashed {--}) can also be used
* to identify an argument on the command line. Note that the
* _name does NOT include the two dashes as part of the _name. The
* _name cannot be blank.
*/
std::string _name;
/**
* Description of the argument.
*/
std::string _description;
/**
* Indicating whether the argument is required.
*/
bool _required;
/**
* Label to be used in usage description. Normally set to
* "required", but can be changed when necessary.
*/
std::string _requireLabel;
/**
* Indicates whether a value is required for the argument.
* Note that the value may be required but the argument/value
* combination may not be, as specified by _required.
*/
bool _valueRequired;
/**
* Indicates whether the argument has been set.
* Indicates that a value on the command line has matched the
* name/flag of this argument and the values have been set accordingly.
*/
bool _alreadySet;
/**
* A pointer to a vistitor object.
* The visitor allows special handling to occur as soon as the
* argument is matched. This defaults to NULL and should not
* be used unless absolutely necessary.
*/
Visitor* _visitor;
/**
* Whether this argument can be ignored, if desired.
*/
bool _ignoreable;
/**
* Indicates that the arg was set as part of an XOR and not on the
* command line.
*/
bool _xorSet;
bool _acceptsMultipleValues;
/**
* Performs the special handling described by the Vistitor.
*/
void _checkWithVisitor() const;
/**
* Primary constructor. YOU (yes you) should NEVER construct an Arg
* directly, this is a base class that is extended by various children
* that are meant to be used. Use SwitchArg, ValueArg, MultiArg,
* UnlabeledValueArg, or UnlabeledMultiArg instead.
*
* \param flag - The flag identifying the argument.
* \param name - The name identifying the argument.
* \param desc - The description of the argument, used in the usage.
* \param req - Whether the argument is required.
* \param valreq - Whether the a value is required for the argument.
* \param v - The visitor checked by the argument. Defaults to NULL.
*/
Arg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
bool valreq,
Visitor* v = NULL );
public:
/**
* Destructor.
*/
virtual ~Arg();
/**
* Adds this to the specified list of Args.
* \param argList - The list to add this to.
*/
virtual void addToList( std::list<Arg*>& argList ) const;
/**
* Begin ignoring arguments since the "--" argument was specified.
*/
static void beginIgnoring() { ignoreRestRef() = true; }
/**
* Whether to ignore the rest.
*/
static bool ignoreRest() { return ignoreRestRef(); }
static void enableIgnoreMismatched() { ignoreMismatchedRef() = true; }
static bool ignoreMismatched() { return ignoreMismatchedRef(); }
/**
* The delimiter that separates an argument flag/name from the
* value.
*/
static char delimiter() { return delimiterRef(); }
/**
* The char used as a place holder when SwitchArgs are combined.
* Currently set to the bell char (ASCII 7).
*/
static char blankChar() { return (char)7; }
/**
* The char that indicates the beginning of a flag. Defaults to '-', but
* clients can define TCLAP_FLAGSTARTCHAR to override.
*/
#ifndef TCLAP_FLAGSTARTCHAR
#define TCLAP_FLAGSTARTCHAR '-'
#endif
static char flagStartChar() { return TCLAP_FLAGSTARTCHAR; }
/**
* The sting that indicates the beginning of a flag. Defaults to "-", but
* clients can define TCLAP_FLAGSTARTSTRING to override. Should be the same
* as TCLAP_FLAGSTARTCHAR.
*/
#ifndef TCLAP_FLAGSTARTSTRING
#define TCLAP_FLAGSTARTSTRING "-"
#endif
static const std::string flagStartString() { return TCLAP_FLAGSTARTSTRING; }
/**
* The sting that indicates the beginning of a name. Defaults to "--", but
* clients can define TCLAP_NAMESTARTSTRING to override.
*/
#ifndef TCLAP_NAMESTARTSTRING
#define TCLAP_NAMESTARTSTRING "--"
#endif
static const std::string nameStartString() { return TCLAP_NAMESTARTSTRING; }
/**
* The name used to identify the ignore rest argument.
*/
static const std::string ignoreNameString() { return "ignore_rest"; }
/**
* Sets the delimiter for all arguments.
* \param c - The character that delimits flags/names from values.
*/
static void setDelimiter( char c ) { delimiterRef() = c; }
/**
* Pure virtual method meant to handle the parsing and value assignment
* of the string on the command line.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. What is
* passed in from main.
*/
virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
/**
* Operator ==.
* Equality operator. Must be virtual to handle unlabeled args.
* \param a - The Arg to be compared to this.
*/
virtual bool operator==(const Arg& a) const;
/**
* Returns the argument flag.
*/
const std::string& getFlag() const;
/**
* Returns the argument name.
*/
const std::string& getName() const;
/**
* Returns the argument description.
*/
std::string getDescription() const;
/**
* Indicates whether the argument is required.
*/
virtual bool isRequired() const;
/**
* Sets _required to true. This is used by the XorHandler.
* You really have no reason to ever use it.
*/
void forceRequired();
/**
* Sets the _alreadySet value to true. This is used by the XorHandler.
* You really have no reason to ever use it.
*/
void xorSet();
/**
* Indicates whether a value must be specified for argument.
*/
bool isValueRequired() const;
/**
* Indicates whether the argument has already been set. Only true
* if the arg has been matched on the command line.
*/
bool isSet() const;
/**
* Indicates whether the argument can be ignored, if desired.
*/
bool isIgnoreable() const;
/**
* A method that tests whether a string matches this argument.
* This is generally called by the processArg() method. This
* method could be re-implemented by a child to change how
* arguments are specified on the command line.
* \param s - The string to be compared to the flag/name to determine
* whether the arg matches.
*/
virtual bool argMatches( const std::string& s ) const;
/**
* Returns a simple string representation of the argument.
* Primarily for debugging.
*/
virtual std::string toString() const;
/**
* Returns a short ID for the usage.
* \param valueId - The value used in the id.
*/
virtual std::string shortID( const std::string& valueId = "val" ) const;
/**
* Returns a long ID for the usage.
* \param valueId - The value used in the id.
*/
virtual std::string longID( const std::string& valueId = "val" ) const;
/**
* Trims a value off of the flag.
* \param flag - The string from which the flag and value will be
* trimmed. Contains the flag once the value has been trimmed.
* \param value - Where the value trimmed from the string will
* be stored.
*/
virtual void trimFlag( std::string& flag, std::string& value ) const;
/**
* Checks whether a given string has blank chars, indicating that
* it is a combined SwitchArg. If so, return true, otherwise return
* false.
* \param s - string to be checked.
*/
bool _hasBlanks( const std::string& s ) const;
/**
* Sets the requireLabel. Used by XorHandler. You shouldn't ever
* use this.
* \param s - Set the requireLabel to this value.
*/
void setRequireLabel( const std::string& s );
/**
* Used for MultiArgs and XorHandler to determine whether args
* can still be set.
*/
virtual bool allowMore();
/**
* Use by output classes to determine whether an Arg accepts
* multiple values.
*/
virtual bool acceptsMultipleValues();
/**
* Clears the Arg object and allows it to be reused by new
* command lines.
*/
virtual void reset();
};
/**
* Typedef of an Arg list iterator.
*/
typedef std::list<Arg*>::iterator ArgListIterator;
/**
* Typedef of an Arg vector iterator.
*/
typedef std::vector<Arg*>::iterator ArgVectorIterator;
/**
* Typedef of a Visitor list iterator.
*/
typedef std::list<Visitor*>::iterator VisitorListIterator;
/*
* Extract a value of type T from it's string representation contained
* in strVal. The ValueLike parameter used to select the correct
* specialization of ExtractValue depending on the value traits of T.
* ValueLike traits use operator>> to assign the value from strVal.
*/
template<typename T> void
ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
{
static_cast<void>(vl); // Avoid warning about unused vl
std::istringstream is(strVal);
int valuesRead = 0;
while ( is.good() ) {
if ( is.peek() != EOF )
#ifdef TCLAP_SETBASE_ZERO
is >> std::setbase(0) >> destVal;
#else
is >> destVal;
#endif
else
break;
valuesRead++;
}
if ( is.fail() )
throw( ArgParseException("Couldn't read argument value "
"from string '" + strVal + "'"));
if ( valuesRead > 1 )
throw( ArgParseException("More than one valid value parsed from "
"string '" + strVal + "'"));
}
/*
* Extract a value of type T from it's string representation contained
* in strVal. The ValueLike parameter used to select the correct
* specialization of ExtractValue depending on the value traits of T.
* StringLike uses assignment (operator=) to assign from strVal.
*/
template<typename T> void
ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
{
static_cast<void>(sl); // Avoid warning about unused sl
SetString(destVal, strVal);
}
//////////////////////////////////////////////////////////////////////
//BEGIN Arg.cpp
//////////////////////////////////////////////////////////////////////
inline Arg::Arg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
bool valreq,
Visitor* v) :
_flag(flag),
_name(name),
_description(desc),
_required(req),
_requireLabel("required"),
_valueRequired(valreq),
_alreadySet(false),
_visitor( v ),
_ignoreable(true),
_xorSet(false),
_acceptsMultipleValues(false)
{
if ( _flag.length() > 1 )
throw(SpecificationException(
"Argument flag can only be one character long", toString() ) );
if ( _name != ignoreNameString() &&
( _flag == Arg::flagStartString() ||
_flag == Arg::nameStartString() ||
_flag == " " ) )
throw(SpecificationException("Argument flag cannot be either '" +
Arg::flagStartString() + "' or '" +
Arg::nameStartString() + "' or a space.",
toString() ) );
if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) ||
( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) ||
( _name.find( " ", 0 ) != std::string::npos ) )
throw(SpecificationException("Argument name begin with either '" +
Arg::flagStartString() + "' or '" +
Arg::nameStartString() + "' or space.",
toString() ) );
}
inline Arg::~Arg() { }
inline std::string Arg::shortID( const std::string& valueId ) const
{
std::string id = "";
if ( _flag != "" )
id = Arg::flagStartString() + _flag;
else
id = Arg::nameStartString() + _name;
if ( _valueRequired )
id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
if ( !_required )
id = "[" + id + "]";
return id;
}
inline std::string Arg::longID( const std::string& valueId ) const
{
std::string id = "";
if ( _flag != "" )
{
id += Arg::flagStartString() + _flag;
if ( _valueRequired )
id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
id += ", ";
}
id += Arg::nameStartString() + _name;
if ( _valueRequired )
id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
return id;
}
inline bool Arg::operator==(const Arg& a) const
{
if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
return true;
else
return false;
}
inline std::string Arg::getDescription() const
{
std::string desc = "";
if ( _required )
desc = "(" + _requireLabel + ") ";
// if ( _valueRequired )
// desc += "(value required) ";
desc += _description;
return desc;
}
inline const std::string& Arg::getFlag() const { return _flag; }
inline const std::string& Arg::getName() const { return _name; }
inline bool Arg::isRequired() const { return _required; }
inline bool Arg::isValueRequired() const { return _valueRequired; }
inline bool Arg::isSet() const
{
if ( _alreadySet && !_xorSet )
return true;
else
return false;
}
inline bool Arg::isIgnoreable() const { return _ignoreable; }
inline void Arg::setRequireLabel( const std::string& s)
{
_requireLabel = s;
}
inline bool Arg::argMatches( const std::string& argFlag ) const
{
if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
argFlag == Arg::nameStartString() + _name )
return true;
else
return false;
}
inline std::string Arg::toString() const
{
std::string s = "";
if ( _flag != "" )
s += Arg::flagStartString() + _flag + " ";
s += "(" + Arg::nameStartString() + _name + ")";
return s;
}
inline void Arg::_checkWithVisitor() const
{
if ( _visitor != NULL )
_visitor->visit();
}
/**
* Implementation of trimFlag.
*/
inline void Arg::trimFlag(std::string& flag, std::string& value) const
{
int stop = 0;
for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
if ( flag[i] == Arg::delimiter() )
{
stop = i;
break;
}
if ( stop > 1 )
{
value = flag.substr(stop+1);
flag = flag.substr(0,stop);
}
}
/**
* Implementation of _hasBlanks.
*/
inline bool Arg::_hasBlanks( const std::string& s ) const
{
for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
if ( s[i] == Arg::blankChar() )
return true;
return false;
}
inline void Arg::forceRequired()
{
_required = true;
}
inline void Arg::xorSet()
{
_alreadySet = true;
_xorSet = true;
}
/**
* Overridden by Args that need to added to the end of the list.
*/
inline void Arg::addToList( std::list<Arg*>& argList ) const
{
argList.push_front( const_cast<Arg*>(this) );
}
inline bool Arg::allowMore()
{
return false;
}
inline bool Arg::acceptsMultipleValues()
{
return _acceptsMultipleValues;
}
inline void Arg::reset()
{
_xorSet = false;
_alreadySet = false;
}
//////////////////////////////////////////////////////////////////////
//END Arg.cpp
//////////////////////////////////////////////////////////////////////
} //namespace TCLAP
#endif

View File

@ -0,0 +1,200 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: ArgException.h
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_ARG_EXCEPTION_H
#define TCLAP_ARG_EXCEPTION_H
#include <string>
#include <exception>
namespace TCLAP {
/**
* A simple class that defines and argument exception. Should be caught
* whenever a CmdLine is created and parsed.
*/
class ArgException : public std::exception
{
public:
/**
* Constructor.
* \param text - The text of the exception.
* \param id - The text identifying the argument source.
* \param td - Text describing the type of ArgException it is.
* of the exception.
*/
ArgException( const std::string& text = "undefined exception",
const std::string& id = "undefined",
const std::string& td = "Generic ArgException")
: std::exception(),
_errorText(text),
_argId( id ),
_typeDescription(td)
{ }
/**
* Destructor.
*/
virtual ~ArgException() throw() { }
/**
* Returns the error text.
*/
std::string error() const { return ( _errorText ); }
/**
* Returns the argument id.
*/
std::string argId() const
{
if ( _argId == "undefined" )
return " ";
else
return ( "Argument: " + _argId );
}
/**
* Returns the arg id and error text.
*/
const char* what() const throw()
{
static std::string ex;
ex = _argId + " -- " + _errorText;
return ex.c_str();
}
/**
* Returns the type of the exception. Used to explain and distinguish
* between different child exceptions.
*/
std::string typeDescription() const
{
return _typeDescription;
}
private:
/**
* The text of the exception message.
*/
std::string _errorText;
/**
* The argument related to this exception.
*/
std::string _argId;
/**
* Describes the type of the exception. Used to distinguish
* between different child exceptions.
*/
std::string _typeDescription;
};
/**
* Thrown from within the child Arg classes when it fails to properly
* parse the argument it has been passed.
*/
class ArgParseException : public ArgException
{
public:
/**
* Constructor.
* \param text - The text of the exception.
* \param id - The text identifying the argument source
* of the exception.
*/
ArgParseException( const std::string& text = "undefined exception",
const std::string& id = "undefined" )
: ArgException( text,
id,
std::string( "Exception found while parsing " ) +
std::string( "the value the Arg has been passed." ))
{ }
};
/**
* Thrown from CmdLine when the arguments on the command line are not
* properly specified, e.g. too many arguments, required argument missing, etc.
*/
class CmdLineParseException : public ArgException
{
public:
/**
* Constructor.
* \param text - The text of the exception.
* \param id - The text identifying the argument source
* of the exception.
*/
CmdLineParseException( const std::string& text = "undefined exception",
const std::string& id = "undefined" )
: ArgException( text,
id,
std::string( "Exception found when the values ") +
std::string( "on the command line do not meet ") +
std::string( "the requirements of the defined ") +
std::string( "Args." ))
{ }
};
/**
* Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
* same flag as another Arg, same name, etc.
*/
class SpecificationException : public ArgException
{
public:
/**
* Constructor.
* \param text - The text of the exception.
* \param id - The text identifying the argument source
* of the exception.
*/
SpecificationException( const std::string& text = "undefined exception",
const std::string& id = "undefined" )
: ArgException( text,
id,
std::string("Exception found when an Arg object ")+
std::string("is improperly defined by the ") +
std::string("developer." ))
{ }
};
class ExitException {
public:
ExitException(int estat) : _estat(estat) {}
int getExitStatus() const { return _estat; }
private:
int _estat;
};
} // namespace TCLAP
#endif

87
include/tclap/ArgTraits.h Normal file
View File

@ -0,0 +1,87 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: ArgTraits.h
*
* Copyright (c) 2007, Daniel Aarno, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
// This is an internal tclap file, you should probably not have to
// include this directly
#ifndef TCLAP_ARGTRAITS_H
#define TCLAP_ARGTRAITS_H
namespace TCLAP {
// We use two empty structs to get compile type specialization
// function to work
/**
* A value like argument value type is a value that can be set using
* operator>>. This is the default value type.
*/
struct ValueLike {
typedef ValueLike ValueCategory;
virtual ~ValueLike() {}
};
/**
* A string like argument value type is a value that can be set using
* operator=(string). Usefull if the value type contains spaces which
* will be broken up into individual tokens by operator>>.
*/
struct StringLike {
virtual ~StringLike() {}
};
/**
* A class can inherit from this object to make it have string like
* traits. This is a compile time thing and does not add any overhead
* to the inherenting class.
*/
struct StringLikeTrait {
typedef StringLike ValueCategory;
virtual ~StringLikeTrait() {}
};
/**
* A class can inherit from this object to make it have value like
* traits. This is a compile time thing and does not add any overhead
* to the inherenting class.
*/
struct ValueLikeTrait {
typedef ValueLike ValueCategory;
virtual ~ValueLikeTrait() {}
};
/**
* Arg traits are used to get compile type specialization when parsing
* argument values. Using an ArgTraits you can specify the way that
* values gets assigned to any particular type during parsing. The two
* supported types are StringLike and ValueLike.
*/
template<typename T>
struct ArgTraits {
typedef typename T::ValueCategory ValueCategory;
virtual ~ArgTraits() {}
//typedef ValueLike ValueCategory;
};
#endif
} // namespace

633
include/tclap/CmdLine.h Normal file
View File

@ -0,0 +1,633 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: CmdLine.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_CMDLINE_H
#define TCLAP_CMDLINE_H
#include <tclap/SwitchArg.h>
#include <tclap/MultiSwitchArg.h>
#include <tclap/UnlabeledValueArg.h>
#include <tclap/UnlabeledMultiArg.h>
#include <tclap/XorHandler.h>
#include <tclap/HelpVisitor.h>
#include <tclap/VersionVisitor.h>
#include <tclap/IgnoreRestVisitor.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/StdOutput.h>
#include <tclap/Constraint.h>
#include <tclap/ValuesConstraint.h>
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <stdlib.h> // Needed for exit(), which isn't defined in some envs.
namespace TCLAP {
template<typename T> void DelPtr(T ptr)
{
delete ptr;
}
template<typename C> void ClearContainer(C &c)
{
typedef typename C::value_type value_type;
std::for_each(c.begin(), c.end(), DelPtr<value_type>);
c.clear();
}
/**
* The base class that manages the command line definition and passes
* along the parsing to the appropriate Arg classes.
*/
class CmdLine : public CmdLineInterface
{
protected:
/**
* The list of arguments that will be tested against the
* command line.
*/
std::list<Arg*> _argList;
/**
* The name of the program. Set to argv[0].
*/
std::string _progName;
/**
* A message used to describe the program. Used in the usage output.
*/
std::string _message;
/**
* The version to be displayed with the --version switch.
*/
std::string _version;
/**
* The number of arguments that are required to be present on
* the command line. This is set dynamically, based on the
* Args added to the CmdLine object.
*/
int _numRequired;
/**
* The character that is used to separate the argument flag/name
* from the value. Defaults to ' ' (space).
*/
char _delimiter;
/**
* The handler that manages xoring lists of args.
*/
XorHandler _xorHandler;
/**
* A list of Args to be explicitly deleted when the destructor
* is called. At the moment, this only includes the three default
* Args.
*/
std::list<Arg*> _argDeleteOnExitList;
/**
* A list of Visitors to be explicitly deleted when the destructor
* is called. At the moment, these are the Vistors created for the
* default Args.
*/
std::list<Visitor*> _visitorDeleteOnExitList;
/**
* Object that handles all output for the CmdLine.
*/
CmdLineOutput* _output;
/**
* Should CmdLine handle parsing exceptions internally?
*/
bool _handleExceptions;
/**
* Throws an exception listing the missing args.
*/
void missingArgsException();
/**
* Checks whether a name/flag string matches entirely matches
* the Arg::blankChar. Used when multiple switches are combined
* into a single argument.
* \param s - The message to be used in the usage.
*/
bool _emptyCombined(const std::string& s);
/**
* Perform a delete ptr; operation on ptr when this object is deleted.
*/
void deleteOnExit(Arg* ptr);
/**
* Perform a delete ptr; operation on ptr when this object is deleted.
*/
void deleteOnExit(Visitor* ptr);
private:
/**
* Prevent accidental copying.
*/
CmdLine(const CmdLine& rhs);
CmdLine& operator=(const CmdLine& rhs);
/**
* Encapsulates the code common to the constructors
* (which is all of it).
*/
void _constructor();
/**
* Is set to true when a user sets the output object. We use this so
* that we don't delete objects that are created outside of this lib.
*/
bool _userSetOutput;
/**
* Whether or not to automatically create help and version switches.
*/
bool _helpAndVersion;
public:
/**
* Command line constructor. Defines how the arguments will be
* parsed.
* \param message - The message to be used in the usage
* output.
* \param delimiter - The character that is used to separate
* the argument flag/name from the value. Defaults to ' ' (space).
* \param version - The version number to be used in the
* --version switch.
* \param helpAndVersion - Whether or not to create the Help and
* Version switches. Defaults to true.
*/
CmdLine(const std::string& message,
const char delimiter = ' ',
const std::string& version = "none",
bool helpAndVersion = true);
/**
* Deletes any resources allocated by a CmdLine object.
*/
virtual ~CmdLine();
/**
* Adds an argument to the list of arguments to be parsed.
* \param a - Argument to be added.
*/
void add( Arg& a );
/**
* An alternative add. Functionally identical.
* \param a - Argument to be added.
*/
void add( Arg* a );
/**
* Add two Args that will be xor'd. If this method is used, add does
* not need to be called.
* \param a - Argument to be added and xor'd.
* \param b - Argument to be added and xor'd.
*/
void xorAdd( Arg& a, Arg& b );
/**
* Add a list of Args that will be xor'd. If this method is used,
* add does not need to be called.
* \param xors - List of Args to be added and xor'd.
*/
void xorAdd( std::vector<Arg*>& xors );
/**
* Parses the command line.
* \param argc - Number of arguments.
* \param argv - Array of arguments.
*/
void parse(int argc, const char * const * argv);
/**
* Parses the command line.
* \param args - A vector of strings representing the args.
* args[0] is still the program name.
*/
void parse(std::vector<std::string>& args);
/**
*
*/
CmdLineOutput* getOutput();
/**
*
*/
void setOutput(CmdLineOutput* co);
/**
*
*/
std::string& getVersion();
/**
*
*/
std::string& getProgramName();
/**
*
*/
std::list<Arg*>& getArgList();
/**
*
*/
XorHandler& getXorHandler();
/**
*
*/
char getDelimiter();
/**
*
*/
std::string& getMessage();
/**
*
*/
bool hasHelpAndVersion();
/**
* Disables or enables CmdLine's internal parsing exception handling.
*
* @param state Should CmdLine handle parsing exceptions internally?
*/
void setExceptionHandling(const bool state);
/**
* Returns the current state of the internal exception handling.
*
* @retval true Parsing exceptions are handled internally.
* @retval false Parsing exceptions are propagated to the caller.
*/
bool getExceptionHandling() const;
/**
* Allows the CmdLine object to be reused.
*/
void reset();
};
///////////////////////////////////////////////////////////////////////////////
//Begin CmdLine.cpp
///////////////////////////////////////////////////////////////////////////////
inline CmdLine::CmdLine(const std::string& m,
char delim,
const std::string& v,
bool help )
:
_argList(std::list<Arg*>()),
_progName("not_set_yet"),
_message(m),
_version(v),
_numRequired(0),
_delimiter(delim),
_xorHandler(XorHandler()),
_argDeleteOnExitList(std::list<Arg*>()),
_visitorDeleteOnExitList(std::list<Visitor*>()),
_output(0),
_handleExceptions(true),
_userSetOutput(false),
_helpAndVersion(help)
{
_constructor();
}
inline CmdLine::~CmdLine()
{
ClearContainer(_argDeleteOnExitList);
ClearContainer(_visitorDeleteOnExitList);
if ( !_userSetOutput ) {
delete _output;
_output = 0;
}
}
inline void CmdLine::_constructor()
{
_output = new StdOutput;
Arg::setDelimiter( _delimiter );
Visitor* v;
if ( _helpAndVersion )
{
v = new HelpVisitor( this, &_output );
SwitchArg* help = new SwitchArg("h","help",
"Displays usage information and exits.",
false, v);
add( help );
deleteOnExit(help);
deleteOnExit(v);
v = new VersionVisitor( this, &_output );
SwitchArg* vers = new SwitchArg("","version",
"Displays version information and exits.",
false, v);
add( vers );
deleteOnExit(vers);
deleteOnExit(v);
}
v = new IgnoreRestVisitor();
SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
Arg::ignoreNameString(),
"Ignores the rest of the labeled arguments following this flag.",
false, v);
add( ignore );
deleteOnExit(ignore);
deleteOnExit(v);
}
inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
{
_xorHandler.add( ors );
for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
{
(*it)->forceRequired();
(*it)->setRequireLabel( "OR required" );
add( *it );
}
}
inline void CmdLine::xorAdd( Arg& a, Arg& b )
{
std::vector<Arg*> ors;
ors.push_back( &a );
ors.push_back( &b );
xorAdd( ors );
}
inline void CmdLine::add( Arg& a )
{
add( &a );
}
inline void CmdLine::add( Arg* a )
{
for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
if ( *a == *(*it) )
throw( SpecificationException(
"Argument with same flag/name already exists!",
a->longID() ) );
a->addToList( _argList );
if ( a->isRequired() )
_numRequired++;
}
inline void CmdLine::parse(int argc, const char * const * argv)
{
// this step is necessary so that we have easy access to
// mutable strings.
std::vector<std::string> args;
for (int i = 0; i < argc; i++)
args.push_back(argv[i]);
parse(args);
}
inline void CmdLine::parse(std::vector<std::string>& args)
{
bool shouldExit = false;
int estat = 0;
try {
_progName = args.front();
args.erase(args.begin());
int requiredCount = 0;
for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
{
bool matched = false;
for (ArgListIterator it = _argList.begin();
it != _argList.end(); it++) {
if ( (*it)->processArg( &i, args ) )
{
requiredCount += _xorHandler.check( *it );
matched = true;
break;
}
}
// checks to see if the argument is an empty combined
// switch and if so, then we've actually matched it
if ( !matched && _emptyCombined( args[i] ) )
matched = true;
if ( !matched && !Arg::ignoreRest() && !Arg::ignoreMismatched() )
throw(CmdLineParseException("Couldn't find match "
"for argument",
args[i]));
}
if ( requiredCount < _numRequired )
missingArgsException();
if ( requiredCount > _numRequired )
throw(CmdLineParseException("Too many arguments!"));
} catch ( ArgException& e ) {
// If we're not handling the exceptions, rethrow.
if ( !_handleExceptions) {
throw;
}
try {
_output->failure(*this,e);
} catch ( ExitException &ee ) {
estat = ee.getExitStatus();
shouldExit = true;
}
} catch (ExitException &ee) {
// If we're not handling the exceptions, rethrow.
if ( !_handleExceptions) {
throw;
}
estat = ee.getExitStatus();
shouldExit = true;
}
if (shouldExit)
exit(estat);
}
inline bool CmdLine::_emptyCombined(const std::string& s)
{
if ( s.length() > 0 && s[0] != Arg::flagStartChar() )
return false;
for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
if ( s[i] != Arg::blankChar() )
return false;
return true;
}
inline void CmdLine::missingArgsException()
{
int count = 0;
std::string missingArgList;
for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
{
if ( (*it)->isRequired() && !(*it)->isSet() )
{
missingArgList += (*it)->getName();
missingArgList += ", ";
count++;
}
}
missingArgList = missingArgList.substr(0,missingArgList.length()-2);
std::string msg;
if ( count > 1 )
msg = "Required arguments missing: ";
else
msg = "Required argument missing: ";
msg += missingArgList;
throw(CmdLineParseException(msg));
}
inline void CmdLine::deleteOnExit(Arg* ptr)
{
_argDeleteOnExitList.push_back(ptr);
}
inline void CmdLine::deleteOnExit(Visitor* ptr)
{
_visitorDeleteOnExitList.push_back(ptr);
}
inline CmdLineOutput* CmdLine::getOutput()
{
return _output;
}
inline void CmdLine::setOutput(CmdLineOutput* co)
{
if ( !_userSetOutput )
delete _output;
_userSetOutput = true;
_output = co;
}
inline std::string& CmdLine::getVersion()
{
return _version;
}
inline std::string& CmdLine::getProgramName()
{
return _progName;
}
inline std::list<Arg*>& CmdLine::getArgList()
{
return _argList;
}
inline XorHandler& CmdLine::getXorHandler()
{
return _xorHandler;
}
inline char CmdLine::getDelimiter()
{
return _delimiter;
}
inline std::string& CmdLine::getMessage()
{
return _message;
}
inline bool CmdLine::hasHelpAndVersion()
{
return _helpAndVersion;
}
inline void CmdLine::setExceptionHandling(const bool state)
{
_handleExceptions = state;
}
inline bool CmdLine::getExceptionHandling() const
{
return _handleExceptions;
}
inline void CmdLine::reset()
{
for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
(*it)->reset();
_progName.clear();
}
///////////////////////////////////////////////////////////////////////////////
//End CmdLine.cpp
///////////////////////////////////////////////////////////////////////////////
} //namespace TCLAP
#endif

View File

@ -0,0 +1,150 @@
/******************************************************************************
*
* file: CmdLineInterface.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_COMMANDLINE_INTERFACE_H
#define TCLAP_COMMANDLINE_INTERFACE_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>
namespace TCLAP {
class Arg;
class CmdLineOutput;
class XorHandler;
/**
* The base class that manages the command line definition and passes
* along the parsing to the appropriate Arg classes.
*/
class CmdLineInterface
{
public:
/**
* Destructor
*/
virtual ~CmdLineInterface() {}
/**
* Adds an argument to the list of arguments to be parsed.
* \param a - Argument to be added.
*/
virtual void add( Arg& a )=0;
/**
* An alternative add. Functionally identical.
* \param a - Argument to be added.
*/
virtual void add( Arg* a )=0;
/**
* Add two Args that will be xor'd.
* If this method is used, add does
* not need to be called.
* \param a - Argument to be added and xor'd.
* \param b - Argument to be added and xor'd.
*/
virtual void xorAdd( Arg& a, Arg& b )=0;
/**
* Add a list of Args that will be xor'd. If this method is used,
* add does not need to be called.
* \param xors - List of Args to be added and xor'd.
*/
virtual void xorAdd( std::vector<Arg*>& xors )=0;
/**
* Parses the command line.
* \param argc - Number of arguments.
* \param argv - Array of arguments.
*/
virtual void parse(int argc, const char * const * argv)=0;
/**
* Parses the command line.
* \param args - A vector of strings representing the args.
* args[0] is still the program name.
*/
void parse(std::vector<std::string>& args);
/**
* Returns the CmdLineOutput object.
*/
virtual CmdLineOutput* getOutput()=0;
/**
* \param co - CmdLineOutput object that we want to use instead.
*/
virtual void setOutput(CmdLineOutput* co)=0;
/**
* Returns the version string.
*/
virtual std::string& getVersion()=0;
/**
* Returns the program name string.
*/
virtual std::string& getProgramName()=0;
/**
* Returns the argList.
*/
virtual std::list<Arg*>& getArgList()=0;
/**
* Returns the XorHandler.
*/
virtual XorHandler& getXorHandler()=0;
/**
* Returns the delimiter string.
*/
virtual char getDelimiter()=0;
/**
* Returns the message string.
*/
virtual std::string& getMessage()=0;
/**
* Indicates whether or not the help and version switches were created
* automatically.
*/
virtual bool hasHelpAndVersion()=0;
/**
* Resets the instance as if it had just been constructed so that the
* instance can be reused.
*/
virtual void reset()=0;
};
} //namespace
#endif

View File

@ -0,0 +1,74 @@
/******************************************************************************
*
* file: CmdLineOutput.h
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_CMDLINEOUTPUT_H
#define TCLAP_CMDLINEOUTPUT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <iomanip>
#include <algorithm>
namespace TCLAP {
class CmdLineInterface;
class ArgException;
/**
* The interface that any output object must implement.
*/
class CmdLineOutput
{
public:
/**
* Virtual destructor.
*/
virtual ~CmdLineOutput() {}
/**
* Generates some sort of output for the USAGE.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c)=0;
/**
* Generates some sort of output for the version.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c)=0;
/**
* Generates some sort of output for a failure.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure( CmdLineInterface& c,
ArgException& e )=0;
};
} //namespace TCLAP
#endif

View File

@ -0,0 +1,68 @@
/******************************************************************************
*
* file: Constraint.h
*
* Copyright (c) 2005, Michael E. Smoot
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_CONSTRAINT_H
#define TCLAP_CONSTRAINT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <iomanip>
#include <algorithm>
namespace TCLAP {
/**
* The interface that defines the interaction between the Arg and Constraint.
*/
template<class T>
class Constraint
{
public:
/**
* Returns a description of the Constraint.
*/
virtual std::string description() const =0;
/**
* Returns the short ID for the Constraint.
*/
virtual std::string shortID() const =0;
/**
* The method used to verify that the value parsed from the command
* line meets the constraint.
* \param value - The value that will be checked.
*/
virtual bool check(const T& value) const =0;
/**
* Destructor.
* Silences warnings about Constraint being a base class with virtual
* functions but without a virtual destructor.
*/
virtual ~Constraint() { ; }
};
} //namespace TCLAP
#endif

View File

@ -0,0 +1,299 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: DocBookOutput.h
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_DOCBOOKOUTPUT_H
#define TCLAP_DOCBOOKOUTPUT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/XorHandler.h>
#include <tclap/Arg.h>
namespace TCLAP {
/**
* A class that generates DocBook output for usage() method for the
* given CmdLine and its Args.
*/
class DocBookOutput : public CmdLineOutput
{
public:
/**
* Prints the usage to stdout. Can be overridden to
* produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c);
/**
* Prints the version to stdout. Can be overridden
* to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c);
/**
* Prints (to stderr) an error message, short usage
* Can be overridden to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure(CmdLineInterface& c,
ArgException& e );
protected:
/**
* Substitutes the char r for string x in string s.
* \param s - The string to operate on.
* \param r - The char to replace.
* \param x - What to replace r with.
*/
void substituteSpecialChars( std::string& s, char r, std::string& x );
void removeChar( std::string& s, char r);
void basename( std::string& s );
void printShortArg(Arg* it);
void printLongArg(Arg* it);
char theDelimiter;
};
inline void DocBookOutput::version(CmdLineInterface& _cmd)
{
std::cout << _cmd.getVersion() << std::endl;
}
inline void DocBookOutput::usage(CmdLineInterface& _cmd )
{
std::list<Arg*> argList = _cmd.getArgList();
std::string progName = _cmd.getProgramName();
std::string xversion = _cmd.getVersion();
theDelimiter = _cmd.getDelimiter();
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
basename(progName);
std::cout << "<?xml version='1.0'?>" << std::endl;
std::cout << "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\"" << std::endl;
std::cout << "\t\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\">" << std::endl << std::endl;
std::cout << "<refentry>" << std::endl;
std::cout << "<refmeta>" << std::endl;
std::cout << "<refentrytitle>" << progName << "</refentrytitle>" << std::endl;
std::cout << "<manvolnum>1</manvolnum>" << std::endl;
std::cout << "</refmeta>" << std::endl;
std::cout << "<refnamediv>" << std::endl;
std::cout << "<refname>" << progName << "</refname>" << std::endl;
std::cout << "<refpurpose>" << _cmd.getMessage() << "</refpurpose>" << std::endl;
std::cout << "</refnamediv>" << std::endl;
std::cout << "<refsynopsisdiv>" << std::endl;
std::cout << "<cmdsynopsis>" << std::endl;
std::cout << "<command>" << progName << "</command>" << std::endl;
// xor
for ( int i = 0; (unsigned int)i < xorList.size(); i++ )
{
std::cout << "<group choice='req'>" << std::endl;
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end(); it++ )
printShortArg((*it));
std::cout << "</group>" << std::endl;
}
// rest of args
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
if ( !xorHandler.contains( (*it) ) )
printShortArg((*it));
std::cout << "</cmdsynopsis>" << std::endl;
std::cout << "</refsynopsisdiv>" << std::endl;
std::cout << "<refsect1>" << std::endl;
std::cout << "<title>Description</title>" << std::endl;
std::cout << "<para>" << std::endl;
std::cout << _cmd.getMessage() << std::endl;
std::cout << "</para>" << std::endl;
std::cout << "</refsect1>" << std::endl;
std::cout << "<refsect1>" << std::endl;
std::cout << "<title>Options</title>" << std::endl;
std::cout << "<variablelist>" << std::endl;
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
printLongArg((*it));
std::cout << "</variablelist>" << std::endl;
std::cout << "</refsect1>" << std::endl;
std::cout << "<refsect1>" << std::endl;
std::cout << "<title>Version</title>" << std::endl;
std::cout << "<para>" << std::endl;
std::cout << xversion << std::endl;
std::cout << "</para>" << std::endl;
std::cout << "</refsect1>" << std::endl;
std::cout << "</refentry>" << std::endl;
}
inline void DocBookOutput::failure( CmdLineInterface& _cmd,
ArgException& e )
{
static_cast<void>(_cmd); // unused
std::cout << e.what() << std::endl;
throw ExitException(1);
}
inline void DocBookOutput::substituteSpecialChars( std::string& s,
char r,
std::string& x )
{
size_t p;
while ( (p = s.find_first_of(r)) != std::string::npos )
{
s.erase(p,1);
s.insert(p,x);
}
}
inline void DocBookOutput::removeChar( std::string& s, char r)
{
size_t p;
while ( (p = s.find_first_of(r)) != std::string::npos )
{
s.erase(p,1);
}
}
inline void DocBookOutput::basename( std::string& s )
{
size_t p = s.find_last_of('/');
if ( p != std::string::npos )
{
s.erase(0, p + 1);
}
}
inline void DocBookOutput::printShortArg(Arg* a)
{
std::string lt = "&lt;";
std::string gt = "&gt;";
std::string id = a->shortID();
substituteSpecialChars(id,'<',lt);
substituteSpecialChars(id,'>',gt);
removeChar(id,'[');
removeChar(id,']');
std::string choice = "opt";
if ( a->isRequired() )
choice = "plain";
std::cout << "<arg choice='" << choice << '\'';
if ( a->acceptsMultipleValues() )
std::cout << " rep='repeat'";
std::cout << '>';
if ( !a->getFlag().empty() )
std::cout << a->flagStartChar() << a->getFlag();
else
std::cout << a->nameStartString() << a->getName();
if ( a->isValueRequired() )
{
std::string arg = a->shortID();
removeChar(arg,'[');
removeChar(arg,']');
removeChar(arg,'<');
removeChar(arg,'>');
arg.erase(0, arg.find_last_of(theDelimiter) + 1);
std::cout << theDelimiter;
std::cout << "<replaceable>" << arg << "</replaceable>";
}
std::cout << "</arg>" << std::endl;
}
inline void DocBookOutput::printLongArg(Arg* a)
{
std::string lt = "&lt;";
std::string gt = "&gt;";
std::string desc = a->getDescription();
substituteSpecialChars(desc,'<',lt);
substituteSpecialChars(desc,'>',gt);
std::cout << "<varlistentry>" << std::endl;
if ( !a->getFlag().empty() )
{
std::cout << "<term>" << std::endl;
std::cout << "<option>";
std::cout << a->flagStartChar() << a->getFlag();
std::cout << "</option>" << std::endl;
std::cout << "</term>" << std::endl;
}
std::cout << "<term>" << std::endl;
std::cout << "<option>";
std::cout << a->nameStartString() << a->getName();
if ( a->isValueRequired() )
{
std::string arg = a->shortID();
removeChar(arg,'[');
removeChar(arg,']');
removeChar(arg,'<');
removeChar(arg,'>');
arg.erase(0, arg.find_last_of(theDelimiter) + 1);
std::cout << theDelimiter;
std::cout << "<replaceable>" << arg << "</replaceable>";
}
std::cout << "</option>" << std::endl;
std::cout << "</term>" << std::endl;
std::cout << "<listitem>" << std::endl;
std::cout << "<para>" << std::endl;
std::cout << desc << std::endl;
std::cout << "</para>" << std::endl;
std::cout << "</listitem>" << std::endl;
std::cout << "</varlistentry>" << std::endl;
}
} //namespace TCLAP
#endif

View File

@ -0,0 +1,76 @@
/******************************************************************************
*
* file: HelpVisitor.h
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_HELP_VISITOR_H
#define TCLAP_HELP_VISITOR_H
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/Visitor.h>
namespace TCLAP {
/**
* A Visitor object that calls the usage method of the given CmdLineOutput
* object for the specified CmdLine object.
*/
class HelpVisitor: public Visitor
{
private:
/**
* Prevent accidental copying.
*/
HelpVisitor(const HelpVisitor& rhs);
HelpVisitor& operator=(const HelpVisitor& rhs);
protected:
/**
* The CmdLine the output will be generated for.
*/
CmdLineInterface* _cmd;
/**
* The output object.
*/
CmdLineOutput** _out;
public:
/**
* Constructor.
* \param cmd - The CmdLine the output will be generated for.
* \param out - The type of output.
*/
HelpVisitor(CmdLineInterface* cmd, CmdLineOutput** out)
: Visitor(), _cmd( cmd ), _out( out ) { }
/**
* Calls the usage method of the CmdLineOutput for the
* specified CmdLine.
*/
void visit() { (*_out)->usage(*_cmd); throw ExitException(0); }
};
}
#endif

View File

@ -0,0 +1,52 @@
/******************************************************************************
*
* file: IgnoreRestVisitor.h
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_IGNORE_REST_VISITOR_H
#define TCLAP_IGNORE_REST_VISITOR_H
#include <tclap/Visitor.h>
#include <tclap/Arg.h>
namespace TCLAP {
/**
* A Vistor that tells the CmdLine to begin ignoring arguments after
* this one is parsed.
*/
class IgnoreRestVisitor: public Visitor
{
public:
/**
* Constructor.
*/
IgnoreRestVisitor() : Visitor() {}
/**
* Sets Arg::_ignoreRest.
*/
void visit() { Arg::beginIgnoring(); }
};
}
#endif

28
include/tclap/Makefile.am Normal file
View File

@ -0,0 +1,28 @@
libtclapincludedir = $(includedir)/tclap
libtclapinclude_HEADERS = \
CmdLineInterface.h \
ArgException.h \
CmdLine.h \
XorHandler.h \
MultiArg.h \
UnlabeledMultiArg.h \
ValueArg.h \
UnlabeledValueArg.h \
Visitor.h Arg.h \
HelpVisitor.h \
SwitchArg.h \
MultiSwitchArg.h \
VersionVisitor.h \
IgnoreRestVisitor.h \
CmdLineOutput.h \
StdOutput.h \
DocBookOutput.h \
ZshCompletionOutput.h \
OptionalUnlabeledTracker.h \
Constraint.h \
ValuesConstraint.h \
ArgTraits.h \
StandardTraits.h

403
include/tclap/Makefile.in Normal file
View File

@ -0,0 +1,403 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = include/tclap
DIST_COMMON = $(libtclapinclude_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/config/ac_cxx_have_long_long.m4 \
$(top_srcdir)/config/ac_cxx_have_sstream.m4 \
$(top_srcdir)/config/ac_cxx_have_strstream.m4 \
$(top_srcdir)/config/ac_cxx_namespaces.m4 \
$(top_srcdir)/config/ac_cxx_warn_effective_cxx.m4 \
$(top_srcdir)/config/bb_enable_doxygen.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libtclapincludedir)"
libtclapincludeHEADERS_INSTALL = $(INSTALL_HEADER)
HEADERS = $(libtclapinclude_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DOT = @DOT@
DOXYGEN = @DOXYGEN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WARN_EFFECTIVE_CXX = @WARN_EFFECTIVE_CXX@
WARN_NO_EFFECTIVE_CXX = @WARN_NO_EFFECTIVE_CXX@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CXX = @ac_ct_CXX@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
libtclapincludedir = $(includedir)/tclap
libtclapinclude_HEADERS = \
CmdLineInterface.h \
ArgException.h \
CmdLine.h \
XorHandler.h \
MultiArg.h \
UnlabeledMultiArg.h \
ValueArg.h \
UnlabeledValueArg.h \
Visitor.h Arg.h \
HelpVisitor.h \
SwitchArg.h \
MultiSwitchArg.h \
VersionVisitor.h \
IgnoreRestVisitor.h \
CmdLineOutput.h \
StdOutput.h \
DocBookOutput.h \
ZshCompletionOutput.h \
OptionalUnlabeledTracker.h \
Constraint.h \
ValuesConstraint.h \
ArgTraits.h \
StandardTraits.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/tclap/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu include/tclap/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libtclapincludeHEADERS: $(libtclapinclude_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(libtclapincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libtclapincludedir)"
@list='$(libtclapinclude_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(libtclapincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libtclapincludedir)/$$f'"; \
$(libtclapincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libtclapincludedir)/$$f"; \
done
uninstall-libtclapincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libtclapinclude_HEADERS)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(libtclapincludedir)/$$f'"; \
rm -f "$(DESTDIR)$(libtclapincludedir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libtclapincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-libtclapincludeHEADERS
install-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libtclapincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
ctags distclean distclean-generic distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-libtclapincludeHEADERS \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
uninstall uninstall-am uninstall-libtclapincludeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

433
include/tclap/MultiArg.h Normal file
View File

@ -0,0 +1,433 @@
/******************************************************************************
*
* file: MultiArg.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_MULTIPLE_ARGUMENT_H
#define TCLAP_MULTIPLE_ARGUMENT_H
#include <string>
#include <vector>
#include <tclap/Arg.h>
#include <tclap/Constraint.h>
namespace TCLAP {
/**
* An argument that allows multiple values of type T to be specified. Very
* similar to a ValueArg, except a vector of values will be returned
* instead of just one.
*/
template<class T>
class MultiArg : public Arg
{
public:
typedef std::vector<T> container_type;
typedef typename container_type::iterator iterator;
typedef typename container_type::const_iterator const_iterator;
protected:
/**
* The list of values parsed from the CmdLine.
*/
std::vector<T> _values;
/**
* The description of type T to be used in the usage.
*/
std::string _typeDesc;
/**
* A list of constraint on this Arg.
*/
Constraint<T>* _constraint;
/**
* Extracts the value from the string.
* Attempts to parse string as type T, if this fails an exception
* is thrown.
* \param val - The string to be read.
*/
void _extractValue( const std::string& val );
/**
* Used by XorHandler to decide whether to keep parsing for this arg.
*/
bool _allowMore;
public:
/**
* Constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
Visitor* v = NULL);
/**
* Constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param parser - A CmdLine parser object to add this Arg to
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
CmdLineInterface& parser,
Visitor* v = NULL );
/**
* Constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
Visitor* v = NULL );
/**
* Constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param parser - A CmdLine parser object to add this Arg to
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v = NULL );
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately. It knows the difference
* between labeled and unlabeled.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns a vector of type T containing the values parsed from
* the command line.
*/
const std::vector<T>& getValue();
/**
* Returns an iterator over the values parsed from the command
* line.
*/
const_iterator begin() const { return _values.begin(); }
/**
* Returns the end of the values parsed from the command
* line.
*/
const_iterator end() const { return _values.end(); }
/**
* Returns the a short id string. Used in the usage.
* \param val - value to be used.
*/
virtual std::string shortID(const std::string& val="val") const;
/**
* Returns the a long id string. Used in the usage.
* \param val - value to be used.
*/
virtual std::string longID(const std::string& val="val") const;
/**
* Once we've matched the first value, then the arg is no longer
* required.
*/
virtual bool isRequired() const;
virtual bool allowMore();
virtual void reset();
private:
/**
* Prevent accidental copying
*/
MultiArg<T>(const MultiArg<T>& rhs);
MultiArg<T>& operator=(const MultiArg<T>& rhs);
};
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
Visitor* v) :
Arg( flag, name, desc, req, true, v ),
_values(std::vector<T>()),
_typeDesc( typeDesc ),
_constraint( NULL ),
_allowMore(false)
{
_acceptsMultipleValues = true;
}
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
CmdLineInterface& parser,
Visitor* v)
: Arg( flag, name, desc, req, true, v ),
_values(std::vector<T>()),
_typeDesc( typeDesc ),
_constraint( NULL ),
_allowMore(false)
{
parser.add( this );
_acceptsMultipleValues = true;
}
/**
*
*/
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
Visitor* v)
: Arg( flag, name, desc, req, true, v ),
_values(std::vector<T>()),
_typeDesc( constraint->shortID() ),
_constraint( constraint ),
_allowMore(false)
{
_acceptsMultipleValues = true;
}
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v)
: Arg( flag, name, desc, req, true, v ),
_values(std::vector<T>()),
_typeDesc( constraint->shortID() ),
_constraint( constraint ),
_allowMore(false)
{
parser.add( this );
_acceptsMultipleValues = true;
}
template<class T>
const std::vector<T>& MultiArg<T>::getValue() { return _values; }
template<class T>
bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
if ( _hasBlanks( args[*i] ) )
return false;
std::string flag = args[*i];
std::string value = "";
trimFlag( flag, value );
if ( argMatches( flag ) )
{
if ( Arg::delimiter() != ' ' && value == "" )
throw( ArgParseException(
"Couldn't find delimiter for this argument!",
toString() ) );
// always take the first one, regardless of start string
if ( value == "" )
{
(*i)++;
if ( static_cast<unsigned int>(*i) < args.size() )
_extractValue( args[*i] );
else
throw( ArgParseException("Missing a value for this argument!",
toString() ) );
}
else
_extractValue( value );
/*
// continuing taking the args until we hit one with a start string
while ( (unsigned int)(*i)+1 < args.size() &&
args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
_extractValue( args[++(*i)] );
*/
_alreadySet = true;
_checkWithVisitor();
return true;
}
else
return false;
}
/**
*
*/
template<class T>
std::string MultiArg<T>::shortID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return Arg::shortID(_typeDesc) + " ... ";
}
/**
*
*/
template<class T>
std::string MultiArg<T>::longID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return Arg::longID(_typeDesc) + " (accepted multiple times)";
}
/**
* Once we've matched the first value, then the arg is no longer
* required.
*/
template<class T>
bool MultiArg<T>::isRequired() const
{
if ( _required )
{
if ( _values.size() > 1 )
return false;
else
return true;
}
else
return false;
}
template<class T>
void MultiArg<T>::_extractValue( const std::string& val )
{
try {
T tmp;
ExtractValue(tmp, val, typename ArgTraits<T>::ValueCategory());
_values.push_back(tmp);
} catch( ArgParseException &e) {
throw ArgParseException(e.error(), toString());
}
if ( _constraint != NULL )
if ( ! _constraint->check( _values.back() ) )
throw( CmdLineParseException( "Value '" + val +
"' does not meet constraint: " +
_constraint->description(),
toString() ) );
}
template<class T>
bool MultiArg<T>::allowMore()
{
bool am = _allowMore;
_allowMore = true;
return am;
}
template<class T>
void MultiArg<T>::reset()
{
Arg::reset();
_values.clear();
}
} // namespace TCLAP
#endif

View File

@ -0,0 +1,216 @@
/******************************************************************************
*
* file: MultiSwitchArg.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* Copyright (c) 2005, Michael E. Smoot, Daniel Aarno, Erik Zeek.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_MULTI_SWITCH_ARG_H
#define TCLAP_MULTI_SWITCH_ARG_H
#include <string>
#include <vector>
#include <tclap/SwitchArg.h>
namespace TCLAP {
/**
* A multiple switch argument. If the switch is set on the command line, then
* the getValue method will return the number of times the switch appears.
*/
class MultiSwitchArg : public SwitchArg
{
protected:
/**
* The value of the switch.
*/
int _value;
/**
* Used to support the reset() method so that ValueArg can be
* reset to their constructed value.
*/
int _default;
public:
/**
* MultiSwitchArg constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param init - Optional. The initial/default value of this Arg.
* Defaults to 0.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiSwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
int init = 0,
Visitor* v = NULL);
/**
* MultiSwitchArg constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param parser - A CmdLine parser object to add this Arg to
* \param init - Optional. The initial/default value of this Arg.
* Defaults to 0.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiSwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
int init = 0,
Visitor* v = NULL);
/**
* Handles the processing of the argument.
* This re-implements the SwitchArg version of this method to set the
* _value of the argument appropriately.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed
* in from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns int, the number of times the switch has been set.
*/
int getValue();
/**
* Returns the shortID for this Arg.
*/
std::string shortID(const std::string& val) const;
/**
* Returns the longID for this Arg.
*/
std::string longID(const std::string& val) const;
void reset();
};
//////////////////////////////////////////////////////////////////////
//BEGIN MultiSwitchArg.cpp
//////////////////////////////////////////////////////////////////////
inline MultiSwitchArg::MultiSwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
int init,
Visitor* v )
: SwitchArg(flag, name, desc, false, v),
_value( init ),
_default( init )
{ }
inline MultiSwitchArg::MultiSwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
int init,
Visitor* v )
: SwitchArg(flag, name, desc, false, v),
_value( init ),
_default( init )
{
parser.add( this );
}
inline int MultiSwitchArg::getValue() { return _value; }
inline bool MultiSwitchArg::processArg(int *i, std::vector<std::string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
if ( argMatches( args[*i] ))
{
// so the isSet() method will work
_alreadySet = true;
// Matched argument: increment value.
++_value;
_checkWithVisitor();
return true;
}
else if ( combinedSwitchesMatch( args[*i] ) )
{
// so the isSet() method will work
_alreadySet = true;
// Matched argument: increment value.
++_value;
// Check for more in argument and increment value.
while ( combinedSwitchesMatch( args[*i] ) )
++_value;
_checkWithVisitor();
return false;
}
else
return false;
}
inline std::string
MultiSwitchArg::shortID(const std::string& val) const
{
return Arg::shortID(val) + " ... ";
}
inline std::string
MultiSwitchArg::longID(const std::string& val) const
{
return Arg::longID(val) + " (accepted multiple times)";
}
inline void
MultiSwitchArg::reset()
{
MultiSwitchArg::_value = MultiSwitchArg::_default;
}
//////////////////////////////////////////////////////////////////////
//END MultiSwitchArg.cpp
//////////////////////////////////////////////////////////////////////
} //namespace TCLAP
#endif

View File

@ -0,0 +1,62 @@
/******************************************************************************
*
* file: OptionalUnlabeledTracker.h
*
* Copyright (c) 2005, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_OPTIONAL_UNLABELED_TRACKER_H
#define TCLAP_OPTIONAL_UNLABELED_TRACKER_H
#include <string>
namespace TCLAP {
class OptionalUnlabeledTracker
{
public:
static void check( bool req, const std::string& argName );
static void gotOptional() { alreadyOptionalRef() = true; }
static bool& alreadyOptional() { return alreadyOptionalRef(); }
private:
static bool& alreadyOptionalRef() { static bool ct = false; return ct; }
};
inline void OptionalUnlabeledTracker::check( bool req, const std::string& argName )
{
if ( OptionalUnlabeledTracker::alreadyOptional() )
throw( SpecificationException(
"You can't specify ANY Unlabeled Arg following an optional Unlabeled Arg",
argName ) );
if ( !req )
OptionalUnlabeledTracker::gotOptional();
}
} // namespace TCLAP
#endif

View File

@ -0,0 +1,208 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: StandardTraits.h
*
* Copyright (c) 2007, Daniel Aarno, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
// This is an internal tclap file, you should probably not have to
// include this directly
#ifndef TCLAP_STANDARD_TRAITS_H
#define TCLAP_STANDARD_TRAITS_H
#ifdef HAVE_CONFIG_H
#include <config.h> // To check for long long
#endif
// If Microsoft has already typedef'd wchar_t as an unsigned
// short, then compiles will break because it's as if we're
// creating ArgTraits twice for unsigned short. Thus...
#ifdef _MSC_VER
#ifndef _NATIVE_WCHAR_T_DEFINED
#define TCLAP_DONT_DECLARE_WCHAR_T_ARGTRAITS
#endif
#endif
namespace TCLAP {
// ======================================================================
// Integer types
// ======================================================================
/**
* longs have value-like semantics.
*/
template<>
struct ArgTraits<long> {
typedef ValueLike ValueCategory;
};
/**
* ints have value-like semantics.
*/
template<>
struct ArgTraits<int> {
typedef ValueLike ValueCategory;
};
/**
* shorts have value-like semantics.
*/
template<>
struct ArgTraits<short> {
typedef ValueLike ValueCategory;
};
/**
* chars have value-like semantics.
*/
template<>
struct ArgTraits<char> {
typedef ValueLike ValueCategory;
};
#ifdef HAVE_LONG_LONG
/**
* long longs have value-like semantics.
*/
template<>
struct ArgTraits<long long> {
typedef ValueLike ValueCategory;
};
#endif
// ======================================================================
// Unsigned integer types
// ======================================================================
/**
* unsigned longs have value-like semantics.
*/
template<>
struct ArgTraits<unsigned long> {
typedef ValueLike ValueCategory;
};
/**
* unsigned ints have value-like semantics.
*/
template<>
struct ArgTraits<unsigned int> {
typedef ValueLike ValueCategory;
};
/**
* unsigned shorts have value-like semantics.
*/
template<>
struct ArgTraits<unsigned short> {
typedef ValueLike ValueCategory;
};
/**
* unsigned chars have value-like semantics.
*/
template<>
struct ArgTraits<unsigned char> {
typedef ValueLike ValueCategory;
};
// Microsoft implements size_t awkwardly.
#if defined(_MSC_VER) && defined(_M_X64)
/**
* size_ts have value-like semantics.
*/
template<>
struct ArgTraits<size_t> {
typedef ValueLike ValueCategory;
};
#endif
#ifdef HAVE_LONG_LONG
/**
* unsigned long longs have value-like semantics.
*/
template<>
struct ArgTraits<unsigned long long> {
typedef ValueLike ValueCategory;
};
#endif
// ======================================================================
// Float types
// ======================================================================
/**
* floats have value-like semantics.
*/
template<>
struct ArgTraits<float> {
typedef ValueLike ValueCategory;
};
/**
* doubles have value-like semantics.
*/
template<>
struct ArgTraits<double> {
typedef ValueLike ValueCategory;
};
// ======================================================================
// Other types
// ======================================================================
/**
* bools have value-like semantics.
*/
template<>
struct ArgTraits<bool> {
typedef ValueLike ValueCategory;
};
/**
* wchar_ts have value-like semantics.
*/
#ifndef TCLAP_DONT_DECLARE_WCHAR_T_ARGTRAITS
template<>
struct ArgTraits<wchar_t> {
typedef ValueLike ValueCategory;
};
#endif
/**
* Strings have string like argument traits.
*/
template<>
struct ArgTraits<std::string> {
typedef StringLike ValueCategory;
};
template<typename T>
void SetString(T &dst, const std::string &src)
{
dst = src;
}
} // namespace
#endif

298
include/tclap/StdOutput.h Normal file
View File

@ -0,0 +1,298 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: StdOutput.h
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_STDCMDLINEOUTPUT_H
#define TCLAP_STDCMDLINEOUTPUT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/XorHandler.h>
#include <tclap/Arg.h>
namespace TCLAP {
/**
* A class that isolates any output from the CmdLine object so that it
* may be easily modified.
*/
class StdOutput : public CmdLineOutput
{
public:
/**
* Prints the usage to stdout. Can be overridden to
* produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c);
/**
* Prints the version to stdout. Can be overridden
* to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c);
/**
* Prints (to stderr) an error message, short usage
* Can be overridden to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure(CmdLineInterface& c,
ArgException& e );
protected:
/**
* Writes a brief usage message with short args.
* \param c - The CmdLine object the output is generated for.
* \param os - The stream to write the message to.
*/
void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
/**
* Writes a longer usage message with long and short args,
* provides descriptions and prints message.
* \param c - The CmdLine object the output is generated for.
* \param os - The stream to write the message to.
*/
void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
/**
* This function inserts line breaks and indents long strings
* according the params input. It will only break lines at spaces,
* commas and pipes.
* \param os - The stream to be printed to.
* \param s - The string to be printed.
* \param maxWidth - The maxWidth allowed for the output line.
* \param indentSpaces - The number of spaces to indent the first line.
* \param secondLineOffset - The number of spaces to indent the second
* and all subsequent lines in addition to indentSpaces.
*/
void spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces,
int secondLineOffset ) const;
};
inline void StdOutput::version(CmdLineInterface& _cmd)
{
std::string progName = _cmd.getProgramName();
std::string xversion = _cmd.getVersion();
std::cout << std::endl << progName << " version: "
<< xversion << std::endl << std::endl;
}
inline void StdOutput::usage(CmdLineInterface& _cmd )
{
std::cout << std::endl << "USAGE: " << std::endl << std::endl;
_shortUsage( _cmd, std::cout );
std::cout << std::endl << std::endl << "Where: " << std::endl << std::endl;
_longUsage( _cmd, std::cout );
std::cout << std::endl;
}
inline void StdOutput::failure( CmdLineInterface& _cmd,
ArgException& e )
{
std::string progName = _cmd.getProgramName();
std::cerr << "PARSE ERROR: " << e.argId() << std::endl
<< " " << e.error() << std::endl << std::endl;
if ( _cmd.hasHelpAndVersion() )
{
std::cerr << "Brief USAGE: " << std::endl;
_shortUsage( _cmd, std::cerr );
std::cerr << std::endl << "For complete USAGE and HELP type: "
<< std::endl << " " << progName << " --help"
<< std::endl << std::endl;
}
else
usage(_cmd);
throw ExitException(1);
}
inline void
StdOutput::_shortUsage( CmdLineInterface& _cmd,
std::ostream& os ) const
{
std::list<Arg*> argList = _cmd.getArgList();
std::string progName = _cmd.getProgramName();
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
std::string s = progName + " ";
// first the xor
for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
{
s += " {";
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end(); it++ )
s += (*it)->shortID() + "|";
s[s.length()-1] = '}';
}
// then the rest
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
if ( !xorHandler.contains( (*it) ) )
s += " " + (*it)->shortID();
// if the program name is too long, then adjust the second line offset
int secondLineOffset = static_cast<int>(progName.length()) + 2;
if ( secondLineOffset > 75/2 )
secondLineOffset = static_cast<int>(75/2);
spacePrint( os, s, 75, 3, secondLineOffset );
}
inline void
StdOutput::_longUsage( CmdLineInterface& _cmd,
std::ostream& os ) const
{
std::list<Arg*> argList = _cmd.getArgList();
std::string message = _cmd.getMessage();
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
// first the xor
for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
{
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end();
it++ )
{
spacePrint( os, (*it)->longID(), 75, 3, 3 );
spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
if ( it+1 != xorList[i].end() )
spacePrint(os, "-- OR --", 75, 9, 0);
}
os << std::endl << std::endl;
}
// then the rest
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
if ( !xorHandler.contains( (*it) ) )
{
spacePrint( os, (*it)->longID(), 75, 3, 3 );
spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
os << std::endl;
}
os << std::endl;
spacePrint( os, message, 75, 3, 0 );
}
inline void StdOutput::spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces,
int secondLineOffset ) const
{
int len = static_cast<int>(s.length());
if ( (len + indentSpaces > maxWidth) && maxWidth > 0 )
{
int allowedLen = maxWidth - indentSpaces;
int start = 0;
while ( start < len )
{
// find the substring length
// int stringLen = std::min<int>( len - start, allowedLen );
// doing it this way to support a VisualC++ 2005 bug
using namespace std;
int stringLen = min<int>( len - start, allowedLen );
// trim the length so it doesn't end in middle of a word
if ( stringLen == allowedLen )
while ( stringLen >= 0 &&
s[stringLen+start] != ' ' &&
s[stringLen+start] != ',' &&
s[stringLen+start] != '|' )
stringLen--;
// ok, the word is longer than the line, so just split
// wherever the line ends
if ( stringLen <= 0 )
stringLen = allowedLen;
// check for newlines
for ( int i = 0; i < stringLen; i++ )
if ( s[start+i] == '\n' )
stringLen = i+1;
// print the indent
for ( int i = 0; i < indentSpaces; i++ )
os << " ";
if ( start == 0 )
{
// handle second line offsets
indentSpaces += secondLineOffset;
// adjust allowed len
allowedLen -= secondLineOffset;
}
os << s.substr(start,stringLen) << std::endl;
// so we don't start a line with a space
while ( s[stringLen+start] == ' ' && start < len )
start++;
start += stringLen;
}
}
else
{
for ( int i = 0; i < indentSpaces; i++ )
os << " ";
os << s << std::endl;
}
}
} //namespace TCLAP
#endif

266
include/tclap/SwitchArg.h Normal file
View File

@ -0,0 +1,266 @@
/******************************************************************************
*
* file: SwitchArg.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_SWITCH_ARG_H
#define TCLAP_SWITCH_ARG_H
#include <string>
#include <vector>
#include <tclap/Arg.h>
namespace TCLAP {
/**
* A simple switch argument. If the switch is set on the command line, then
* the getValue method will return the opposite of the default value for the
* switch.
*/
class SwitchArg : public Arg
{
protected:
/**
* The value of the switch.
*/
bool _value;
/**
* Used to support the reset() method so that ValueArg can be
* reset to their constructed value.
*/
bool _default;
public:
/**
* SwitchArg constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param def - The default value for this Switch.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool def = false,
Visitor* v = NULL);
/**
* SwitchArg constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param parser - A CmdLine parser object to add this Arg to
* \param def - The default value for this Switch.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
bool def = false,
Visitor* v = NULL);
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed
* in from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Checks a string to see if any of the chars in the string
* match the flag for this Switch.
*/
bool combinedSwitchesMatch(std::string& combined);
/**
* Returns bool, whether or not the switch has been set.
*/
bool getValue();
virtual void reset();
private:
/**
* Checks to see if we've found the last match in
* a combined string.
*/
bool lastCombined(std::string& combined);
/**
* Does the common processing of processArg.
*/
void commonProcessing();
};
//////////////////////////////////////////////////////////////////////
//BEGIN SwitchArg.cpp
//////////////////////////////////////////////////////////////////////
inline SwitchArg::SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool default_val,
Visitor* v )
: Arg(flag, name, desc, false, false, v),
_value( default_val ),
_default( default_val )
{ }
inline SwitchArg::SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
bool default_val,
Visitor* v )
: Arg(flag, name, desc, false, false, v),
_value( default_val ),
_default(default_val)
{
parser.add( this );
}
inline bool SwitchArg::getValue() { return _value; }
inline bool SwitchArg::lastCombined(std::string& combinedSwitches )
{
for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
if ( combinedSwitches[i] != Arg::blankChar() )
return false;
return true;
}
inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
{
// make sure this is actually a combined switch
if ( combinedSwitches.length() > 0 &&
combinedSwitches[0] != Arg::flagStartString()[0] )
return false;
// make sure it isn't a long name
if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) ==
Arg::nameStartString() )
return false;
// make sure the delimiter isn't in the string
if ( combinedSwitches.find_first_of( Arg::delimiter() ) != std::string::npos )
return false;
// ok, we're not specifying a ValueArg, so we know that we have
// a combined switch list.
for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
if ( _flag.length() > 0 &&
combinedSwitches[i] == _flag[0] &&
_flag[0] != Arg::flagStartString()[0] )
{
// update the combined switches so this one is no longer present
// this is necessary so that no unlabeled args are matched
// later in the processing.
//combinedSwitches.erase(i,1);
combinedSwitches[i] = Arg::blankChar();
return true;
}
// none of the switches passed in the list match.
return false;
}
inline void SwitchArg::commonProcessing()
{
if ( _xorSet )
throw(CmdLineParseException(
"Mutually exclusive argument already set!", toString()));
if ( _alreadySet )
throw(CmdLineParseException("Argument already set!", toString()));
_alreadySet = true;
if ( _value == true )
_value = false;
else
_value = true;
_checkWithVisitor();
}
inline bool SwitchArg::processArg(int *i, std::vector<std::string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
// if the whole string matches the flag or name string
if ( argMatches( args[*i] ) )
{
commonProcessing();
return true;
}
// if a substring matches the flag as part of a combination
else if ( combinedSwitchesMatch( args[*i] ) )
{
// check again to ensure we don't misinterpret
// this as a MultiSwitchArg
if ( combinedSwitchesMatch( args[*i] ) )
throw(CmdLineParseException("Argument already set!",
toString()));
commonProcessing();
// We only want to return true if we've found the last combined
// match in the string, otherwise we return true so that other
// switches in the combination will have a chance to match.
return lastCombined( args[*i] );
}
else
return false;
}
inline void SwitchArg::reset()
{
Arg::reset();
_value = _default;
}
//////////////////////////////////////////////////////////////////////
//End SwitchArg.cpp
//////////////////////////////////////////////////////////////////////
} //namespace TCLAP
#endif

View File

@ -0,0 +1,301 @@
/******************************************************************************
*
* file: UnlabeledMultiArg.h
*
* Copyright (c) 2003, Michael E. Smoot.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_MULTIPLE_UNLABELED_ARGUMENT_H
#define TCLAP_MULTIPLE_UNLABELED_ARGUMENT_H
#include <string>
#include <vector>
#include <tclap/MultiArg.h>
#include <tclap/OptionalUnlabeledTracker.h>
namespace TCLAP {
/**
* Just like a MultiArg, except that the arguments are unlabeled. Basically,
* this Arg will slurp up everything that hasn't been matched to another
* Arg.
*/
template<class T>
class UnlabeledMultiArg : public MultiArg<T>
{
// If compiler has two stage name lookup (as gcc >= 3.4 does)
// this is requried to prevent undef. symbols
using MultiArg<T>::_ignoreable;
using MultiArg<T>::_hasBlanks;
using MultiArg<T>::_extractValue;
using MultiArg<T>::_typeDesc;
using MultiArg<T>::_name;
using MultiArg<T>::_description;
using MultiArg<T>::_alreadySet;
using MultiArg<T>::toString;
public:
/**
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param ignoreable - Whether or not this argument can be ignored
* using the "--" flag.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
UnlabeledMultiArg( const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
bool ignoreable = false,
Visitor* v = NULL );
/**
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param parser - A CmdLine parser object to add this Arg to
* \param ignoreable - Whether or not this argument can be ignored
* using the "--" flag.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
UnlabeledMultiArg( const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL );
/**
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param ignoreable - Whether or not this argument can be ignored
* using the "--" flag.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
UnlabeledMultiArg( const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
bool ignoreable = false,
Visitor* v = NULL );
/**
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param parser - A CmdLine parser object to add this Arg to
* \param ignoreable - Whether or not this argument can be ignored
* using the "--" flag.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
UnlabeledMultiArg( const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL );
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately. It knows the difference
* between labeled and unlabeled.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns the a short id string. Used in the usage.
* \param val - value to be used.
*/
virtual std::string shortID(const std::string& val="val") const;
/**
* Returns the a long id string. Used in the usage.
* \param val - value to be used.
*/
virtual std::string longID(const std::string& val="val") const;
/**
* Opertor ==.
* \param a - The Arg to be compared to this.
*/
virtual bool operator==(const Arg& a) const;
/**
* Pushes this to back of list rather than front.
* \param argList - The list this should be added to.
*/
virtual void addToList( std::list<Arg*>& argList ) const;
};
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, typeDesc, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
}
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
CmdLineInterface& parser,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, typeDesc, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
parser.add( this );
}
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, constraint, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
}
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
CmdLineInterface& parser,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, constraint, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
parser.add( this );
}
template<class T>
bool UnlabeledMultiArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _hasBlanks( args[*i] ) )
return false;
// never ignore an unlabeled multi arg
// always take the first value, regardless of the start string
_extractValue( args[(*i)] );
/*
// continue taking args until we hit the end or a start string
while ( (unsigned int)(*i)+1 < args.size() &&
args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
_extractValue( args[++(*i)] );
*/
_alreadySet = true;
return true;
}
template<class T>
std::string UnlabeledMultiArg<T>::shortID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return std::string("<") + _typeDesc + "> ...";
}
template<class T>
std::string UnlabeledMultiArg<T>::longID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return std::string("<") + _typeDesc + "> (accepted multiple times)";
}
template<class T>
bool UnlabeledMultiArg<T>::operator==(const Arg& a) const
{
if ( _name == a.getName() || _description == a.getDescription() )
return true;
else
return false;
}
template<class T>
void UnlabeledMultiArg<T>::addToList( std::list<Arg*>& argList ) const
{
argList.push_back( const_cast<Arg*>(static_cast<const Arg* const>(this)) );
}
}
#endif

View File

@ -0,0 +1,340 @@
/******************************************************************************
*
* file: UnlabeledValueArg.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_UNLABELED_VALUE_ARGUMENT_H
#define TCLAP_UNLABELED_VALUE_ARGUMENT_H
#include <string>
#include <vector>
#include <tclap/ValueArg.h>
#include <tclap/OptionalUnlabeledTracker.h>
namespace TCLAP {
/**
* The basic unlabeled argument that parses a value.
* This is a template class, which means the type T defines the type
* that a given object will attempt to parse when an UnlabeledValueArg
* is reached in the list of args that the CmdLine iterates over.
*/
template<class T>
class UnlabeledValueArg : public ValueArg<T>
{
// If compiler has two stage name lookup (as gcc >= 3.4 does)
// this is requried to prevent undef. symbols
using ValueArg<T>::_ignoreable;
using ValueArg<T>::_hasBlanks;
using ValueArg<T>::_extractValue;
using ValueArg<T>::_typeDesc;
using ValueArg<T>::_name;
using ValueArg<T>::_description;
using ValueArg<T>::_alreadySet;
using ValueArg<T>::toString;
public:
/**
* UnlabeledValueArg constructor.
* \param name - A one word name for the argument. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
bool ignoreable = false,
Visitor* v = NULL);
/**
* UnlabeledValueArg constructor.
* \param name - A one word name for the argument. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param parser - A CmdLine parser object to add this Arg to
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL );
/**
* UnlabeledValueArg constructor.
* \param name - A one word name for the argument. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
bool ignoreable = false,
Visitor* v = NULL );
/**
* UnlabeledValueArg constructor.
* \param name - A one word name for the argument. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param parser - A CmdLine parser object to add this Arg to
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL);
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately. Handling specific to
* unlabled arguments.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings.
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Overrides shortID for specific behavior.
*/
virtual std::string shortID(const std::string& val="val") const;
/**
* Overrides longID for specific behavior.
*/
virtual std::string longID(const std::string& val="val") const;
/**
* Overrides operator== for specific behavior.
*/
virtual bool operator==(const Arg& a ) const;
/**
* Instead of pushing to the front of list, push to the back.
* \param argList - The list to add this to.
*/
virtual void addToList( std::list<Arg*>& argList ) const;
};
/**
* Constructor implemenation.
*/
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, typeDesc, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
}
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
CmdLineInterface& parser,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, typeDesc, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
parser.add( this );
}
/**
* Constructor implemenation.
*/
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, constraint, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
}
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
CmdLineInterface& parser,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, constraint, v)
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
parser.add( this );
}
/**
* Implementation of processArg().
*/
template<class T>
bool UnlabeledValueArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _alreadySet )
return false;
if ( _hasBlanks( args[*i] ) )
return false;
// never ignore an unlabeled arg
_extractValue( args[*i] );
_alreadySet = true;
return true;
}
/**
* Overriding shortID for specific output.
*/
template<class T>
std::string UnlabeledValueArg<T>::shortID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return std::string("<") + _typeDesc + ">";
}
/**
* Overriding longID for specific output.
*/
template<class T>
std::string UnlabeledValueArg<T>::longID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
// Ideally we would like to be able to use RTTI to return the name
// of the type required for this argument. However, g++ at least,
// doesn't appear to return terribly useful "names" of the types.
return std::string("<") + _typeDesc + ">";
}
/**
* Overriding operator== for specific behavior.
*/
template<class T>
bool UnlabeledValueArg<T>::operator==(const Arg& a ) const
{
if ( _name == a.getName() || _description == a.getDescription() )
return true;
else
return false;
}
template<class T>
void UnlabeledValueArg<T>::addToList( std::list<Arg*>& argList ) const
{
argList.push_back( const_cast<Arg*>(static_cast<const Arg* const>(this)) );
}
}
#endif

425
include/tclap/ValueArg.h Normal file
View File

@ -0,0 +1,425 @@
/******************************************************************************
*
* file: ValueArg.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VALUE_ARGUMENT_H
#define TCLAP_VALUE_ARGUMENT_H
#include <string>
#include <vector>
#include <tclap/Arg.h>
#include <tclap/Constraint.h>
namespace TCLAP {
/**
* The basic labeled argument that parses a value.
* This is a template class, which means the type T defines the type
* that a given object will attempt to parse when the flag/name is matched
* on the command line. While there is nothing stopping you from creating
* an unflagged ValueArg, it is unwise and would cause significant problems.
* Instead use an UnlabeledValueArg.
*/
template<class T>
class ValueArg : public Arg
{
protected:
/**
* The value parsed from the command line.
* Can be of any type, as long as the >> operator for the type
* is defined.
*/
T _value;
/**
* Used to support the reset() method so that ValueArg can be
* reset to their constructed value.
*/
T _default;
/**
* A human readable description of the type to be parsed.
* This is a hack, plain and simple. Ideally we would use RTTI to
* return the name of type T, but until there is some sort of
* consistent support for human readable names, we are left to our
* own devices.
*/
std::string _typeDesc;
/**
* A Constraint this Arg must conform to.
*/
Constraint<T>* _constraint;
/**
* Extracts the value from the string.
* Attempts to parse string as type T, if this fails an exception
* is thrown.
* \param val - value to be parsed.
*/
void _extractValue( const std::string& val );
public:
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
Visitor* v = NULL);
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param typeDesc - A short, human readable description of the
* type that this object expects. This is used in the generation
* of the USAGE statement. The goal is to be helpful to the end user
* of the program.
* \param parser - A CmdLine parser object to add this Arg to
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
CmdLineInterface& parser,
Visitor* v = NULL );
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param parser - A CmdLine parser object to add this Arg to.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v = NULL );
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
* \param name - A one word name for the argument. Can be
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param req - Whether the argument is required on the command
* line.
* \param value - The default value assigned to this argument if it
* is not present on the command line.
* \param constraint - A pointer to a Constraint object used
* to constrain this Arg.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
Visitor* v = NULL );
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately. It knows the difference
* between labeled and unlabeled.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed
* in from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns the value of the argument.
*/
T& getValue() ;
/**
* Specialization of shortID.
* \param val - value to be used.
*/
virtual std::string shortID(const std::string& val = "val") const;
/**
* Specialization of longID.
* \param val - value to be used.
*/
virtual std::string longID(const std::string& val = "val") const;
virtual void reset() ;
private:
/**
* Prevent accidental copying
*/
ValueArg<T>(const ValueArg<T>& rhs);
ValueArg<T>& operator=(const ValueArg<T>& rhs);
};
/**
* Constructor implementation.
*/
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val ),
_default( val ),
_typeDesc( typeDesc ),
_constraint( NULL )
{ }
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
CmdLineInterface& parser,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val ),
_default( val ),
_typeDesc( typeDesc ),
_constraint( NULL )
{
parser.add( this );
}
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val ),
_default( val ),
_typeDesc( constraint->shortID() ),
_constraint( constraint )
{ }
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v)
: Arg(flag, name, desc, req, true, v),
_value( val ),
_default( val ),
_typeDesc( constraint->shortID() ),
_constraint( constraint )
{
parser.add( this );
}
/**
* Implementation of getValue().
*/
template<class T>
T& ValueArg<T>::getValue() { return _value; }
/**
* Implementation of processArg().
*/
template<class T>
bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
if ( _hasBlanks( args[*i] ) )
return false;
std::string flag = args[*i];
std::string value = "";
trimFlag( flag, value );
if ( argMatches( flag ) )
{
if ( _alreadySet )
{
if ( _xorSet )
throw( CmdLineParseException(
"Mutually exclusive argument already set!",
toString()) );
else
throw( CmdLineParseException("Argument already set!",
toString()) );
}
if ( Arg::delimiter() != ' ' && value == "" )
throw( ArgParseException(
"Couldn't find delimiter for this argument!",
toString() ) );
if ( value == "" )
{
(*i)++;
if ( static_cast<unsigned int>(*i) < args.size() )
_extractValue( args[*i] );
else
throw( ArgParseException("Missing a value for this argument!",
toString() ) );
}
else
_extractValue( value );
_alreadySet = true;
_checkWithVisitor();
return true;
}
else
return false;
}
/**
* Implementation of shortID.
*/
template<class T>
std::string ValueArg<T>::shortID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return Arg::shortID( _typeDesc );
}
/**
* Implementation of longID.
*/
template<class T>
std::string ValueArg<T>::longID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return Arg::longID( _typeDesc );
}
template<class T>
void ValueArg<T>::_extractValue( const std::string& val )
{
try {
ExtractValue(_value, val, typename ArgTraits<T>::ValueCategory());
} catch( ArgParseException &e) {
throw ArgParseException(e.error(), toString());
}
if ( _constraint != NULL )
if ( ! _constraint->check( _value ) )
throw( CmdLineParseException( "Value '" + val +
+ "' does not meet constraint: "
+ _constraint->description(),
toString() ) );
}
template<class T>
void ValueArg<T>::reset()
{
Arg::reset();
_value = _default;
}
} // namespace TCLAP
#endif

View File

@ -0,0 +1,148 @@
/******************************************************************************
*
* file: ValuesConstraint.h
*
* Copyright (c) 2005, Michael E. Smoot
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VALUESCONSTRAINT_H
#define TCLAP_VALUESCONSTRAINT_H
#include <string>
#include <vector>
#include <tclap/Constraint.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#define HAVE_SSTREAM
#endif
#if defined(HAVE_SSTREAM)
#include <sstream>
#elif defined(HAVE_STRSTREAM)
#include <strstream>
#else
#error "Need a stringstream (sstream or strstream) to compile!"
#endif
namespace TCLAP {
/**
* A Constraint that constrains the Arg to only those values specified
* in the constraint.
*/
template<class T>
class ValuesConstraint : public Constraint<T>
{
public:
/**
* Constructor.
* \param allowed - vector of allowed values.
*/
ValuesConstraint(std::vector<T>& allowed);
/**
* Virtual destructor.
*/
virtual ~ValuesConstraint() {}
/**
* Returns a description of the Constraint.
*/
virtual std::string description() const;
/**
* Returns the short ID for the Constraint.
*/
virtual std::string shortID() const;
/**
* The method used to verify that the value parsed from the command
* line meets the constraint.
* \param value - The value that will be checked.
*/
virtual bool check(const T& value) const;
protected:
/**
* The list of valid values.
*/
std::vector<T> _allowed;
/**
* The string used to describe the allowed values of this constraint.
*/
std::string _typeDesc;
};
template<class T>
ValuesConstraint<T>::ValuesConstraint(std::vector<T>& allowed)
: _allowed(allowed),
_typeDesc("")
{
for ( unsigned int i = 0; i < _allowed.size(); i++ )
{
#if defined(HAVE_SSTREAM)
std::ostringstream os;
#elif defined(HAVE_STRSTREAM)
std::ostrstream os;
#else
#error "Need a stringstream (sstream or strstream) to compile!"
#endif
os << _allowed[i];
std::string temp( os.str() );
if ( i > 0 )
_typeDesc += "|";
_typeDesc += temp;
}
}
template<class T>
bool ValuesConstraint<T>::check( const T& val ) const
{
if ( std::find(_allowed.begin(),_allowed.end(),val) == _allowed.end() )
return false;
else
return true;
}
template<class T>
std::string ValuesConstraint<T>::shortID() const
{
return _typeDesc;
}
template<class T>
std::string ValuesConstraint<T>::description() const
{
return _typeDesc;
}
} //namespace TCLAP
#endif

View File

@ -0,0 +1,81 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: VersionVisitor.h
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VERSION_VISITOR_H
#define TCLAP_VERSION_VISITOR_H
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/Visitor.h>
namespace TCLAP {
/**
* A Vistor that will call the version method of the given CmdLineOutput
* for the specified CmdLine object and then exit.
*/
class VersionVisitor: public Visitor
{
private:
/**
* Prevent accidental copying
*/
VersionVisitor(const VersionVisitor& rhs);
VersionVisitor& operator=(const VersionVisitor& rhs);
protected:
/**
* The CmdLine of interest.
*/
CmdLineInterface* _cmd;
/**
* The output object.
*/
CmdLineOutput** _out;
public:
/**
* Constructor.
* \param cmd - The CmdLine the output is generated for.
* \param out - The type of output.
*/
VersionVisitor( CmdLineInterface* cmd, CmdLineOutput** out )
: Visitor(), _cmd( cmd ), _out( out ) { }
/**
* Calls the version method of the output object using the
* specified CmdLine.
*/
void visit() {
(*_out)->version(*_cmd);
throw ExitException(0);
}
};
}
#endif

53
include/tclap/Visitor.h Normal file
View File

@ -0,0 +1,53 @@
/******************************************************************************
*
* file: Visitor.h
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VISITOR_H
#define TCLAP_VISITOR_H
namespace TCLAP {
/**
* A base class that defines the interface for visitors.
*/
class Visitor
{
public:
/**
* Constructor. Does nothing.
*/
Visitor() { }
/**
* Destructor. Does nothing.
*/
virtual ~Visitor() { }
/**
* Does nothing. Should be overridden by child.
*/
virtual void visit() { }
};
}
#endif

166
include/tclap/XorHandler.h Normal file
View File

@ -0,0 +1,166 @@
/******************************************************************************
*
* file: XorHandler.h
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_XORHANDLER_H
#define TCLAP_XORHANDLER_H
#include <tclap/Arg.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
namespace TCLAP {
/**
* This class handles lists of Arg's that are to be XOR'd on the command
* line. This is used by CmdLine and you shouldn't ever use it.
*/
class XorHandler
{
protected:
/**
* The list of of lists of Arg's to be or'd together.
*/
std::vector< std::vector<Arg*> > _orList;
public:
/**
* Constructor. Does nothing.
*/
XorHandler( ) : _orList(std::vector< std::vector<Arg*> >()) {}
/**
* Add a list of Arg*'s that will be orred together.
* \param ors - list of Arg* that will be xor'd.
*/
void add( std::vector<Arg*>& ors );
/**
* Checks whether the specified Arg is in one of the xor lists and
* if it does match one, returns the size of the xor list that the
* Arg matched. If the Arg matches, then it also sets the rest of
* the Arg's in the list. You shouldn't use this.
* \param a - The Arg to be checked.
*/
int check( const Arg* a );
/**
* Returns the XOR specific short usage.
*/
std::string shortUsage();
/**
* Prints the XOR specific long usage.
* \param os - Stream to print to.
*/
void printLongUsage(std::ostream& os);
/**
* Simply checks whether the Arg is contained in one of the arg
* lists.
* \param a - The Arg to be checked.
*/
bool contains( const Arg* a );
std::vector< std::vector<Arg*> >& getXorList();
};
//////////////////////////////////////////////////////////////////////
//BEGIN XOR.cpp
//////////////////////////////////////////////////////////////////////
inline void XorHandler::add( std::vector<Arg*>& ors )
{
_orList.push_back( ors );
}
inline int XorHandler::check( const Arg* a )
{
// iterate over each XOR list
for ( int i = 0; static_cast<unsigned int>(i) < _orList.size(); i++ )
{
// if the XOR list contains the arg..
ArgVectorIterator ait = std::find( _orList[i].begin(),
_orList[i].end(), a );
if ( ait != _orList[i].end() )
{
// first check to see if a mutually exclusive switch
// has not already been set
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a != (*it) && (*it)->isSet() )
throw(CmdLineParseException(
"Mutually exclusive argument already set!",
(*it)->toString()));
// go through and set each arg that is not a
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a != (*it) )
(*it)->xorSet();
// return the number of required args that have now been set
if ( (*ait)->allowMore() )
return 0;
else
return static_cast<int>(_orList[i].size());
}
}
if ( a->isRequired() )
return 1;
else
return 0;
}
inline bool XorHandler::contains( const Arg* a )
{
for ( int i = 0; static_cast<unsigned int>(i) < _orList.size(); i++ )
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a == (*it) )
return true;
return false;
}
inline std::vector< std::vector<Arg*> >& XorHandler::getXorList()
{
return _orList;
}
//////////////////////////////////////////////////////////////////////
//END XOR.cpp
//////////////////////////////////////////////////////////////////////
} //namespace TCLAP
#endif

View File

@ -0,0 +1,323 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
* file: ZshCompletionOutput.h
*
* Copyright (c) 2006, Oliver Kiddle
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_ZSHCOMPLETIONOUTPUT_H
#define TCLAP_ZSHCOMPLETIONOUTPUT_H
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include <map>
#include <tclap/CmdLineInterface.h>
#include <tclap/CmdLineOutput.h>
#include <tclap/XorHandler.h>
#include <tclap/Arg.h>
namespace TCLAP {
/**
* A class that generates a Zsh completion function as output from the usage()
* method for the given CmdLine and its Args.
*/
class ZshCompletionOutput : public CmdLineOutput
{
public:
ZshCompletionOutput();
/**
* Prints the usage to stdout. Can be overridden to
* produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c);
/**
* Prints the version to stdout. Can be overridden
* to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c);
/**
* Prints (to stderr) an error message, short usage
* Can be overridden to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure(CmdLineInterface& c,
ArgException& e );
protected:
void basename( std::string& s );
void quoteSpecialChars( std::string& s );
std::string getMutexList( CmdLineInterface& _cmd, Arg* a );
void printOption( Arg* it, std::string mutex );
void printArg( Arg* it );
std::map<std::string, std::string> common;
char theDelimiter;
};
ZshCompletionOutput::ZshCompletionOutput()
: common(std::map<std::string, std::string>()),
theDelimiter('=')
{
common["host"] = "_hosts";
common["hostname"] = "_hosts";
common["file"] = "_files";
common["filename"] = "_files";
common["user"] = "_users";
common["username"] = "_users";
common["directory"] = "_directories";
common["path"] = "_directories";
common["url"] = "_urls";
}
inline void ZshCompletionOutput::version(CmdLineInterface& _cmd)
{
std::cout << _cmd.getVersion() << std::endl;
}
inline void ZshCompletionOutput::usage(CmdLineInterface& _cmd )
{
std::list<Arg*> argList = _cmd.getArgList();
std::string progName = _cmd.getProgramName();
std::string xversion = _cmd.getVersion();
theDelimiter = _cmd.getDelimiter();
basename(progName);
std::cout << "#compdef " << progName << std::endl << std::endl <<
"# " << progName << " version " << _cmd.getVersion() << std::endl << std::endl <<
"_arguments -s -S";
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
{
if ( (*it)->shortID().at(0) == '<' )
printArg((*it));
else if ( (*it)->getFlag() != "-" )
printOption((*it), getMutexList(_cmd, *it));
}
std::cout << std::endl;
}
inline void ZshCompletionOutput::failure( CmdLineInterface& _cmd,
ArgException& e )
{
static_cast<void>(_cmd); // unused
std::cout << e.what() << std::endl;
}
inline void ZshCompletionOutput::quoteSpecialChars( std::string& s )
{
size_t idx = s.find_last_of(':');
while ( idx != std::string::npos )
{
s.insert(idx, 1, '\\');
idx = s.find_last_of(':', idx);
}
idx = s.find_last_of('\'');
while ( idx != std::string::npos )
{
s.insert(idx, "'\\'");
if (idx == 0)
idx = std::string::npos;
else
idx = s.find_last_of('\'', --idx);
}
}
inline void ZshCompletionOutput::basename( std::string& s )
{
size_t p = s.find_last_of('/');
if ( p != std::string::npos )
{
s.erase(0, p + 1);
}
}
inline void ZshCompletionOutput::printArg(Arg* a)
{
static int count = 1;
std::cout << " \\" << std::endl << " '";
if ( a->acceptsMultipleValues() )
std::cout << '*';
else
std::cout << count++;
std::cout << ':';
if ( !a->isRequired() )
std::cout << ':';
std::cout << a->getName() << ':';
std::map<std::string, std::string>::iterator compArg = common.find(a->getName());
if ( compArg != common.end() )
{
std::cout << compArg->second;
}
else
{
std::cout << "_guard \"^-*\" " << a->getName();
}
std::cout << '\'';
}
inline void ZshCompletionOutput::printOption(Arg* a, std::string mutex)
{
std::string flag = a->flagStartChar() + a->getFlag();
std::string name = a->nameStartString() + a->getName();
std::string desc = a->getDescription();
// remove full stop and capitalisation from description as
// this is the convention for zsh function
if (!desc.compare(0, 12, "(required) "))
{
desc.erase(0, 12);
}
if (!desc.compare(0, 15, "(OR required) "))
{
desc.erase(0, 15);
}
size_t len = desc.length();
if (len && desc.at(--len) == '.')
{
desc.erase(len);
}
if (len)
{
desc.replace(0, 1, 1, tolower(desc.at(0)));
}
std::cout << " \\" << std::endl << " '" << mutex;
if ( a->getFlag().empty() )
{
std::cout << name;
}
else
{
std::cout << "'{" << flag << ',' << name << "}'";
}
if ( theDelimiter == '=' && a->isValueRequired() )
std::cout << "=-";
quoteSpecialChars(desc);
std::cout << '[' << desc << ']';
if ( a->isValueRequired() )
{
std::string arg = a->shortID();
arg.erase(0, arg.find_last_of(theDelimiter) + 1);
if ( arg.at(arg.length()-1) == ']' )
arg.erase(arg.length()-1);
if ( arg.at(arg.length()-1) == ']' )
{
arg.erase(arg.length()-1);
}
if ( arg.at(0) == '<' )
{
arg.erase(arg.length()-1);
arg.erase(0, 1);
}
size_t p = arg.find('|');
if ( p != std::string::npos )
{
do
{
arg.replace(p, 1, 1, ' ');
}
while ( (p = arg.find_first_of('|', p)) != std::string::npos );
quoteSpecialChars(arg);
std::cout << ": :(" << arg << ')';
}
else
{
std::cout << ':' << arg;
std::map<std::string, std::string>::iterator compArg = common.find(arg);
if ( compArg != common.end() )
{
std::cout << ':' << compArg->second;
}
}
}
std::cout << '\'';
}
inline std::string ZshCompletionOutput::getMutexList( CmdLineInterface& _cmd, Arg* a)
{
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
if (a->getName() == "help" || a->getName() == "version")
{
return "(-)";
}
std::ostringstream list;
if ( a->acceptsMultipleValues() )
{
list << '*';
}
for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
{
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end();
it++)
if ( a == (*it) )
{
list << '(';
for ( ArgVectorIterator iu = xorList[i].begin();
iu != xorList[i].end();
iu++ )
{
bool notCur = (*iu) != a;
bool hasFlag = !(*iu)->getFlag().empty();
if ( iu != xorList[i].begin() && (notCur || hasFlag) )
list << ' ';
if (hasFlag)
list << (*iu)->flagStartChar() << (*iu)->getFlag() << ' ';
if ( notCur || hasFlag )
list << (*iu)->nameStartString() << (*iu)->getName();
}
list << ')';
return list.str();
}
}
// wasn't found in xor list
if (!a->getFlag().empty()) {
list << "(" << a->flagStartChar() << a->getFlag() << ' ' <<
a->nameStartString() << a->getName() << ')';
}
return list.str();
}
} //namespace TCLAP
#endif

1
rapidjson Submodule

@ -0,0 +1 @@
Subproject commit c8c8ad47c372dc724cbabcbaf5c62aee4618afeb

View File

@ -0,0 +1,87 @@
#include <windows.h>
#include "CControl.h"
CControl::CControl(const UINT ID)
{
ResourceID = ID;
}
CControl::CControl()
{
}
CControl::~CControl()
{
}
void CControl::RegisterFunc(HWND hWnd)
{
hSub = GetDlgItem(hWnd, ResourceID);
if(hSub == NULL)
return;
SetWindowLongPtr(hSub, GWLP_USERDATA, (LONG_PTR)this);
OrgSubWnd = (WNDPROC)GetWindowLongPtr(hSub, GWLP_WNDPROC);
SetWindowLongPtr(hSub, GWLP_WNDPROC, (LONG_PTR)DispatchSubProc);
}
int CControl::GetResourceID()
{
return ResourceID;
}
void CControl::SetEventCallBack(const CustomEventFunc &func, const LPVOID lpData, const UINT uMsg)
{
mEventMap[uMsg] = stEvent(func, lpData);
}
BOOL CControl::Register(LPCTSTR ClassName, const HINSTANCE hInstance)
{
WNDCLASS winc;
winc.style = CS_HREDRAW | CS_VREDRAW;
winc.cbClsExtra = winc.cbWndExtra = 0;
winc.hInstance = hInstance;
winc.hCursor = LoadCursor(NULL , IDC_ARROW);
winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winc.lpszMenuName = NULL;
winc.lpfnWndProc = DispatchCustomProc;
winc.hIcon = NULL;
winc.lpszClassName = ClassName;
return RegisterClass(&winc);
}
LRESULT CControl::SubProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
auto it = mEventMap.find(uMsg);
if(it != mEventMap.end())
return it->second.pfunc(hWnd, wParam, lParam, OrgSubWnd, it->second.lpData);
else
//自分で処理しないものは元のプロシージャにやってもらう
return CallWindowProc(OrgSubWnd, hWnd, uMsg, wParam, lParam);
}
// ダイアログプロシージャ(形式上)
LRESULT CALLBACK CControl::DispatchSubProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// ダイアログの 32 ビット整数に格納されている
// this ポインタを取りだす
CControl *pcControl = (CControl *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if(pcControl == NULL)
{
// たぶんここが実行されることはない
return NULL;
}
// メンバ関数のダイアログプロシージャを呼び出す
return pcControl->SubProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK CControl::DispatchCustomProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

View File

@ -0,0 +1,79 @@
#pragma once
#include <windows.h>
#include <unordered_map>
#include "GUICommon.h"
// 注意
// イベントハンドラでSetWindowLongでGWL_USERDATAを書き換えた場合おかしくなる
class CControl
{
private:
// コピー、代入の禁止
CControl(const CControl&);
CControl& operator =(const CControl&);
protected:
struct stEvent
{
CustomEventFunc pfunc;
LPVOID lpData;
stEvent() : pfunc(nullptr), lpData(nullptr)
{
}
stEvent(const CustomEventFunc &func, const LPVOID Data) : pfunc(func), lpData(Data)
{
}
stEvent(const stEvent &st)
{
pfunc = st.pfunc;
lpData = st.lpData;
}
};
std::unordered_map<UINT, stEvent> mEventMap;
HWND hSub;
WNDPROC OrgSubWnd;
int ResourceID;
// ダイアログプロシージャ(実質)
virtual LRESULT SubProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
// コンストラクタ(リソースIDを指定)
CControl(const UINT ID);
CControl();
// 仮想デストラクタ(何もしない)
virtual ~CControl();
// 一つのメッセージにつき一つの関数しか登録できない.
// すでにあった場合は上書きされる.
// lpDataは登録した関数に与える好きな引数.
// 登録できる関数は、
// BOOL Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData);
// のような関数.
// 戻り値はTRUEでもFALSEでもよい.
void SetEventCallBack(const CustomEventFunc &func, const LPVOID lpData, const UINT uMsg);
// カスタムコントロールを登録
BOOL Register(LPCTSTR ClassName, const HINSTANCE hInstance);
// ユーザーが使うのはここまで
void RegisterFunc(HWND hWnd);
int GetResourceID();
// ダイアログプロシージャ(形式上)
static LRESULT CALLBACK DispatchSubProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// カスタムコントロールプロシージャ
static LRESULT CALLBACK DispatchCustomProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};

View File

@ -0,0 +1,58 @@
#include "CControl.h"
#include "CDialog.h"
CDialog::CDialog() : mInitFunc(nullptr), mInitData(nullptr)
{
mEventMap[WM_INITDIALOG] = stEvent([this](HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID){ SetControl(hWnd); if(mInitFunc) mInitFunc(hWnd, wParam, lParam, mInitData); }, nullptr);
mEventMap[WM_CLOSE] = stEvent([this](HWND hWnd, WPARAM, LPARAM, LPVOID){ EndDialog(hWnd, 0); }, nullptr);
mEventMap[WM_COMMAND] = stEvent([this](HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID){ CommandCallBack(hWnd, wParam, lParam); }, nullptr);
}
void CDialog::SetEventCallBack(const EventFunc &func, const LPVOID lpData, const UINT uMsg)
{
if(uMsg == WM_INITDIALOG) // 特別に処理を挟まなくてはいけない関係上
{
mInitFunc = func;
mInitData = lpData;
}
else
mEventMap[uMsg] = stEvent(func, lpData);
}
void CDialog::SetCommandCallBack(const EventFunc &func, const LPVOID lpData, const UINT ResourceID)
{
mCommandMap[ResourceID] = stCommand(func, lpData);
}
void CDialog::AddControl(CControl *pfunc)
{
vControl.push_back(pfunc);
}
void CDialog::SetControl(HWND hWnd)
{
for(std::vector<CControl*>::size_type i = 0; i < vControl.size(); i++)
vControl[i]->RegisterFunc(hWnd);
}
INT_PTR CDialog::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
const auto it = mEventMap.find(uMsg);
if(it != mEventMap.end())
{
it->second.pfunc(hWnd, wParam, lParam, it->second.lpData);
return TRUE;
}
return FALSE;
}
void CDialog::CommandCallBack(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
const int ResourceID = LOWORD(wParam);
auto it = mCommandMap.find(ResourceID);
if(it != mCommandMap.end())
it->second.pfunc(hWnd, wParam, lParam, it->second.lpData);
}

View File

@ -0,0 +1,93 @@
#pragma once
#include <windows.h>
#include <vector>
#include <unordered_map>
#include "CDialogBase.h"
#include "GUICommon.h"
class CControl;
// 注意
// イベントハンドラでSetWindowLongでGWL_USERDATAを書き換えた場合おかしくなる
class CDialog: public CDialogBase
{
private:
struct stEvent
{
EventFunc pfunc;
LPVOID lpData;
stEvent() : pfunc(nullptr), lpData(nullptr)
{
}
stEvent(const EventFunc &func, const LPVOID Data) : pfunc(func), lpData(Data)
{
}
stEvent(const stEvent &st)
{
pfunc = st.pfunc;
lpData = st.lpData;
}
};
struct stCommand
{
EventFunc pfunc;
LPVOID lpData;
stCommand() : pfunc(nullptr), lpData(nullptr)
{
}
stCommand(const EventFunc &func, const LPVOID Data) : pfunc(func), lpData(Data)
{
}
stCommand(const stCommand &st)
{
pfunc = st.pfunc;
lpData = st.lpData;
}
};
std::vector<CControl*> vControl;
std::unordered_map<UINT, stEvent> mEventMap;
std::unordered_map<UINT, stCommand> mCommandMap;
EventFunc mInitFunc;
LPVOID mInitData;
// コピー、代入の禁止
CDialog(const CDialog&);
CDialog& operator =(const CDialog&);
// ダイアログプロシージャ
INT_PTR DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void CommandCallBack(HWND hWnd, WPARAM wParam, LPARAM lParam);
void SetControl(HWND hWnd);
public:
// 一つのメッセージにつき一つの関数しか登録できない.
// すでにあった場合は上書きされる.
// WM_COMMANDを登録した場合、SetCommandCallBackは使えなくなる.
// lpDataは登録した関数に与える好きな引数.
// 登録できる関数は、
// BOOL Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData);
// のような関数.
// ダイアログではTRUEを返すこと.
void SetEventCallBack(const EventFunc &func, const LPVOID lpData, const UINT uMsg);
// ボタンが押されたときなどのため
// lpDataは登録した関数に与える好きな引数
void SetCommandCallBack(const EventFunc &func, const LPVOID lpData, const UINT ResourceID);
// ボタンなどのサブクラス化するコントロールを追加する
void AddControl(CControl *pfunc);
// コンストラクタ(何もしない)
CDialog();
};

View File

@ -0,0 +1,41 @@
#include <windows.h>
#include "CDialogBase.h"
// ダイアログを作成する
INT_PTR CDialogBase::DoModal(HINSTANCE hInstance, int iDialogId)
{
return DialogBoxParam(hInstance, MAKEINTRESOURCE(iDialogId), NULL, &DispatchDialogProc, (LPARAM)this);
}
HWND CDialogBase::GetDialogHWND(void)
{
return hDialog;
}
// ダイアログプロシージャ(形式上)
INT_PTR CALLBACK CDialogBase::DispatchDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// ダイアログの 32 ビット整数に格納されている
// this ポインタを取りだす
CDialogBase *pcDialog = (CDialogBase *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if(pcDialog == NULL)
{
if(uMsg == WM_INITDIALOG || uMsg == WM_CREATE)
{
// 直前に DialogBoxParam() が呼ばれてる場合
// this ポインタをダイアログのユーザー領域に入れる
pcDialog = (CDialogBase*)lParam;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pcDialog);
pcDialog->hDialog = hWnd;
return pcDialog->DialogProc(hWnd, uMsg, wParam, lParam);
}
return FALSE;
}
// メンバ関数のダイアログプロシージャを呼び出す
return pcDialog->DialogProc(hWnd, uMsg, wParam, lParam);
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <windows.h>
class CDialogBase
{
private:
// ダイアログプロシージャ(実質)
virtual INT_PTR DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
protected:
HWND hDialog;
public:
virtual ~CDialogBase(){};
// ダイアログを作成する
INT_PTR DoModal(HINSTANCE hInstance, int iDialogId);
HWND GetDialogHWND(void);
// ダイアログプロシージャ(形式上)
static INT_PTR CALLBACK DispatchDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};

View File

@ -0,0 +1,61 @@
#pragma once
#include <windows.h>
#include <vector>
#include <unordered_map>
#include "CWindowBase.h"
#include "GUICommon.h"
// 注意
// イベントハンドラでSetWindowLongでGWL_USERDATAを書き換えた場合おかしくなる
class CWindow: public CWindowBase
{
private:
struct stEvent
{
EventFunc pfunc;
LPVOID lpData;
stEvent() : pfunc(nullptr), lpData(nullptr)
{
}
stEvent(const EventFunc &func, const LPVOID Data) : pfunc(func), lpData(Data)
{
}
stEvent(const stEvent &st)
{
pfunc = st.pfunc;
lpData = st.lpData;
}
};
std::unordered_map<UINT, stEvent> mEvent;
// コピー、代入の禁止
CWindow(const CWindow&);
CWindow& operator =(const CWindow&);
// ダイアログプロシージャ(実質)
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
// 一つのメッセージにつき一つの関数しか登録できない.
// すでにあった場合は上書きされる.
// lpDataは登録した関数に与える好きな引数.
// 登録できる関数は、
// BOOL Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData);
// のような関数.
// 戻り値はTRUEでもFALSEでもよい.
void SetEventCallBack(EventFunc pfunc, LPVOID lpData, UINT uMsg);
// ウィンドウサイズ変更
void SetWindowSize(int nWidth, int nHeight, BOOL Adjust);
// ウィンドウを画面中心へ移動
void MoveWindowCenter();
// コンストラクタ(何もしない)
CWindow();
};

View File

@ -0,0 +1,47 @@
#pragma once
#include <windows.h>
class CWindowBase
{
private:
// ダイアログプロシージャ(実質)
virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
protected:
HWND hWindow;
DWORD dwStyle;
public:
// 仮想デストラクタ(何もしない)
virtual ~CWindowBase();
// ダイアログを作成
// Adjust: 真ならサイズをクライアント領域のものとする
// bSizeBox: 真ならサイズ変更できるようにする
HWND InitWindow(HINSTANCE hInstance, UINT Width, UINT Height,
BOOL Adjust, BOOL bSizeBox, LPCTSTR szClassName, LPCTSTR szWindowTitle);
HWND InitWindow(HINSTANCE hInstance, UINT Width, UINT Height,
BOOL Adjust, LPCTSTR szClassName, LPCTSTR szWindowTitle,
UINT WindowClassStyle = CS_HREDRAW | CS_VREDRAW, DWORD WindowStyle = WS_OVERLAPPEDWINDOW);
// ウィンドウを表示
void ShowWindow(int nCmdShow);
// メインウィンドウのハンドルを取得
HWND GetWindowHandle(void);
// メッセージループ
void MessageLoop();
// 戻り値: 終了 0
// メッセージを処理 1
// メッセージはなかった 2
int PeekLoop();
// ダイアログプロシージャ(形式上)
static LRESULT CALLBACK DispatchWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};

View File

@ -0,0 +1,10 @@
#pragma once
#include <windows.h>
#include <functional>
#define SetClassFunc(FuncObject, ObjectPointer) std::bind(&FuncObject, ObjectPointer, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)
#define SetClassCustomFunc(FuncObject, ObjectPointer) std::bind(&FuncObject, ObjectPointer, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)
typedef std::function<void (HWND, WPARAM, LPARAM, LPVOID)> EventFunc;
typedef std::function<LRESULT (HWND, WPARAM, LPARAM, WNDPROC, LPVOID)> CustomEventFunc;

Binary file not shown.

View File

@ -0,0 +1,601 @@
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <Commctrl.h>
#include <tchar.h>
#include <string>
#include <thread>
#include <atomic>
#include <boost/filesystem.hpp>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include "resource.h"
#include "../common/waifu2x.h"
#include "CDialog.h"
#include "CControl.h"
#define WM_FAILD_CREATE_DIR (WM_APP + 5)
#define WM_END_WAIFU2X (WM_APP + 6)
#define WM_END_THREAD (WM_APP + 7)
const size_t AR_PATH_MAX(1024);
// http://stackoverflow.com/questions/10167382/boostfilesystem-get-relative-path
boost::filesystem::path relativePath(const boost::filesystem::path &path, const boost::filesystem::path &relative_to)
{
// create absolute paths
boost::filesystem::path p = boost::filesystem::absolute(path);
boost::filesystem::path r = boost::filesystem::absolute(relative_to);
// if root paths are different, return absolute path
if (p.root_path() != r.root_path())
return p;
// initialize relative path
boost::filesystem::path result;
// find out where the two paths diverge
boost::filesystem::path::const_iterator itr_path = p.begin();
boost::filesystem::path::const_iterator itr_relative_to = r.begin();
while (*itr_path == *itr_relative_to && itr_path != p.end() && itr_relative_to != r.end()) {
++itr_path;
++itr_relative_to;
}
// add "../" for each remaining token in relative_to
if (itr_relative_to != r.end()) {
++itr_relative_to;
while (itr_relative_to != r.end()) {
result /= "..";
++itr_relative_to;
}
}
// add remaining path
while (itr_path != p.end()) {
result /= *itr_path;
++itr_path;
}
return result;
}
// ダイアログ用
class DialogEvent
{
private:
HWND dh;
std::string input_str;
std::string output_str;
std::string mode;
int noise_level;
double scale_ratio;
std::string process;
std::string outputExt;
std::string inputFileExt;
std::thread processThread;
std::atomic_bool cancelFlag;
std::string autoSetAddName;
bool isLastError;
private:
std::string AddName() const
{
std::string addstr("_" + mode);
if (mode.find("noise") != mode.npos || mode.find("auto_scale") != mode.npos)
addstr += "(Level" + std::to_string(noise_level) + ")";
if (mode.find("scale") != mode.npos)
addstr += "(x" + std::to_string(scale_ratio) + ")";
return addstr;
}
bool SyncMember()
{
bool ret = true;
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_INPUT), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
input_str = buf;
}
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_OUTPUT), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
output_str = buf;
}
if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_NOISE), BM_GETCHECK, 0, 0))
mode = "noise";
else if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_SCALE), BM_GETCHECK, 0, 0))
mode = "scale";
else if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_NOISE_SCALE), BM_GETCHECK, 0, 0))
mode = "noise_scale";
else
mode = "auto_scale";
if (SendMessage(GetDlgItem(dh, IDC_RADIONOISE_LEVEL1), BM_GETCHECK, 0, 0))
noise_level = 1;
else
noise_level = 2;
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_SCALE_RATIO), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
char *ptr = nullptr;
scale_ratio = strtod(buf, &ptr);
if (!ptr || *ptr != '\0')
{
scale_ratio = 2.0;
ret = false;
MessageBox(dh, TEXT("拡大率は数字である必要があります"), TEXT("エラー"), MB_OK | MB_ICONERROR);
}
}
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_OUT_EXT), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
outputExt = buf;
if (outputExt.length() > 0 && outputExt[0] != '.')
outputExt = "." + outputExt;
}
if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_CPU), BM_GETCHECK, 0, 0))
process = "cpu";
else
process = "gpu";
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_INPUT_EXT_LIST), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
inputFileExt = buf;
}
return ret;
}
void ProcessWaifu2x()
{
const boost::filesystem::path input_path(boost::filesystem::absolute(input_str));
std::vector<InputOutputPathPair> file_paths;
if (boost::filesystem::is_directory(input_path)) // input_pathがフォルダならそのディレクトリ以下の画像ファイルを一括変換
{
boost::filesystem::path output_path(output_str);
output_path = boost::filesystem::absolute(output_path);
if (!boost::filesystem::exists(output_path))
{
if (!boost::filesystem::create_directory(output_path))
{
SendMessage(dh, WM_FAILD_CREATE_DIR, (WPARAM)&output_path, 0);
PostMessage(dh, WM_END_THREAD, 0, 0);
// printf("出力フォルダ「%s」の作成に失敗しました\n", output_path.string().c_str());
return;
}
}
std::vector<std::string> extList;
{
// input_extention_listを文字列の配列にする
typedef boost::char_separator<char> char_separator;
typedef boost::tokenizer<char_separator> tokenizer;
char_separator sep(":", "", boost::drop_empty_tokens);
tokenizer tokens(inputFileExt, sep);
for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
extList.push_back("." + *tok_iter);
}
// 変換する画像の入力、出力パスを取得
const auto func = [this, &extList, &input_path, &output_path, &file_paths](const boost::filesystem::path &path)
{
BOOST_FOREACH(const boost::filesystem::path& p, std::make_pair(boost::filesystem::recursive_directory_iterator(path),
boost::filesystem::recursive_directory_iterator()))
{
if (!boost::filesystem::is_directory(p) && std::find(extList.begin(), extList.end(), p.extension().string()) != extList.end())
{
const auto out_relative = relativePath(p, input_path);
const auto out_absolute = output_path / out_relative;
const auto out = (out_absolute.branch_path() / out_absolute.stem()).string() + outputExt;
file_paths.emplace_back(p.string(), out);
}
}
return true;
};
if (!func(input_path))
return;
for (const auto &p : file_paths)
{
const boost::filesystem::path out_path(p.second);
const boost::filesystem::path out_dir(out_path.parent_path());
if (!boost::filesystem::exists(out_dir))
{
if (!boost::filesystem::create_directories(out_dir))
{
SendMessage(dh, WM_FAILD_CREATE_DIR, (WPARAM)&out_dir, 0);
PostMessage(dh, WM_END_THREAD, 0, 0);
//printf("出力フォルダ「%s」の作成に失敗しました\n", out_absolute.string().c_str());
return;
}
}
}
}
else
file_paths.emplace_back(input_str, output_str);
bool isFirst = true;
const auto ProgessFunc = [this, &isFirst](const int ProgressFileMax, const int ProgressFileNow)
{
if (isFirst)
{
isFirst = true;
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETRANGE32, 0, ProgressFileMax);
}
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETPOS, ProgressFileNow, 0);
};
std::vector<PathAndErrorPair> errors;
const eWaifu2xError ret = waifu2x(__argc, __argv, file_paths, mode, noise_level, scale_ratio, "models", process, errors, [this]()
{
return cancelFlag;
}, ProgessFunc);
SendMessage(dh, WM_END_WAIFU2X, (WPARAM)&ret, (LPARAM)&errors);
PostMessage(dh, WM_END_THREAD, 0, 0);
}
void ReplaceAddString()
{
SyncMember();
const boost::filesystem::path output_path(output_str);
std::string stem = output_path.stem().string();
if (stem.length() > 0 && stem.length() >= autoSetAddName.length())
{
const std::string base = stem.substr(0, stem.length() - autoSetAddName.length());
stem.erase(0, base.length());
if (stem == autoSetAddName)
{
const std::string addstr(AddName());
autoSetAddName = addstr;
boost::filesystem::path new_out_path = output_path.branch_path() / (base + addstr + outputExt);
SetWindowTextA(GetDlgItem(dh, IDC_EDIT_OUTPUT), new_out_path.string().c_str());
}
}
}
public:
DialogEvent() : dh(nullptr), mode("noise_scale"), noise_level(1), scale_ratio(2.0), process("gpu"), outputExt("png"), inputFileExt("png:jpg:jpeg:tif:tiff:bmp"), isLastError(false)
{
}
void Exec(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
if (processThread.joinable())
return;
SyncMember();
if (input_str.length() == 0)
{
MessageBox(dh, TEXT("入力パスを指定して下さい"), TEXT("エラー"), MB_OK | MB_ICONERROR);
return;
}
if (output_str.length() == 0)
{
MessageBox(dh, TEXT("出力パスを指定して下さい"), TEXT("エラー"), MB_OK | MB_ICONERROR);
return;
}
if (outputExt.length() == 0)
{
MessageBox(dh, TEXT("出力拡張子を指定して下さい"), TEXT("エラー"), MB_OK | MB_ICONERROR);
return;
}
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETPOS, 0, 0);
cancelFlag = false;
isLastError = false;
processThread = std::thread(std::bind(&DialogEvent::ProcessWaifu2x, this));
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), TRUE);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), FALSE);
}
void WaitThreadExit(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
processThread.join();
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), FALSE);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), TRUE);
if (!isLastError)
MessageBeep(MB_ICONASTERISK);
}
void OnDialogEnd(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
if (!processThread.joinable())
PostQuitMessage(0);
else
MessageBeep(MB_ICONEXCLAMATION);
}
void OnFaildCreateDir(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
const boost::filesystem::path *p = (const boost::filesystem::path *)wParam;
// 出力フォルダ「%s」の作成に失敗しました\n", out_absolute.string().c_str());
std::wstring msg(L"出力フォルダ\r\n");
msg += p->wstring();
msg += L"\r\nの作成に失敗しました";
MessageBox(dh, msg.c_str(), TEXT("エラー"), MB_OK | MB_ICONERROR);
isLastError = true;
}
void OnEndWaifu2x(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
const eWaifu2xError ret = *(const eWaifu2xError *)wParam;
const std::vector<PathAndErrorPair> &errors = *(const std::vector<PathAndErrorPair> *)lParam;
if ((ret != eWaifu2xError_OK) || errors.size() > 0)
{
char msg[1024] = "";
switch (ret)
{
case eWaifu2xError_Cancel:
sprintf(msg, "キャンセルされました");
break;
case eWaifu2xError_InvalidParameter:
sprintf(msg, "パラメータが不正です");
break;
case eWaifu2xError_FailedOpenModelFile:
sprintf(msg, "モデルファイルが開けませんでした");
break;
case eWaifu2xError_FailedParseModelFile:
sprintf(msg, "モデルファイルが壊れています");
break;
case eWaifu2xError_FailedConstructModel:
sprintf(msg, "ネットワークの構築に失敗しました");
break;
}
if (ret == eWaifu2xError_OK)
{
// 全てのエラーを表示することは出来ないので最初の一つだけ表示
const auto &fp = errors[0].first;
bool isBreak = false;
switch (errors[0].second)
{
case eWaifu2xError_InvalidParameter:
sprintf(msg, "パラメータが不正です");
break;
case eWaifu2xError_FailedOpenInputFile:
//sprintf(msg, "入力画像「%s」が開けませんでした", fp.first.c_str());
sprintf(msg, "入力画像が開けませんでした");
break;
case eWaifu2xError_FailedOpenOutputFile:
//sprintf(msg, "出力画像「%s」が書き込めませんでした", fp.second.c_str());
sprintf(msg, "出力画像が書き込めませんでした");
break;
case eWaifu2xError_FailedProcessCaffe:
sprintf(msg, "補間処理に失敗しました");
break;
}
}
MessageBoxA(dh, msg, "エラー", MB_OK | MB_ICONERROR);
isLastError = true;
}
}
void Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
dh = hWnd;
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODE_NOISE_SCALE), BM_SETCHECK, BST_CHECKED, 0);
SendMessage(GetDlgItem(hWnd, IDC_RADIONOISE_LEVEL1), BM_SETCHECK, BST_CHECKED, 0);
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODE_GPU), BM_SETCHECK, BST_CHECKED, 0);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), FALSE);
char text[] = "2.00";
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_SCALE_RATIO), text);
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_OUT_EXT), outputExt.c_str());
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_INPUT_EXT_LIST), inputFileExt.c_str());
}
void Cancel(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
cancelFlag = true;
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), FALSE);
}
void RadioButtom(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
ReplaceAddString();
}
void CheckCUDNN(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
if (can_use_cuDNN())
MessageBox(dh, TEXT("cuDNNが使えます"), TEXT("結果"), MB_OK | MB_ICONINFORMATION);
else
MessageBox(dh, TEXT("cuDNNは使えません"), TEXT("結果"), MB_OK | MB_ICONERROR);
}
// ここで渡されるhWndはIDC_EDITのHWND(コントロールのイベントだから)
LRESULT DropInput(HWND hWnd, WPARAM wParam, LPARAM lParam, WNDPROC OrgSubWnd, LPVOID lpData)
{
char szTmp[AR_PATH_MAX];
// ドロップされたファイル数を取得
UINT FileNum = DragQueryFileA((HDROP)wParam, 0xFFFFFFFF, szTmp, _countof(szTmp));
if (FileNum >= 1)
{
DragQueryFileA((HDROP)wParam, 0, szTmp, _countof(szTmp));
boost::filesystem::path path(szTmp);
if (!SyncMember())
return 0L;
if (boost::filesystem::is_directory(path))
{
HWND ho = GetDlgItem(dh, IDC_EDIT_OUTPUT);
const std::string addstr(AddName());
autoSetAddName = AddName();
auto str = (path.branch_path() / (path.stem().string() + addstr)).string();
SetWindowTextA(ho, str.c_str());
SetWindowTextA(hWnd, szTmp);
}
else
{
HWND ho = GetDlgItem(dh, IDC_EDIT_OUTPUT);
std::string outputFileName = szTmp;
const auto tailDot = outputFileName.find_last_of('.');
outputFileName.erase(tailDot, outputFileName.length());
const std::string addstr(AddName());
autoSetAddName = addstr;
outputFileName += addstr + outputExt;
SetWindowTextA(ho, outputFileName.c_str());
SetWindowTextA(hWnd, szTmp);
}
}
return 0L;
}
// ここで渡されるhWndはIDC_EDITのHWND(コントロールのイベントだから)
LRESULT DropOutput(HWND hWnd, WPARAM wParam, LPARAM lParam, WNDPROC OrgSubWnd, LPVOID lpData)
{
TCHAR szTmp[AR_PATH_MAX];
// ドロップされたファイル数を取得
UINT FileNum = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, szTmp, AR_PATH_MAX);
if (FileNum >= 1)
{
DragQueryFile((HDROP)wParam, 0, szTmp, AR_PATH_MAX);
SetWindowText(hWnd, szTmp);
}
return 0L;
}
LRESULT TextInput(HWND hWnd, WPARAM wParam, LPARAM lParam, WNDPROC OrgSubWnd, LPVOID lpData)
{
const auto ret = CallWindowProc(OrgSubWnd, hWnd, WM_CHAR, wParam, lParam);
ReplaceAddString();
return ret;
}
};
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// CDialogクラスでダイアログを作成する
CDialog cDialog;
CDialog cDialog2;
// IDC_EDITのサブクラス
CControl cControlInput(IDC_EDIT_INPUT);
CControl cControlOutput(IDC_EDIT_OUTPUT);
CControl cControlScale(IDC_EDIT_SCALE_RATIO);
CControl cControlOutExt(IDC_EDIT_OUT_EXT);
// 登録する関数がまとめられたクラス
// グローバル関数を使えばクラスにまとめる必要はないがこの方法が役立つこともあるはず
DialogEvent cDialogEvent;
// クラスの関数を登録する場合
// IDC_EDITにWM_DROPFILESが送られてきたときに実行する関数の登録
cControlInput.SetEventCallBack(SetClassCustomFunc(DialogEvent::DropInput, &cDialogEvent), NULL, WM_DROPFILES);
cControlOutput.SetEventCallBack(SetClassCustomFunc(DialogEvent::DropOutput, &cDialogEvent), NULL, WM_DROPFILES);
cControlScale.SetEventCallBack(SetClassCustomFunc(DialogEvent::TextInput, &cDialogEvent), NULL, WM_CHAR);
cControlOutExt.SetEventCallBack(SetClassCustomFunc(DialogEvent::TextInput, &cDialogEvent), NULL, WM_CHAR);
// コントロールのサブクラスを登録
cDialog.AddControl(&cControlInput);
cDialog.AddControl(&cControlOutput);
cDialog.AddControl(&cControlScale);
cDialog.AddControl(&cControlOutExt);
// 各コントロールのイベントで実行する関数の登録
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::Exec, &cDialogEvent), NULL, IDC_BUTTON_EXEC);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::Cancel, &cDialogEvent), NULL, IDC_BUTTON_CANCEL);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_NOISE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_SCALE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_NOISE_SCALE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_AUTO_SCALE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIONOISE_LEVEL1);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_CPU);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_GPU);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::CheckCUDNN, &cDialogEvent), NULL, IDC_BUTTON_CHECK_CUDNN);
// ダイアログのイベントで実行する関数の登録
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::Create, &cDialogEvent), NULL, WM_INITDIALOG);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnDialogEnd, &cDialogEvent), NULL, WM_CLOSE);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnFaildCreateDir, &cDialogEvent), NULL, WM_FAILD_CREATE_DIR);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnEndWaifu2x, &cDialogEvent), NULL, WM_END_WAIFU2X);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::WaitThreadExit, &cDialogEvent), NULL, WM_END_THREAD);
// ダイアログを表示
cDialog.DoModal(hInstance, IDD_DIALOG);
return 0;
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="waifu2x-caffe.exe"
type="win32"
/>
<description>applcation</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,193 @@
name: "srcnn"
layer {
name: "image_input_layer"
type: "MemoryData"
top: "input"
top: "dummy_label1"
memory_data_param {
batch_size: 1
channels: 1
height: 142
width: 142
}
}
layer {
name: "conv1_layer"
type: "Convolution"
bottom: "input"
top: "conv1"
convolution_param {
num_output: 32
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv1_relu_layer"
type: "ReLU"
bottom: "conv1"
top: "conv1"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv2_layer"
type: "Convolution"
bottom: "conv1"
top: "conv2"
convolution_param {
num_output: 32
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv2_relu_layer"
type: "ReLU"
bottom: "conv2"
top: "conv2"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv3_layer"
type: "Convolution"
bottom: "conv2"
top: "conv3"
convolution_param {
num_output: 64
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv3_relu_layer"
type: "ReLU"
bottom: "conv3"
top: "conv3"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv4_layer"
type: "Convolution"
bottom: "conv3"
top: "conv4"
convolution_param {
num_output: 64
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv4_relu_layer"
type: "ReLU"
bottom: "conv4"
top: "conv4"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv5_layer"
type: "Convolution"
bottom: "conv4"
top: "conv5"
convolution_param {
num_output: 128
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv5_relu_layer"
type: "ReLU"
bottom: "conv5"
top: "conv5"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv6_layer"
type: "Convolution"
bottom: "conv5"
top: "conv6"
convolution_param {
num_output: 128
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv6_relu_layer"
type: "ReLU"
bottom: "conv6"
top: "conv6"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv7_layer"
type: "Convolution"
bottom: "conv6"
top: "conv7"
convolution_param {
num_output: 1
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "target"
type: "MemoryData"
top: "target"
top: "dummy_label2"
memory_data_param {
batch_size: 1
channels: 1
height: 142
width: 142
}
include: { phase: TRAIN }
}
layer {
name: "loss"
type: "EuclideanLoss"
bottom: "conv7"
bottom: "target"
top: "loss"
include: { phase: TRAIN }
}

Binary file not shown.

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{63FB3EFC-63B0-401C-BB54-F3A984DC233F}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>waifu2xcaffegui</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>D:\caffe\include;D:\caffe\3rdparty\include;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.5\include;C:\boost_1_56_0;C:\opencv249\build\include;$(SolutionDir)rapidjson\include;$(SolutionDir)include;$(IncludePath)</IncludePath>
<LibraryPath>D:\caffe\lib;D:\caffe\3rdparty\lib;C:\boost_1_56_0\lib64-msvc-12.0;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>D:\caffe\include;D:\caffe\3rdparty\include;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.5\include;C:\boost_1_56_0;C:\opencv249\build\include;$(SolutionDir)rapidjson\include;$(SolutionDir)include;$(IncludePath)</IncludePath>
<LibraryPath>D:\caffe\lib;D:\caffe\3rdparty\lib;C:\boost_1_56_0\lib64-msvc-12.0;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<DelayLoadDLLs>cudnn64_65.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<Manifest>
<AdditionalManifestFiles>manifest.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<DelayLoadDLLs>cudnn64_65.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<Manifest>
<AdditionalManifestFiles>manifest.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\common\waifu2x.cpp" />
<ClCompile Include="CControl.cpp" />
<ClCompile Include="CDialog.cpp" />
<ClCompile Include="CDialogBase.cpp" />
<ClCompile Include="Source.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\waifu2x.h" />
<ClInclude Include="CControl.h" />
<ClInclude Include="CDialog.h" />
<ClInclude Include="CDialogBase.h" />
<ClInclude Include="CWindow.h" />
<ClInclude Include="CWindowBase.h" />
<ClInclude Include="GUICommon.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="manifest.manifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="ソース ファイル">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="ヘッダー ファイル">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="リソース ファイル">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Source.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
<ClCompile Include="..\common\waifu2x.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
<ClCompile Include="CControl.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
<ClCompile Include="CDialog.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
<ClCompile Include="CDialogBase.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\waifu2x.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="CControl.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="CDialog.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="CDialogBase.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="CWindow.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="CWindowBase.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="GUICommon.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc">
<Filter>リソース ファイル</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="manifest.manifest">
<Filter>リソース ファイル</Filter>
</Manifest>
</ItemGroup>
</Project>

31
waifu2x-caffe.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "waifu2x-caffe", "waifu2x-caffe\waifu2x-caffe.vcxproj", "{7C406EE4-2309-4D4C-98BB-CB7BA865FC41}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "waifu2x-caffe-gui", "waifu2x-caffe-gui\waifu2x-caffe-gui.vcxproj", "{63FB3EFC-63B0-401C-BB54-F3A984DC233F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7C406EE4-2309-4D4C-98BB-CB7BA865FC41}.Debug|x64.ActiveCfg = Debug|x64
{7C406EE4-2309-4D4C-98BB-CB7BA865FC41}.Debug|x64.Build.0 = Debug|x64
{7C406EE4-2309-4D4C-98BB-CB7BA865FC41}.Release|x64.ActiveCfg = Release|x64
{7C406EE4-2309-4D4C-98BB-CB7BA865FC41}.Release|x64.Build.0 = Release|x64
{63FB3EFC-63B0-401C-BB54-F3A984DC233F}.Debug|x64.ActiveCfg = Debug|x64
{63FB3EFC-63B0-401C-BB54-F3A984DC233F}.Debug|x64.Build.0 = Debug|x64
{63FB3EFC-63B0-401C-BB54-F3A984DC233F}.Release|x64.ActiveCfg = Release|x64
{63FB3EFC-63B0-401C-BB54-F3A984DC233F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
VisualSVNWorkingCopyRoot = .
EndGlobalSection
EndGlobal

277
waifu2x-caffe/Source.cpp Normal file
View File

@ -0,0 +1,277 @@
#include <stdio.h>
#include <tclap/CmdLine.h>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <functional>
#include <boost/tokenizer.hpp>
#include "../common/waifu2x.h"
// http://stackoverflow.com/questions/10167382/boostfilesystem-get-relative-path
boost::filesystem::path relativePath(const boost::filesystem::path &path, const boost::filesystem::path &relative_to)
{
// create absolute paths
boost::filesystem::path p = boost::filesystem::absolute(path);
boost::filesystem::path r = boost::filesystem::absolute(relative_to);
// if root paths are different, return absolute path
if (p.root_path() != r.root_path())
return p;
// initialize relative path
boost::filesystem::path result;
// find out where the two paths diverge
boost::filesystem::path::const_iterator itr_path = p.begin();
boost::filesystem::path::const_iterator itr_relative_to = r.begin();
while (*itr_path == *itr_relative_to && itr_path != p.end() && itr_relative_to != r.end()) {
++itr_path;
++itr_relative_to;
}
// add "../" for each remaining token in relative_to
if (itr_relative_to != r.end()) {
++itr_relative_to;
while (itr_relative_to != r.end()) {
result /= "..";
++itr_relative_to;
}
}
// add remaining path
while (itr_path != p.end()) {
result /= *itr_path;
++itr_path;
}
return result;
}
int main(int argc, char** argv)
{
// definition of command line arguments
TCLAP::CmdLine cmd("waifu2x reimplementation using Caffe", ' ', "1.0.0");
TCLAP::ValueArg<std::string> cmdInputFile("i", "input_path",
"path to input image file", true, "",
"string", cmd);
TCLAP::ValueArg<std::string> cmdOutputFile("o", "output_path",
"path to output image file (when input_path is folder, output_path must be folder)", false,
"(auto)", "string", cmd);
TCLAP::ValueArg<std::string> cmdInputFileExt("l", "input_extention_list",
"extention to input image file when input_path is folder", false, "png:jpg:jpeg:tif:tiff:bmp",
"string", cmd);
TCLAP::ValueArg<std::string> cmdOutputFileExt("e", "output_extention",
"extention to output image file when output_path is (auto) or input_path is folder", false,
"png", "string", cmd);
std::vector<std::string> cmdModeConstraintV;
cmdModeConstraintV.push_back("noise");
cmdModeConstraintV.push_back("scale");
cmdModeConstraintV.push_back("noise_scale");
cmdModeConstraintV.push_back("auto_scale");
TCLAP::ValuesConstraint<std::string> cmdModeConstraint(cmdModeConstraintV);
TCLAP::ValueArg<std::string> cmdMode("m", "mode", "image processing mode",
false, "noise_scale", &cmdModeConstraint, cmd);
std::vector<int> cmdNRLConstraintV;
cmdNRLConstraintV.push_back(1);
cmdNRLConstraintV.push_back(2);
TCLAP::ValuesConstraint<int> cmdNRLConstraint(cmdNRLConstraintV);
TCLAP::ValueArg<int> cmdNRLevel("n", "noise_level", "noise reduction level",
false, 1, &cmdNRLConstraint, cmd);
TCLAP::ValueArg<double> cmdScaleRatio("s", "scale_ratio",
"custom scale ratio", false, 2.0, "double", cmd);
TCLAP::ValueArg<std::string> cmdModelPath("", "model_dir",
"path to custom model directory (don't append last / )", false,
"models", "string", cmd);
std::vector<std::string> cmdProcessConstraintV;
cmdProcessConstraintV.push_back("cpu");
cmdProcessConstraintV.push_back("gpu");
cmdProcessConstraintV.push_back("cudnn");
TCLAP::ValuesConstraint<std::string> cmdProcessConstraint(cmdProcessConstraintV);
TCLAP::ValueArg<std::string> cmdProcess("p", "process", "process mode",
false, "gpu", &cmdProcessConstraint, cmd);
// definition of command line argument : end
TCLAP::Arg::enableIgnoreMismatched();
// parse command line arguments
try
{
cmd.parse(argc, argv);
}
catch (std::exception &e)
{
printf("エラー: %s\n", e.what());
return 1;
}
const boost::filesystem::path input_path(boost::filesystem::absolute((cmdInputFile.getValue())));
std::string outputExt = cmdOutputFileExt.getValue();
if (outputExt.length() > 0 && outputExt[0] != '.')
outputExt = "." + outputExt;
std::vector<InputOutputPathPair> file_paths;
if (boost::filesystem::is_directory(input_path)) // input_pathがフォルダならそのディレクトリ以下の画像ファイルを一括変換
{
boost::filesystem::path output_path;
if (cmdOutputFile.getValue() == "(auto)")
{
// 「test」なら「test_noise_scale(Level1)(x2.000000)」みたいな感じにする
std::string addstr("_" + cmdMode.getValue());
const std::string &mode = cmdMode.getValue();
if (mode.find("noise") != mode.npos || mode.find("auto_scale") != mode.npos)
addstr += "(Level" + std::to_string(cmdNRLevel.getValue()) + ")";
if (mode.find("scale") != mode.npos)
addstr += "(x" + std::to_string(cmdScaleRatio.getValue()) + ")";
output_path = input_path.branch_path() / (input_path.stem().string() + addstr);
}
else
output_path = cmdOutputFile.getValue();
output_path = boost::filesystem::absolute(output_path);
if (!boost::filesystem::exists(output_path))
{
if (!boost::filesystem::create_directory(output_path))
{
printf("エラー: 出力フォルダ「%s」の作成に失敗しました\n", output_path.string().c_str());
return 1;
}
}
std::vector<std::string> extList;
{
// input_extention_listを文字列の配列にする
typedef boost::char_separator<char> char_separator;
typedef boost::tokenizer<char_separator> tokenizer;
char_separator sep(":", "", boost::drop_empty_tokens);
tokenizer tokens(cmdInputFileExt.getValue(), sep);
for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
extList.push_back("." + *tok_iter);
}
// 変換する画像の入力、出力パスを取得
const auto func = [&extList, &input_path, &output_path, &outputExt, &file_paths](const boost::filesystem::path &path)
{
BOOST_FOREACH(const boost::filesystem::path& p, std::make_pair(boost::filesystem::recursive_directory_iterator(path),
boost::filesystem::recursive_directory_iterator()))
{
if (boost::filesystem::is_directory(p))
{
const auto out_relative = relativePath(p, input_path);
const auto out_absolute = output_path / out_relative;
if (!boost::filesystem::exists(out_absolute))
{
if (!boost::filesystem::create_directory(out_absolute))
{
printf("エラー: 出力フォルダ「%s」の作成に失敗しました\n", out_absolute.string().c_str());
return false;
}
}
}
else if (std::find(extList.begin(), extList.end(), p.extension().string()) != extList.end())
{
const auto out_relative = relativePath(p, input_path);
const auto out_absolute = output_path / out_relative;
const auto out = (out_absolute.branch_path() / out_absolute.stem()).string() + outputExt;
file_paths.emplace_back(p.string(), out);
}
}
return true;
};
if (!func(input_path))
return 1;
}
else
{
std::string outputFileName = cmdOutputFile.getValue();
if (outputFileName == "(auto)")
{
// 「miku_small.png」なら「miku_small(noise_scale)(Level1)(x2.000000).png」みたいな感じにする
outputFileName = cmdInputFile.getValue();
const auto tailDot = outputFileName.find_last_of('.');
outputFileName.erase(tailDot, outputFileName.length());
outputFileName = outputFileName + "(" + cmdMode.getValue() + ")";
std::string &mode = cmdMode.getValue();
if (mode.find("noise") != mode.npos || mode.find("auto_scale") != mode.npos)
outputFileName = outputFileName + "(Level" + std::to_string(cmdNRLevel.getValue()) + ")";
if (mode.find("scale") != mode.npos)
outputFileName = outputFileName + "(x" + std::to_string(cmdScaleRatio.getValue()) + ")";
outputFileName += outputExt;
}
file_paths.emplace_back(cmdInputFile.getValue(), outputFileName);
}
std::vector<PathAndErrorPair> errors;
const eWaifu2xError ret = waifu2x(argc, argv, file_paths, cmdMode.getValue(), cmdNRLevel.getValue(), cmdScaleRatio.getValue(), cmdModelPath.getValue(), cmdProcess.getValue(), errors);
if (ret != eWaifu2xError_OK || errors.size() > 0)
{
switch (ret)
{
case eWaifu2xError_InvalidParameter:
printf("エラー: パラメータが不正です\n");
break;
case eWaifu2xError_FailedOpenModelFile:
printf("エラー: モデルファイルが開けませんでした\n");
break;
case eWaifu2xError_FailedParseModelFile:
printf("エラー: モデルファイルが壊れています\n");
break;
case eWaifu2xError_FailedConstructModel:
printf("エラー: ネットワークの構築に失敗しました\n");
break;
}
for (const auto &ep : errors)
{
const auto &fp = ep.first;
switch (ep.second)
{
case eWaifu2xError_InvalidParameter:
printf("エラー: パラメータが不正です\n");
break;
case eWaifu2xError_FailedOpenInputFile:
printf("エラー: 入力画像「%s」が開けませんでした\n", fp.first.c_str());
break;
case eWaifu2xError_FailedOpenOutputFile:
printf("エラー: 出力画像「%s」が書き込めませんでした\n", fp.second.c_str());
break;
case eWaifu2xError_FailedProcessCaffe:
printf("エラー: 補間処理に失敗しました\n");
break;
}
}
printf("変換に失敗しました\n");
return 1;
}
return 0;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,193 @@
name: "srcnn"
layer {
name: "image_input_layer"
type: "MemoryData"
top: "input"
top: "dummy_label1"
memory_data_param {
batch_size: 1
channels: 1
height: 142
width: 142
}
}
layer {
name: "conv1_layer"
type: "Convolution"
bottom: "input"
top: "conv1"
convolution_param {
num_output: 32
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv1_relu_layer"
type: "ReLU"
bottom: "conv1"
top: "conv1"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv2_layer"
type: "Convolution"
bottom: "conv1"
top: "conv2"
convolution_param {
num_output: 32
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv2_relu_layer"
type: "ReLU"
bottom: "conv2"
top: "conv2"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv3_layer"
type: "Convolution"
bottom: "conv2"
top: "conv3"
convolution_param {
num_output: 64
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv3_relu_layer"
type: "ReLU"
bottom: "conv3"
top: "conv3"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv4_layer"
type: "Convolution"
bottom: "conv3"
top: "conv4"
convolution_param {
num_output: 64
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv4_relu_layer"
type: "ReLU"
bottom: "conv4"
top: "conv4"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv5_layer"
type: "Convolution"
bottom: "conv4"
top: "conv5"
convolution_param {
num_output: 128
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv5_relu_layer"
type: "ReLU"
bottom: "conv5"
top: "conv5"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv6_layer"
type: "Convolution"
bottom: "conv5"
top: "conv6"
convolution_param {
num_output: 128
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "conv6_relu_layer"
type: "ReLU"
bottom: "conv6"
top: "conv6"
relu_param {
negative_slope: 0.1
}
}
layer {
name: "conv7_layer"
type: "Convolution"
bottom: "conv6"
top: "conv7"
convolution_param {
num_output: 1
kernel_size: 3
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
}
}
layer {
name: "target"
type: "MemoryData"
top: "target"
top: "dummy_label2"
memory_data_param {
batch_size: 1
channels: 1
height: 142
width: 142
}
include: { phase: TRAIN }
}
layer {
name: "loss"
type: "EuclideanLoss"
bottom: "conv7"
bottom: "target"
top: "loss"
include: { phase: TRAIN }
}

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7C406EE4-2309-4D4C-98BB-CB7BA865FC41}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>waifu2x-caffe</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>D:\caffe\include;D:\caffe\3rdparty\include;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.5\include;C:\boost_1_56_0;C:\opencv249\build\include;$(SolutionDir)rapidjson\include;$(SolutionDir)include;$(IncludePath)</IncludePath>
<LibraryPath>D:\caffe\lib;D:\caffe\3rdparty\lib;C:\boost_1_56_0\lib64-msvc-12.0;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>D:\caffe\include;D:\caffe\3rdparty\include;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.5\include;C:\boost_1_56_0;C:\opencv249\build\include;$(SolutionDir)rapidjson\include;$(SolutionDir)include;$(IncludePath)</IncludePath>
<LibraryPath>D:\caffe\lib;D:\caffe\3rdparty\lib;C:\boost_1_56_0\lib64-msvc-12.0;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<DelayLoadDLLs>cudnn64_65.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<DelayLoadDLLs>cudnn64_65.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\common\waifu2x.cpp" />
<ClCompile Include="Source.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\waifu2x.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="ソース ファイル">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="ヘッダー ファイル">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="リソース ファイル">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Source.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
<ClCompile Include="..\common\waifu2x.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\waifu2x.h">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
</ItemGroup>
</Project>