diff options
author | Orochimarufan <orochimarufan.x3@gmail.com> | 2013-02-20 00:07:52 +0100 |
---|---|---|
committer | Orochimarufan <orochimarufan.x3@gmail.com> | 2013-02-20 00:07:52 +0100 |
commit | c523a2c752bb7b071715f6c4eac18f36bcd2c162 (patch) | |
tree | 1440f811d161cfd5159d2427d760815021a5485f /util/cmdutils.h | |
parent | cf0e78b46dbd740caac9288f3fe5ef5d99ed2ce9 (diff) | |
download | MultiMC-c523a2c752bb7b071715f6c4eac18f36bcd2c162.tar MultiMC-c523a2c752bb7b071715f6c4eac18f36bcd2c162.tar.gz MultiMC-c523a2c752bb7b071715f6c4eac18f36bcd2c162.tar.lz MultiMC-c523a2c752bb7b071715f6c4eac18f36bcd2c162.tar.xz MultiMC-c523a2c752bb7b071715f6c4eac18f36bcd2c162.zip |
implement commandline parsing
Diffstat (limited to 'util/cmdutils.h')
-rw-r--r-- | util/cmdutils.h | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/util/cmdutils.h b/util/cmdutils.h new file mode 100644 index 00000000..10f8a9db --- /dev/null +++ b/util/cmdutils.h @@ -0,0 +1,237 @@ +/* Copyright 2013 MultiMC Contributors + * + * Authors: Orochimarufan <orochimarufan.x3@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CMDUTILS_H +#define CMDUTILS_H + +#include <exception> + +#include <QString> +#include <QVariant> +#include <QHash> +#include <QStringList> + +/** + * @file utils/cmdutils.h + * @brief commandline parsing utilities + */ + +namespace Util { +namespace Commandline { + +/** + * @brief The FlagStyle enum + * Specifies how flags are decorated + */ +enum class FlagStyle { + GNU, /**< --option and -o (GNU Style) */ + Unix, /**< -option and -o (Unix Style) */ + Windows, /**< /option and /o (Windows Style) */ +#ifdef Q_OS_WIN32 + Default = Windows +#else + Default = GNU +#endif +}; + +/** + * @brief The ArgumentStyle enum + */ +enum class ArgumentStyle { + Space, /**< --option=value */ + Equals, /**< --option value */ + SpaceAndEquals, /**< --option[= ]value */ +#ifdef Q_OS_WIN32 + Default = Equals +#else + Default = SpaceAndEquals +#endif +}; + +/** + * @brief The ParsingError class + */ +class ParsingError : public std::exception +{ +public: + ParsingError(const QString &what) throw(); + ParsingError(const ParsingError &e) throw(); + ~ParsingError() throw() {} + char *what() const throw(); + QString qwhat() const throw(); +private: + QString m_what; +}; + +/** + * @brief The Parser class + */ +class Parser +{ +public: + /** + * @brief Parser constructor + * @param flagStyle the FlagStyle to use in this Parser + * @param argStyle the ArgumentStyle to use in this Parser + */ + Parser(FlagStyle flagStyle=FlagStyle::Default, ArgumentStyle argStyle=ArgumentStyle::Default); + + /** + * @brief set the flag style + * @param style + */ + void setFlagStyle(FlagStyle style); + + /** + * @brief get the flag style + * @return + */ + FlagStyle flagStyle(); + + /** + * @brief set the argument style + * @param style + */ + void setArgumentStyle(ArgumentStyle style); + + /** + * @brief get the argument style + * @return + */ + ArgumentStyle argumentStyle(); + + /** + * @brief define a boolean switch + * @param name the parameter name + * @param def the default value + */ + void addSwitch(QString name, bool def=false) throw (const char *); + + /** + * @brief define an option that takes an additional argument + * @param name the parameter name + * @param def the default value + */ + void addOption(QString name, QVariant def=QVariant()) throw (const char *); + + /** + * @brief define a positional argument + * @param name the parameter name + * @param required wether this argument is required + * @param def the default value + */ + void addArgument(QString name, bool required=true, QVariant def=QVariant()) throw (const char *); + + /** + * @brief adds a flag to an existing parameter + * @param name the (existing) parameter name + * @param flag the flag character + * @see addSwitch addArgument addOption + * Note: any one parameter can only have one flag + */ + void addShortOpt(QString name, QChar flag) throw (const char *); + + /** + * @brief adds documentation to a Parameter + * @param name the parameter name + * @param metavar a string to be displayed as placeholder for the value + * @param doc a QString containing the documentation + */ + void addDocumentation(QString name, QString doc, QString metavar=QString()) throw (const char *); + + /** + * @brief generate a help message + * @param progName the program name to use in the help message + * @param helpIndent how much the parameter documentation should be indented + * @param flagsInUsage whether we should use flags instead of options in the usage + * @return a help message + */ + QString compileHelp(QString progName, int helpIndent=22, bool flagsInUsage=true); + + /** + * @brief generate a short usage message + * @param progName the program name to use in the usage message + * @param useFlags whether we should use flags instead of options + * @return a usage message + */ + QString compileUsage(QString progName, bool useFlags=true); + + /** + * @brief parse + * @param argv a QStringList containing the program ARGV + * @return a QHash mapping argument names to their values + */ + QHash<QString, QVariant> parse(QStringList argv) throw (ParsingError); + + /** + * @brief clear all definitions + */ + void clear(); + + ~Parser(); + +private: + FlagStyle m_flagStyle; + ArgumentStyle m_argStyle; + + enum class OptionType { + Switch, + Option + }; + + // Important: the common part MUST BE COMMON ON ALL THREE structs + struct CommonDef { + QString name; + QString doc; + QString metavar; + QVariant def; + }; + + struct OptionDef { + // common + QString name; + QString doc; + QString metavar; + QVariant def; + // option + OptionType type; + QChar flag; + }; + + struct PositionalDef { + // common + QString name; + QString doc; + QString metavar; + QVariant def; + // positional + bool required; + }; + + QHash<QString, OptionDef *> m_options; + QHash<QChar, OptionDef *> m_flags; + QHash<QString, CommonDef *> m_params; + QList<PositionalDef *> m_positionals; + QList<OptionDef *> m_optionList; + + void getPrefix(QString &opt, QString &flag); +}; + +} +} + +#endif // CMDUTILS_H |