#include "argsparser.h" using namespace args_parse; ArgvPackImpl::ArgvPackImpl(const QString& means, ParamType t) : means_store(means), type_store(t) {} // ͨ¹ý ArgvPack ¼Ì³Ð ParamType ArgvPackImpl::paramType() const { return type_store; } QString ArgvPackImpl::means() const { return means_store; } void ArgvPackImpl::setValue(const QString& v) { this->value_store = v; } QString ArgvPackImpl::value() const { return value_store; } FloatArgvPack::FloatArgvPack(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; } int FloatArgvPack::matchLenth() const { return 2; } bool FloatArgvPack::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& means) : ArgvPackImpl(means, ParamType::IndexParam) {} int args_parse::IndexParam::matchLenth() const { return 1; } bool args_parse::IndexParam::parse(const QList args, int start) { setValue(args[start]); return true; } FloatArgvImpl::FloatArgvImpl(const QString& key, const QString& means, bool optional) : ArgvPackImpl(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"); } 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) {} int modeCode()const {return code_store;} QList> result() const {return args_mode;} bool parse(const QList& args, int argv_start, int parse_index) { if(argv_start >= args.size()) return true; auto parse_unit = args_mode[parse_index]; switch (parse_unit->paramType()) { case ParamType::IndexParam: { parse_unit->parse(args, argv_start); return parse(args, argv_start + 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.append(std::dynamic_pointer_cast(unit)); } for (auto& unit : float_parsers) { if(unit->matchLenth() + argv_start > args.size()) continue; auto result = unit->parse(args, argv_start); if (result) if (parse(args, argv_start + unit->matchLenth(), parse_index + 1)) return true; else if (!result && unit->optional()) if (parse(args, argv_start, parse_index + 1)) return true; } }break; } return false; } }; } void args_parse::ArgsParser::loadMode(int mode_code, const QList>& args_model) { this->match_modes.append(std::make_shared(args_model, mode_code)); } std::tuple>> args_parse::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 std::tuple>>(minst->modeCode(), minst->result()); } return std::tuple>>(0, QList>()); }