From b3a2bd9e7d829afca26c6ab3ea09dfc6490319ce Mon Sep 17 00:00:00 2001 From: Sebastian Goth Date: Mon, 14 Jul 2008 18:46:33 +0200 Subject: [PATCH] Added parsing, usage() generation and removed debugging. --- src/common/cliparser.cpp | 163 ++++++++++++++++++++++++++++++++++----- src/common/cliparser.h | 49 +++++++----- 2 files changed, 172 insertions(+), 40 deletions(-) diff --git a/src/common/cliparser.cpp b/src/common/cliparser.cpp index ad02b968..fc29f0e5 100644 --- a/src/common/cliparser.cpp +++ b/src/common/cliparser.cpp @@ -18,57 +18,180 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "cliparser.h" -#include -CliParser::CliParser(int argc, char *argv[]) +#include +#include + +CliParser::CliParser(QStringList arguments) { - if(argc) { - for (int i=0; i < argc; ++i) - argsRaw.append(QString::fromUtf8(argv[i])); - } + argsRaw = arguments; } +void CliParser::addSwitch(QString longName, char shortName, QVariant def) { + addArgument(CliParserArg::CliArgSwitch, longName, shortName, def); +} -CliParser::~CliParser() -{ +void CliParser::addOption(QString longName, char shortName, QVariant def) { + addArgument(CliParserArg::CliArgOption, longName, shortName, def); } -void CliParser::addArgument(QString longName, char shortName = 0, QVariant def = QVariant()) { - CliParserArg arg = CliParserArg(longName, shortName, def); +void CliParser::addArgument(CliParserArg::CliArgType type, QString longName, char shortName, QVariant def) { + CliParserArg arg = CliParserArg(type, longName, shortName, def); argsHash.insert(longName, arg); - qDebug() << "Added Argument: " << longName << " with arg-addr: " << &arg; + if(shortName && !shortHash.contains(shortName)) shortHash.insert(shortName, argsHash.find(longName)); +} + +void CliParser::addHelp(QString key, QString txt) { + if(argsHash.contains(key)) argsHash[key].shortHelp = txt; + else qWarning("Warning: Helptext for unknown argument '%s' given",key.toLatin1().constData()); } bool CliParser::parse() { - qDebug() << "Parse results: "; - qDebug() << argsHash.value("logfile").value; - argsHash[QString("logfile")].value = "BOOYA"; + QStringList::const_iterator currentArg; + for (currentArg = argsRaw.constBegin(); currentArg != argsRaw.constEnd(); ++currentArg) { + if(currentArg->startsWith("--")) { + QString name; + // long + if(currentArg->contains("=")) { + // option + QStringList tmp = currentArg->mid(2).split("="); + name = tmp.at(0); + QString value = tmp.at(1); + if(argsHash.contains(name) && !value.isEmpty()){ + argsHash[name].value = value; + } + else return false; + } + else { + // switch + name = currentArg->mid(2); + if(argsHash.contains(name)) { + argsHash[name].value = true; + } + else return false; + } + } + else if(currentArg->startsWith("-")) { + char name; + // short + bool bla = true; + if(++currentArg == argsRaw.constEnd()) { + --currentArg; + bla = false; + } + // if next arg is a short/long option/switch the current arg is one too + if(currentArg->startsWith("-")) { + // switch + if(bla) --currentArg; + for (int i = 0; i < currentArg->mid(1).toAscii().size(); i++) { + name = currentArg->mid(1).toAscii().at(i); + if(shortHash.contains(name) && shortHash.value(name).value().type == CliParserArg::CliArgSwitch) { + shortHash[name].value().value = true; + } + else return false; + } + } + // if next arg is is no option/switch it's an argument to a shortoption + else { + // option + QString value = currentArg->toUtf8(); + if(bla) --currentArg; + name = currentArg->mid(1).toAscii().at(0); + if(bla) currentArg++; + if(shortHash.contains(name) && shortHash.value(name).value().type == CliParserArg::CliArgOption) { + shortHash[name].value().value = value; + } + else return false; + } + } + else { + // we don't support plain arguments without -/-- + if(currentArg->toLatin1() != argsRaw.at(0)) { + return false; + } + } + } + return true; +} + +void CliParser::usage() { + qWarning("Usage: %s [arguments]",QFileInfo(argsRaw.at(0)).completeBaseName().toLatin1().constData()); + + // get size of longName field + QStringList keys = argsHash.keys(); + uint lnameFieldSize = 0; + foreach (QString key, keys) { + uint size = 0; + if(argsHash.value(key).type == CliParserArg::CliArgOption) + size += key.size()*2; + else + size += key.size(); + // this is for " --...=[....] " + size += 8; + if(size > lnameFieldSize) lnameFieldSize = size; + } + + QHash::const_iterator arg; + for(arg = argsHash.constBegin(); arg != argsHash.constEnd(); ++arg) { + QString output; + QString lnameField; + + if(arg.value().sname) { + output.append(" -").append(arg.value().sname).append(","); + } + else output.append(" "); + lnameField.append(" --").append(arg.key().toLatin1().constData()); + if(arg.value().type == CliParserArg::CliArgOption) { + lnameField.append("=[").append(arg.value().lname.toUpper()).append("]"); + } + output.append(lnameField.leftJustified(lnameFieldSize)); + if(!arg.value().shortHelp.isEmpty()) { + output.append(arg.value().shortHelp); + } + if(arg.value().type == CliParserArg::CliArgOption) { + output.append(". Default is: ").append(arg.value().def.toString()); + } + qWarning(output.toLatin1()); + } } QVariant CliParser::value(QString key) { - return argsHash.value(key).value; + if(argsHash.contains(key)) { + if(argsHash.value(key).value.isValid()) + return argsHash.value(key).value; + else + return argsHash.value(key).def; + } + else { + qWarning("Warning: Requested value of not defined argument '%s'",key.toLatin1().constData()); + return QVariant(); + } } -CliParserArg::CliParserArg(QString longName, char shortName = 0, QVariant _def = QVariant() ) - : lname(longName), +CliParserArg::CliParserArg(CliArgType _type, QString longName, char shortName, QVariant _def) + : type(_type), + lname(longName), sname(shortName), + shortHelp(QString()), def(_def), - value(0) { - + value(QVariant()) { } CliParserArg::CliParserArg(const CliParserArg &other) { + type = other.type; lname = other.lname; sname = other.sname; + shortHelp = other.shortHelp; def = other.def; value = other.value; } CliParserArg &CliParserArg::operator=(const CliParserArg &other) { + type = other.type; lname = other.lname; sname = other.sname; + shortHelp = other.shortHelp; def = other.def; value = other.value; return *this; } - diff --git a/src/common/cliparser.h b/src/common/cliparser.h index 6872f773..00f22b98 100644 --- a/src/common/cliparser.h +++ b/src/common/cliparser.h @@ -26,36 +26,45 @@ #include #include -class CliParserArg; - -class CliParser{ -public: - inline CliParser() {}; - CliParser(int argc, char *argv[]); - - ~CliParser(); - bool parse(); - QVariant value(QString key); - void addArgument(QString longName, char shortName, QVariant def); -private: - QStringList argsRaw; - QHash savedValues; - QHash argsHash; - QHash::iterator> shortHash; -}; - class CliParserArg { public: + enum CliArgType { + CliArgInvalid, + CliArgSwitch, + CliArgOption + }; + typedef CliArgType CliArgTypes; + inline CliParserArg() {}; CliParserArg(const CliParserArg &other); - CliParserArg(QString longName, char shortName, QVariant _def); + CliParserArg(CliArgType type, QString longName, char shortName = 0, QVariant _def = QVariant()); CliParserArg &operator=(const CliParserArg &other); -// private: + + CliArgType type; QString lname; char sname; + QString shortHelp; QVariant def; QVariant value; }; Q_DECLARE_METATYPE(CliParserArg); +class CliParser{ +public: + inline CliParser() {}; + CliParser(QStringList arguments); + bool parse(); + QVariant value(QString key); + void addSwitch(QString longName, char shortName = 0, QVariant def = false); + void addOption(QString longName, char shortName = 0, QVariant def = QVariant()); + void addHelp(QString key, QString txt); + void usage(); +private: + void addArgument(CliParserArg::CliArgType type, QString longName, char shortName, QVariant def); + QStringList argsRaw; + QHash argsHash; + QHash::iterator> shortHash; +}; + + #endif -- 2.20.1