#include "argsparser.h" using namespace args_parse; using namespace std; __ArgvPackImpls::__ArgvPackImpls(const QString& means, ParamType t) : means_store(means), type_store(t) { } // 通过 IArgvPack 继承 ParamType __ArgvPackImpls::paramType() const { return type_store; } QString __ArgvPackImpls::means() const { return means_store; } void __ArgvPackImpls::setValue(const QString& v) { this->value_store = v; } QString __ArgvPackImpls::value() const { return value_store; } FloatKeyValue::FloatKeyValue(const QString& key, const QString& means, bool optional) : __FloatArgvImpl(key, means, optional) { } QString __FloatArgvImpl::bindKey() const { return key_name; } bool __FloatArgvImpl::optional() const { return optional_value; } QString args_parse::FloatKeyValue::placeHolder() const { if(optional()) return QString("[--%1 <%2>]").arg(bindKey(), bindKey()); return QString("--%1 <%2>").arg(bindKey(), bindKey()); } int FloatKeyValue::matchLenth() const { return 2; } bool FloatKeyValue::parse(const QList args, int start) { auto args_t = args[start]; auto args_v = args[start + 1]; if (args_t == bindKey()) setValue(args_v); return args_t == bindKey(); } IndexParam::IndexParam(const QString& place_v, const QString& means) : __ArgvPackImpls(means, ParamType::IndexParam), _place_holder(place_v) { } QString args_parse::IndexParam::placeHolder() const { return QString("<%1>").arg(_place_holder); } int IndexParam::matchLenth() const { return 1; } bool IndexParam::parse(const QList args, int start) { setValue(args[start]); return true; } __FloatArgvImpl::__FloatArgvImpl(const QString& key, const QString& means, bool optional) : __ArgvPackImpls(means, ParamType::FloatParam), key_name(key), optional_value(optional) { } FloatOption::FloatOption(const QString& key, const QString& means, bool opt) : __FloatArgvImpl(key, means, opt) { setValue(u8"0"); } QString args_parse::FloatOption::placeHolder() const { if(optional()) return QString("[--%1]").arg(bindKey()); return QString("--%1").arg(bindKey()); } int FloatOption::matchLenth() const { return 1; } bool FloatOption::parse(const QList args, int start) { auto args_t = args[start]; setValue(QString::number(args_t == bindKey())); return args_t == bindKey(); } namespace args_parse { class MatchMode { private: QList> args_mode; int code_store; public: explicit MatchMode(const QList> mode, int mode_code) :args_mode(mode), code_store(mode_code) { } /** * @brief 获取模式代码 * @return 模式代码 */ int modeCode()const { return code_store; } /** * @brief 获取模式匹配结果 * @return 模式匹配结果 */ QList> result() const { return args_mode; } /** * @brief 解析匹配参数 */ bool parse(const QList& args, int argv_index, int parse_index) { if (argv_index >= args.size()) return true; // 获取模式匹配单元 auto parse_unit = args_mode[parse_index]; switch (parse_unit->paramType()) { case ParamType::IndexParam:// 固定位置索引匹配 { parse_unit->parse(args, argv_index); // 继续匹配下一个为止 return parse(args, argv_index + parse_unit->matchLenth(), parse_index + 1); }break; case ParamType::FloatParam:// 浮动参数匹配 { QList> float_parsers; for (auto& unit : args_mode) { if (unit->paramType() == ParamType::FloatParam) float_parsers << dynamic_pointer_cast<__FloatArgvImpl>(unit); } for (auto& unit : float_parsers) { if (unit->matchLenth() + argv_index > args.size()) continue; auto result = unit->parse(args, argv_index); if (result) if (parse(args, argv_index + unit->matchLenth(), parse_index + 1)) return true; else if (!result && unit->optional()) if (parse(args, argv_index, parse_index + 1)) return true; } }break; } return false; } }; } void ArgsParser::loadMode(int mode_code, const QList>& args_model) { this->match_modes.append(make_shared(args_model, mode_code)); } tuple>> ArgsParser::parse(int argc, char* argv[]) { // 聚合参数数组 QList args_list; for (int idx = 0; idx < argc; idx++) { auto argv_str = QString::fromLocal8Bit(argv[idx]); args_list.append(argv_str); } // 枚举模式匹配 for (auto& minst : this->match_modes) { if (minst->parse(args_list, 0, 0)) return tuple>>(minst->modeCode(), minst->result()); } return tuple>>(0, QList>()); }