WsParser_VS/ArgsParser/argsparser.cpp

265 lines
6.3 KiB
C++
Raw Normal View History

2024-06-22 10:53:51 +00:00
#include "argsparser.h"
2024-10-01 16:03:59 +00:00
#include <QVariant>
2024-06-22 10:53:51 +00:00
using namespace args_parse;
2024-09-24 10:43:10 +00:00
using namespace std;
2024-06-22 10:53:51 +00:00
2024-10-01 08:52:05 +00:00
__ArgvPackImpls::__ArgvPackImpls(const QString& means, ParamType t) : means_store(means), type_store(t) { }
2024-06-22 10:53:51 +00:00
2025-02-15 15:47:42 +00:00
// 通过 IArgvPack 继承
2024-10-01 08:52:05 +00:00
ParamType __ArgvPackImpls::paramType() const {
2024-09-24 10:43:10 +00:00
return type_store;
}
2024-06-22 10:53:51 +00:00
2024-10-01 08:52:05 +00:00
QString __ArgvPackImpls::means() const {
2024-09-24 10:43:10 +00:00
return means_store;
}
2024-06-22 10:53:51 +00:00
2024-10-01 16:03:59 +00:00
void __ArgvPackImpls::setValue(const QVariant& v) {
2024-06-22 10:53:51 +00:00
this->value_store = v;
}
2024-10-01 16:03:59 +00:00
QVariant __ArgvPackImpls::value() const {
2024-09-24 10:43:10 +00:00
return value_store;
}
2024-06-22 10:53:51 +00:00
2024-10-01 08:52:05 +00:00
FloatKeyValue::FloatKeyValue(const QString& key, const QString& means, bool optional) :
2024-10-01 15:23:54 +00:00
__FloatArgvImpls(key, means, optional) { }
2024-06-22 10:53:51 +00:00
2024-10-01 15:23:54 +00:00
QString __FloatArgvImpls::bindKey() const {
2024-09-24 10:43:10 +00:00
return key_name;
}
2024-06-22 10:53:51 +00:00
2024-10-01 15:23:54 +00:00
bool __FloatArgvImpls::optional() const {
2024-06-22 10:53:51 +00:00
return optional_value;
}
2024-10-03 13:45:30 +00:00
QString FloatKeyValue::placeHolder(bool v) const {
2024-10-02 02:03:19 +00:00
if (optional() && v)
2024-10-01 09:48:20 +00:00
return QString("[--%1 <%2>]").arg(bindKey(), bindKey());
return QString("--%1 <%2>").arg(bindKey(), bindKey());
}
2024-10-01 08:52:05 +00:00
int FloatKeyValue::matchLenth() const {
2024-06-22 10:53:51 +00:00
return 2;
}
2024-10-03 13:45:30 +00:00
bool FloatKeyValue::parse(const QList<QString> args) {
if (args.size() < 2)
return false;
auto args_t = args[0];
2025-02-15 15:47:42 +00:00
if (args_t == "--" + bindKey()) {
2024-10-03 13:45:30 +00:00
auto args_v = args[1];
2024-06-22 10:53:51 +00:00
setValue(args_v);
2024-10-01 15:23:54 +00:00
return true;
}
return false;
2024-06-22 10:53:51 +00:00
}
2024-10-01 09:48:20 +00:00
IndexParam::IndexParam(const QString& place_v, const QString& means)
: __ArgvPackImpls(means, ParamType::IndexParam), _place_holder(place_v) { }
2024-10-03 13:45:30 +00:00
QString IndexParam::placeHolder(bool v) const {
2024-10-01 09:48:20 +00:00
return QString("<%1>").arg(_place_holder);
}
2024-06-22 10:53:51 +00:00
2024-09-24 10:43:10 +00:00
int IndexParam::matchLenth() const {
2024-06-22 10:53:51 +00:00
return 1;
}
2024-10-03 13:45:30 +00:00
bool IndexParam::parse(const QList<QString> args) {
if (args.size() < 1)
return false;
setValue(args[0]);
2024-06-22 10:53:51 +00:00
return true;
}
2024-10-01 15:23:54 +00:00
__FloatArgvImpls::__FloatArgvImpls(const QString& key, const QString& means, bool optional)
2024-10-01 08:52:05 +00:00
: __ArgvPackImpls(means, ParamType::FloatParam), key_name(key), optional_value(optional) { }
2024-06-22 10:53:51 +00:00
2024-09-24 10:43:10 +00:00
FloatOption::FloatOption(const QString& key, const QString& means, bool opt)
2024-10-03 12:37:24 +00:00
: __FloatArgvImpls(key, means, opt) { }
2024-06-22 10:53:51 +00:00
2024-10-03 13:45:30 +00:00
QString FloatOption::placeHolder(bool d) const {
2024-10-02 02:03:19 +00:00
if (optional() && d)
2024-10-01 09:48:20 +00:00
return QString("[--%1]").arg(bindKey());
return QString("--%1").arg(bindKey());
}
2024-09-24 10:43:10 +00:00
int FloatOption::matchLenth() const {
return 1;
}
2024-06-22 10:53:51 +00:00
2024-10-03 13:45:30 +00:00
bool FloatOption::parse(const QList<QString> args) {
if (args.size() < 1)
return false;
auto args_t = args[0];
2025-02-15 15:47:42 +00:00
if (args_t == "--" + bindKey()) {
2024-10-03 12:37:24 +00:00
setValue(true);
2024-10-03 13:45:30 +00:00
return true;
}
2024-10-03 12:37:24 +00:00
return false;
2024-06-22 10:53:51 +00:00
}
2024-10-01 15:23:54 +00:00
MatchMode::MatchMode(int mode_code, const QString& mode)
:_means_explain(mode), code_store(mode_code) { }
2024-10-01 10:17:40 +00:00
/**
2025-02-15 15:47:42 +00:00
* @brief
* @return
2024-10-01 10:17:40 +00:00
*/
2024-10-03 13:45:30 +00:00
MatchMode& MatchMode::operator<<(std::shared_ptr<IArgvPack> unit) {
2024-10-04 05:12:16 +00:00
if(unit->paramType() == ParamType::FloatParam){
auto unit_in = std::dynamic_pointer_cast<__FloatArgvImpls>(unit);
for (auto& u_exist : args_mode) {
if (u_exist->paramType() == ParamType::FloatParam) {
auto u_cast = std::dynamic_pointer_cast<__FloatArgvImpls>(u_exist);
if (u_cast->bindKey() == unit_in->bindKey())
2025-02-15 15:47:42 +00:00
throw new std::exception("重复设置选项");
2024-10-04 05:12:16 +00:00
}
}
}
2024-10-01 15:23:54 +00:00
args_mode << unit;
return *this;
}
2024-10-01 10:17:40 +00:00
int MatchMode::modeCode() const {
return code_store;
}
2025-02-19 05:43:34 +00:00
QString MatchMode::usagestring() const {
2024-10-01 15:23:54 +00:00
QString usage_string;
for (auto& item : args_mode)
2025-02-15 15:47:42 +00:00
usage_string += item->placeHolder() + " ";
2024-10-01 10:17:40 +00:00
2024-10-01 15:23:54 +00:00
return usage_string;
}
2025-02-19 05:43:34 +00:00
QString MatchMode::explanstring() const {
2024-10-01 15:23:54 +00:00
QStringList sections;
2025-02-15 15:47:42 +00:00
sections << " " + _means_explain;
2024-10-01 15:23:54 +00:00
sections << QString(" Switch:");
for (auto& item : args_mode) {
2024-10-03 12:37:24 +00:00
if (item->paramType() == ParamType::IndexParam) {
sections << " " + item->placeHolder(false);
sections << " " + item->means();
}
}
for (auto& item : args_mode) {
if (item->paramType() == ParamType::FloatParam) {
sections << " " + item->placeHolder(false);
sections << " " + item->means();
}
2024-10-01 15:23:54 +00:00
}
return sections.join("\n");
2024-10-01 10:17:40 +00:00
}
/**
2025-02-15 15:47:42 +00:00
* @brief
2024-10-01 10:17:40 +00:00
*/
2024-10-03 13:45:30 +00:00
bool MatchMode::parse(const QList<QString>& args) {
decltype(this->args_mode) float_units;
std::copy_if(this->args_mode.begin(), this->args_mode.end(), std::back_inserter(float_units),
[](std::shared_ptr<IArgvPack> inst) {
return inst->paramType() == ParamType::FloatParam;
});
auto remains = args;
for (auto idx = 0; idx < remains.size(); ++idx) {
auto vargs = remains.mid(idx);
for (auto& unit : float_units) {
if (unit->parse(vargs)) {
auto it_start = remains.begin() + idx;
auto it_until = it_start + unit->matchLenth();
remains.erase(it_start, it_until);
idx--;
break;
}
}
2024-10-01 10:17:40 +00:00
}
2024-10-03 13:45:30 +00:00
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;
2024-06-22 10:53:51 +00:00
}
2024-10-01 10:17:40 +00:00
2024-10-03 13:45:30 +00:00
std::shared_ptr<IArgvPack> MatchMode::getUnitViaKey(const QString& key) {
2024-10-01 15:23:54 +00:00
for (auto& u : args_mode) {
if (u->paramType() == ParamType::FloatParam) {
auto conv = std::dynamic_pointer_cast<__FloatArgvImpls>(u);
if (conv->bindKey() == key)
return u;
}
}
return std::shared_ptr<IArgvPack>();
}
2024-10-03 13:45:30 +00:00
std::shared_ptr<IArgvPack> MatchMode::getUnitViaInitIndex(int pos) {
2024-10-01 15:23:54 +00:00
return args_mode[pos];
}
2024-10-04 05:12:16 +00:00
QString ArgsParser::helperDoc() const {
2024-10-01 15:23:54 +00:00
QString help_string;
for (auto& mode : this->match_modes) {
2025-02-19 05:43:34 +00:00
help_string += "Usage:" + mode->usagestring() + "\n";
help_string += mode->explanstring() + "\n\n";
2024-10-01 15:23:54 +00:00
}
return help_string;
}
2024-10-03 13:45:30 +00:00
ArgsParser& ArgsParser::operator<<(std::shared_ptr<MatchMode> mode) {
2024-10-01 15:23:54 +00:00
this->match_modes.append(mode);
return *this;
2024-06-22 10:53:51 +00:00
}
2024-10-01 15:23:54 +00:00
std::shared_ptr<MatchMode> ArgsParser::parse(int argc, char* argv[]) {
2025-02-15 15:47:42 +00:00
// 聚合参数数组
2024-06-22 10:53:51 +00:00
QList<QString> args_list;
for (int idx = 0; idx < argc; idx++) {
auto argv_str = QString::fromLocal8Bit(argv[idx]);
args_list.append(argv_str);
}
2025-02-15 15:47:42 +00:00
// 枚举模式匹配
2024-06-22 10:53:51 +00:00
for (auto& minst : this->match_modes) {
2024-10-03 13:45:30 +00:00
if (minst->parse(args_list))
2024-10-01 15:23:54 +00:00
return minst;
2024-06-22 10:53:51 +00:00
}
2024-10-01 15:23:54 +00:00
return std::shared_ptr<MatchMode>();
2024-06-22 10:53:51 +00:00
}