/* * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved. * * This file is part of ZLToolKit(https://github.com/xia-chu/ZLToolKit). * * Use of this source code is governed by MIT license that can be found in the * LICENSE file in the root of the source tree. All contributing project authors * may be found in the AUTHORS file in the root of the source tree. */ #ifndef SRC_UTIL_CMD_H_ #define SRC_UTIL_CMD_H_ #include #include #include #include #include #include #include #include #include "Util/mini.h" #include "Util/onceToken.h" using namespace std; namespace toolkit{ class Option { public: typedef function &stream, const string &arg)> OptionHandler; enum ArgType { ArgNone = 0,//no_argument, ArgRequired = 1,//required_argument, ArgOptional = 2,//optional_argument }; Option(){} Option(char shortOpt, const char *longOpt, enum ArgType argType, const char *defaultValue, bool mustExist,//该参数是否必须存在 const char *des, const OptionHandler &cb) { _shortOpt = shortOpt; _longOpt = longOpt; _argType = argType; if(argType != ArgNone){ if(defaultValue){ _defaultValue = std::make_shared(defaultValue); } if(!_defaultValue && mustExist){ _mustExist = true; } } _des = des; _cb = cb; } ~Option() {} bool operator()(const std::shared_ptr &stream, const string &arg){ return _cb ? _cb(stream,arg): true; } private: friend class OptionParser; char _shortOpt; string _longOpt; std::shared_ptr _defaultValue; enum ArgType _argType; string _des; OptionHandler _cb; bool _mustExist = false; }; class OptionParser { public: typedef function< void(const std::shared_ptr &,mINI &)> OptionCompleted; OptionParser(const OptionCompleted &cb = nullptr,bool enableEmptyArgs = true) { _onCompleted = cb; _enableEmptyArgs = enableEmptyArgs; _helper = Option('h', "help", Option::ArgNone, nullptr, false, "打印此信息", [this](const std::shared_ptr &stream,const string &arg)->bool { static const char *argsType[] = {"无参","有参","选参"}; static const char *mustExist[] = {"选填","必填"}; static string defaultPrefix = "默认:"; static string defaultNull = "null"; stringstream printer; size_t maxLen_longOpt = 0; auto maxLen_default = defaultNull.size(); for (auto &pr : _map_options) { auto &opt = pr.second; if(opt._longOpt.size() > maxLen_longOpt){ maxLen_longOpt = opt._longOpt.size(); } if(opt._defaultValue){ if(opt._defaultValue->size() > maxLen_default){ maxLen_default = opt._defaultValue->size(); } } } for (auto &pr : _map_options) { auto &opt = pr.second; //打印短参和长参名 if(opt._shortOpt){ printer <<" -" << opt._shortOpt <<" --" << opt._longOpt; }else{ printer <<" " << " " <<" --" << opt._longOpt; } for (size_t i = 0; i < maxLen_longOpt - opt._longOpt.size(); ++i) { printer << " "; } //打印是否有参 printer << " " << argsType[opt._argType]; //打印默认参数 string defaultValue = defaultNull; if(opt._defaultValue){ defaultValue = *opt._defaultValue; } printer << " " << defaultPrefix << defaultValue; for (size_t i = 0; i < maxLen_default - defaultValue.size(); ++i) { printer << " "; } //打印是否必填参数 printer << " " << mustExist[opt._mustExist]; //打印描述 printer << " " << opt._des << endl; } throw std::invalid_argument(printer.str()); }); (*this) << _helper; } ~OptionParser() { } OptionParser &operator <<(Option &&option) { int index = 0xFF + (int)_map_options.size(); if(option._shortOpt){ _map_charIndex.emplace(option._shortOpt,index); } _map_options.emplace(index, std::forward