This commit is contained in:
codeboss 2024-10-03 21:45:30 +08:00
parent 90b2323eb0
commit 48af8723ef
4 changed files with 88 additions and 60 deletions

View File

@ -34,7 +34,7 @@ bool __FloatArgvImpls::optional() const {
return optional_value; return optional_value;
} }
QString args_parse::FloatKeyValue::placeHolder(bool v) const { QString FloatKeyValue::placeHolder(bool v) const {
if (optional() && v) if (optional() && v)
return QString("[--%1 <%2>]").arg(bindKey(), bindKey()); return QString("[--%1 <%2>]").arg(bindKey(), bindKey());
return QString("--%1 <%2>").arg(bindKey(), bindKey()); return QString("--%1 <%2>").arg(bindKey(), bindKey());
@ -44,10 +44,13 @@ int FloatKeyValue::matchLenth() const {
return 2; return 2;
} }
bool FloatKeyValue::parse(const QList<QString> args, int start) { bool FloatKeyValue::parse(const QList<QString> args) {
auto args_t = args[start]; if (args.size() < 2)
auto args_v = args[start + 1]; return false;
auto args_t = args[0];
if (args_t == u8"--" + bindKey()) { if (args_t == u8"--" + bindKey()) {
auto args_v = args[1];
setValue(args_v); setValue(args_v);
return true; return true;
} }
@ -57,7 +60,7 @@ bool FloatKeyValue::parse(const QList<QString> args, int start) {
IndexParam::IndexParam(const QString& place_v, const QString& means) IndexParam::IndexParam(const QString& place_v, const QString& means)
: __ArgvPackImpls(means, ParamType::IndexParam), _place_holder(place_v) { } : __ArgvPackImpls(means, ParamType::IndexParam), _place_holder(place_v) { }
QString args_parse::IndexParam::placeHolder(bool v) const { QString IndexParam::placeHolder(bool v) const {
return QString("<%1>").arg(_place_holder); return QString("<%1>").arg(_place_holder);
} }
@ -65,8 +68,11 @@ int IndexParam::matchLenth() const {
return 1; return 1;
} }
bool IndexParam::parse(const QList<QString> args, int start) { bool IndexParam::parse(const QList<QString> args) {
setValue(args[start]); if (args.size() < 1)
return false;
setValue(args[0]);
return true; return true;
} }
@ -76,7 +82,7 @@ __FloatArgvImpls::__FloatArgvImpls(const QString& key, const QString& means, boo
FloatOption::FloatOption(const QString& key, const QString& means, bool opt) FloatOption::FloatOption(const QString& key, const QString& means, bool opt)
: __FloatArgvImpls(key, means, opt) { } : __FloatArgvImpls(key, means, opt) { }
QString args_parse::FloatOption::placeHolder(bool d) const { QString FloatOption::placeHolder(bool d) const {
if (optional() && d) if (optional() && d)
return QString("[--%1]").arg(bindKey()); return QString("[--%1]").arg(bindKey());
return QString("--%1").arg(bindKey()); return QString("--%1").arg(bindKey());
@ -86,10 +92,15 @@ int FloatOption::matchLenth() const {
return 1; return 1;
} }
bool FloatOption::parse(const QList<QString> args, int start) { bool FloatOption::parse(const QList<QString> args) {
auto args_t = args[start]; if (args.size() < 1)
if (args_t == u8"--" + bindKey()) return false;
auto args_t = args[0];
if (args_t == u8"--" + bindKey()) {
setValue(true); setValue(true);
return true;
}
return false; return false;
} }
@ -101,7 +112,7 @@ MatchMode::MatchMode(int mode_code, const QString& mode)
* @return * @return
*/ */
MatchMode& args_parse::MatchMode::operator<<(std::shared_ptr<IArgvPack> unit) { MatchMode& MatchMode::operator<<(std::shared_ptr<IArgvPack> unit) {
args_mode << unit; args_mode << unit;
return *this; return *this;
} }
@ -110,7 +121,7 @@ int MatchMode::modeCode() const {
return code_store; return code_store;
} }
QString args_parse::MatchMode::usageString() const { QString MatchMode::usageString() const {
QString usage_string; QString usage_string;
for (auto& item : args_mode) for (auto& item : args_mode)
usage_string += item->placeHolder() + u8" "; usage_string += item->placeHolder() + u8" ";
@ -118,7 +129,7 @@ QString args_parse::MatchMode::usageString() const {
return usage_string; return usage_string;
} }
QString args_parse::MatchMode::explanString() const { QString MatchMode::explanString() const {
QStringList sections; QStringList sections;
sections << u8" " + _means_explain; sections << u8" " + _means_explain;
sections << QString(" Switch:"); sections << QString(" Switch:");
@ -144,45 +155,57 @@ QString args_parse::MatchMode::explanString() const {
* @brief * @brief
*/ */
bool MatchMode::parse(const QList<QString>& args, int argv_index, int parse_index) { bool MatchMode::parse(const QList<QString>& args) {
// 获取模式匹配单元 decltype(this->args_mode) float_units;
auto parse_unit = args_mode[parse_index]; std::copy_if(this->args_mode.begin(), this->args_mode.end(), std::back_inserter(float_units),
switch (parse_unit->paramType()) { [](std::shared_ptr<IArgvPack> inst) {
case ParamType::IndexParam:// 固定位置索引匹配 return inst->paramType() == ParamType::FloatParam;
{ });
parse_unit->parse(args, argv_index);
// 继续匹配下一个为止
return parse(args, argv_index + parse_unit->matchLenth(), parse_index + 1);
}break;
case ParamType::FloatParam:// 浮动参数匹配
{
QList<shared_ptr<__FloatArgvImpls>> float_parsers;
for (auto& unit : args_mode) {
if (unit->paramType() == ParamType::FloatParam)
float_parsers << dynamic_pointer_cast<__FloatArgvImpls>(unit);
}
for (auto& unit : float_parsers) { auto remains = args;
if (argv_index + unit->matchLenth() > args.size()) for (auto idx = 0; idx < remains.size(); ++idx) {
continue; auto vargs = remains.mid(idx);
for (auto& unit : float_units) {
auto result = unit->parse(args, argv_index); if (unit->parse(vargs)) {
// 匹配成功 auto it_start = remains.begin() + idx;
if (result) auto it_until = it_start + unit->matchLenth();
// 继续下一个 remains.erase(it_start, it_until);
if (parse(args, argv_index + unit->matchLenth(), parse_index + 1)) idx--;
return true; break;
else if (!result && unit->optional()) }
if (parse(args, argv_index, parse_index + 1)) }
return true;
}
}break;
} }
return false; decltype(this->args_mode) indexed_units;
std::copy_if(this->args_mode.begin(), this->args_mode.end(), std::back_inserter(indexed_units),
[](std::shared_ptr<IArgvPack> inst) {
return inst->paramType() == ParamType::IndexParam;
});
for (auto idx = 0; idx < std::min(remains.size(), indexed_units.size()); ++idx) {
auto vargs = remains.mid(idx);
auto unit = indexed_units[idx];
unit->parse(vargs);
}
for (auto& u : args_mode) {
switch (u->paramType()) {
case ParamType::IndexParam:
if (u->value().isNull())
return false;
break;
case ParamType::FloatParam:
if (!std::dynamic_pointer_cast<__FloatArgvImpls>(u)->optional() && u->value().isNull())
return false;
break;
default:
break;
}
}
return true;
} }
std::shared_ptr<IArgvPack> args_parse::MatchMode::getUnitViaKey(const QString& key) { std::shared_ptr<IArgvPack> MatchMode::getUnitViaKey(const QString& key) {
for (auto& u : args_mode) { for (auto& u : args_mode) {
if (u->paramType() == ParamType::FloatParam) { if (u->paramType() == ParamType::FloatParam) {
auto conv = std::dynamic_pointer_cast<__FloatArgvImpls>(u); auto conv = std::dynamic_pointer_cast<__FloatArgvImpls>(u);
@ -194,11 +217,11 @@ std::shared_ptr<IArgvPack> args_parse::MatchMode::getUnitViaKey(const QString& k
return std::shared_ptr<IArgvPack>(); return std::shared_ptr<IArgvPack>();
} }
std::shared_ptr<IArgvPack> args_parse::MatchMode::getUnitViaPos(int pos) { std::shared_ptr<IArgvPack> MatchMode::getUnitViaInitIndex(int pos) {
return args_mode[pos]; return args_mode[pos];
} }
QString args_parse::ArgsParser::helpDoc() const { QString ArgsParser::helpDoc() const {
QString help_string; QString help_string;
for (auto& mode : this->match_modes) { for (auto& mode : this->match_modes) {
help_string += "Usage:" + mode->usageString() + "\n"; help_string += "Usage:" + mode->usageString() + "\n";
@ -207,7 +230,7 @@ QString args_parse::ArgsParser::helpDoc() const {
return help_string; return help_string;
} }
ArgsParser& args_parse::ArgsParser::operator<<(std::shared_ptr<MatchMode> mode) { ArgsParser& ArgsParser::operator<<(std::shared_ptr<MatchMode> mode) {
this->match_modes.append(mode); this->match_modes.append(mode);
return *this; return *this;
} }
@ -222,7 +245,7 @@ std::shared_ptr<MatchMode> ArgsParser::parse(int argc, char* argv[]) {
// 枚举模式匹配 // 枚举模式匹配
for (auto& minst : this->match_modes) { for (auto& minst : this->match_modes) {
if (minst->parse(args_list, 0, 0)) if (minst->parse(args_list))
return minst; return minst;
} }

View File

@ -50,7 +50,7 @@ namespace args_parse {
* \param start * \param start
* \return * \return
*/ */
virtual bool parse(const QList<QString> args, int start) = 0; virtual bool parse(const QList<QString> args) = 0;
}; };
class ARGSPARSER_EXPORT __ArgvPackImpls : public IArgvPack { class ARGSPARSER_EXPORT __ArgvPackImpls : public IArgvPack {
@ -100,7 +100,7 @@ namespace args_parse {
virtual QString placeHolder(bool decorate = true) const override; virtual QString placeHolder(bool decorate = true) const override;
virtual int matchLenth() const override; virtual int matchLenth() const override;
bool parse(const QList<QString> args, int start) override; bool parse(const QList<QString> args) override;
}; };
/** /**
@ -121,7 +121,7 @@ namespace args_parse {
virtual QString placeHolder(bool decorate = true) const override; virtual QString placeHolder(bool decorate = true) const override;
virtual int matchLenth() const override; virtual int matchLenth() const override;
bool parse(const QList<QString> args, int start) override; bool parse(const QList<QString> args) override;
}; };
/** /**
@ -138,7 +138,7 @@ namespace args_parse {
// 通过 __ArgvPackImpls 继承 // 通过 __ArgvPackImpls 继承
virtual QString placeHolder(bool decorate = true) const override; virtual QString placeHolder(bool decorate = true) const override;
int matchLenth() const override; int matchLenth() const override;
bool parse(const QList<QString> args, int start) override; bool parse(const QList<QString> args) override;
}; };
class ARGSPARSER_EXPORT MatchMode { class ARGSPARSER_EXPORT MatchMode {
@ -182,7 +182,7 @@ namespace args_parse {
/** /**
* @brief * @brief
*/ */
bool parse(const QList<QString>& args, int argv_index, int parse_index); bool parse(const QList<QString>& args);
/** /**
* . * .
@ -191,7 +191,7 @@ namespace args_parse {
* \return * \return
*/ */
std::shared_ptr<IArgvPack> getUnitViaKey(const QString& key); std::shared_ptr<IArgvPack> getUnitViaKey(const QString& key);
std::shared_ptr<IArgvPack> getUnitViaPos(int pos); std::shared_ptr<IArgvPack> getUnitViaInitIndex(int idx);
}; };
class ARGSPARSER_EXPORT ArgsParser { class ARGSPARSER_EXPORT ArgsParser {

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>--help</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<QtTouchProperty> <QtTouchProperty>
</QtTouchProperty> </QtTouchProperty>

View File

@ -39,12 +39,14 @@ int main(int argc, char *argv[])
<< make_shared<FloatKeyValue>(u8"gmode", u8"设置图形化显示的模式"); << make_shared<FloatKeyValue>(u8"gmode", u8"设置图形化显示的模式");
auto rst = entry_parser.parse(argc, argv); auto rst = entry_parser.parse(argc, argv);
std::cout << rst << std::endl;
if (!rst) { if (!rst) {
qDebug().noquote() << u8"命令行参数错误"; qDebug().noquote() << u8"命令行参数错误";
qDebug().noquote() << entry_parser.helpDoc(); qDebug().noquote() << entry_parser.helpDoc();
return 0; return 0;
} }
if (rst->modeCode() == 0x000au) {
qDebug().noquote() << entry_parser.helpDoc();
}
return 0; return 0;