WsParser_VS/ArgsParser/argsparser.cpp

231 lines
5.6 KiB
C++

#include "argsparser.h"
#include <QVariant>
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 QVariant& v) {
this->value_store = v;
}
QVariant __ArgvPackImpls::value() const {
return value_store;
}
FloatKeyValue::FloatKeyValue(const QString& key, const QString& means, bool optional) :
__FloatArgvImpls(key, means, optional) { }
QString __FloatArgvImpls::bindKey() const {
return key_name;
}
bool __FloatArgvImpls::optional() const {
return optional_value;
}
QString args_parse::FloatKeyValue::placeHolder(bool v) const {
if (optional() && v)
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<QString> args, int start) {
auto args_t = args[start];
auto args_v = args[start + 1];
if (args_t == u8"--" + bindKey()) {
setValue(args_v);
return true;
}
return false;
}
IndexParam::IndexParam(const QString& place_v, const QString& means)
: __ArgvPackImpls(means, ParamType::IndexParam), _place_holder(place_v) { }
QString args_parse::IndexParam::placeHolder(bool v) const {
return QString("<%1>").arg(_place_holder);
}
int IndexParam::matchLenth() const {
return 1;
}
bool IndexParam::parse(const QList<QString> args, int start) {
setValue(args[start]);
return true;
}
__FloatArgvImpls::__FloatArgvImpls(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)
: __FloatArgvImpls(key, means, opt) { }
QString args_parse::FloatOption::placeHolder(bool d) const {
if (optional() && d)
return QString("[--%1]").arg(bindKey());
return QString("--%1").arg(bindKey());
}
int FloatOption::matchLenth() const {
return 1;
}
bool FloatOption::parse(const QList<QString> args, int start) {
auto args_t = args[start];
if (args_t == u8"--" + bindKey())
setValue(true);
return false;
}
MatchMode::MatchMode(int mode_code, const QString& mode)
:_means_explain(mode), code_store(mode_code) { }
/**
* @brief »ñȡģʽ´úÂë
* @return ģʽ´úÂë
*/
MatchMode& args_parse::MatchMode::operator<<(std::shared_ptr<IArgvPack> unit) {
args_mode << unit;
return *this;
}
int MatchMode::modeCode() const {
return code_store;
}
QString args_parse::MatchMode::usageString() const {
QString usage_string;
for (auto& item : args_mode)
usage_string += item->placeHolder() + u8" ";
return usage_string;
}
QString args_parse::MatchMode::explanString() const {
QStringList sections;
sections << u8" " + _means_explain;
sections << QString(" Switch:");
for (auto& item : args_mode) {
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();
}
}
return sections.join("\n");
}
/**
* @brief ½âÎöÆ¥Åä²ÎÊý
*/
bool MatchMode::parse(const QList<QString>& args, int argv_index, int parse_index) {
// »ñȡģʽƥÅäµ¥Ôª
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<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) {
if (argv_index + unit->matchLenth() > 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;
}
std::shared_ptr<IArgvPack> args_parse::MatchMode::getUnitViaKey(const QString& key) {
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>();
}
std::shared_ptr<IArgvPack> args_parse::MatchMode::getUnitViaPos(int pos) {
return args_mode[pos];
}
QString args_parse::ArgsParser::helpDoc() const {
QString help_string;
for (auto& mode : this->match_modes) {
help_string += "Usage:" + mode->usageString() + "\n";
help_string += mode->explanString() + "\n\n";
}
return help_string;
}
ArgsParser& args_parse::ArgsParser::operator<<(std::shared_ptr<MatchMode> mode) {
this->match_modes.append(mode);
return *this;
}
std::shared_ptr<MatchMode> ArgsParser::parse(int argc, char* argv[]) {
// ¾ÛºÏ²ÎÊýÊý×é
QList<QString> 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 minst;
}
return std::shared_ptr<MatchMode>();
}