2013-02-20 04:37:52 +05:30
|
|
|
/* 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>
|
|
|
|
|
2013-02-26 02:14:36 +05:30
|
|
|
#include "libutil_config.h"
|
|
|
|
|
2013-02-20 04:37:52 +05:30
|
|
|
/**
|
2013-02-22 01:10:32 +05:30
|
|
|
* @file libutil/include/cmdutils.h
|
2013-02-20 04:37:52 +05:30
|
|
|
* @brief commandline parsing utilities
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Util {
|
|
|
|
namespace Commandline {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The FlagStyle enum
|
|
|
|
* Specifies how flags are decorated
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
|
|
|
|
namespace FlagStyle
|
|
|
|
{
|
2013-02-27 04:17:39 +05:30
|
|
|
enum LIBUTIL_EXPORT Enum
|
2013-02-26 02:14:36 +05:30
|
|
|
{
|
2013-02-26 01:09:07 +05:30
|
|
|
GNU, /**< --option and -o (GNU Style) */
|
|
|
|
Unix, /**< -option and -o (Unix Style) */
|
|
|
|
Windows, /**< /option and /o (Windows Style) */
|
2013-02-20 04:37:52 +05:30
|
|
|
#ifdef Q_OS_WIN32
|
2013-02-26 01:09:07 +05:30
|
|
|
Default = Windows
|
2013-02-20 04:37:52 +05:30
|
|
|
#else
|
2013-02-26 01:09:07 +05:30
|
|
|
Default = GNU
|
2013-02-20 04:37:52 +05:30
|
|
|
#endif
|
|
|
|
};
|
2013-02-26 02:14:36 +05:30
|
|
|
}
|
2013-02-20 04:37:52 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The ArgumentStyle enum
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
namespace ArgumentStyle
|
|
|
|
{
|
2013-02-27 04:17:39 +05:30
|
|
|
enum LIBUTIL_EXPORT Enum
|
2013-02-26 02:14:36 +05:30
|
|
|
{
|
2013-02-26 01:09:07 +05:30
|
|
|
Space, /**< --option=value */
|
|
|
|
Equals, /**< --option value */
|
|
|
|
SpaceAndEquals, /**< --option[= ]value */
|
2013-02-20 04:37:52 +05:30
|
|
|
#ifdef Q_OS_WIN32
|
2013-02-26 01:09:07 +05:30
|
|
|
Default = Equals
|
2013-02-20 04:37:52 +05:30
|
|
|
#else
|
2013-02-26 01:09:07 +05:30
|
|
|
Default = SpaceAndEquals
|
2013-02-20 04:37:52 +05:30
|
|
|
#endif
|
|
|
|
};
|
2013-02-26 02:14:36 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
namespace OptionType
|
|
|
|
{
|
2013-02-27 04:17:39 +05:30
|
|
|
enum LIBUTIL_EXPORT Enum
|
2013-02-26 02:14:36 +05:30
|
|
|
{
|
|
|
|
Switch,
|
|
|
|
Option
|
|
|
|
};
|
|
|
|
}
|
2013-02-20 04:37:52 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The ParsingError class
|
|
|
|
*/
|
2013-02-27 04:17:39 +05:30
|
|
|
class LIBUTIL_EXPORT ParsingError : public std::exception
|
2013-02-20 04:37:52 +05:30
|
|
|
{
|
|
|
|
public:
|
2013-02-26 01:09:07 +05:30
|
|
|
ParsingError(const QString &what);
|
|
|
|
ParsingError(const ParsingError &e);
|
|
|
|
~ParsingError() throw() {}
|
|
|
|
const char *what() const throw();
|
|
|
|
QString qwhat() const;
|
2013-02-20 04:37:52 +05:30
|
|
|
private:
|
2013-02-26 01:09:07 +05:30
|
|
|
QString m_what;
|
2013-02-20 04:37:52 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The Parser class
|
|
|
|
*/
|
2013-02-27 04:17:39 +05:30
|
|
|
class LIBUTIL_EXPORT Parser
|
2013-02-20 04:37:52 +05:30
|
|
|
{
|
|
|
|
public:
|
2013-02-26 01:09:07 +05:30
|
|
|
/**
|
|
|
|
* @brief Parser constructor
|
|
|
|
* @param flagStyle the FlagStyle to use in this Parser
|
|
|
|
* @param argStyle the ArgumentStyle to use in this Parser
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
Parser(FlagStyle::Enum flagStyle = FlagStyle::Default,
|
|
|
|
ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief set the flag style
|
|
|
|
* @param style
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
void setFlagStyle(FlagStyle::Enum style);
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief get the flag style
|
|
|
|
* @return
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
FlagStyle::Enum flagStyle();
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief set the argument style
|
|
|
|
* @param style
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
void setArgumentStyle(ArgumentStyle::Enum style);
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief get the argument style
|
|
|
|
* @return
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
ArgumentStyle::Enum argumentStyle();
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief define a boolean switch
|
|
|
|
* @param name the parameter name
|
|
|
|
* @param def the default value
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
void addSwitch(QString name, bool def = false);
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief define an option that takes an additional argument
|
|
|
|
* @param name the parameter name
|
|
|
|
* @param def the default value
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
void addOption(QString name, QVariant def = QVariant());
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief define a positional argument
|
|
|
|
* @param name the parameter name
|
|
|
|
* @param required wether this argument is required
|
|
|
|
* @param def the default value
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
void addArgument(QString name, bool required = true, QVariant def = QVariant());
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
* Note: on positional arguments, metavar replaces the name as displayed.
|
|
|
|
* on options , metavar replaces the value placeholder
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
void addDocumentation(QString name, QString doc, QString metavar = QString());
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
2013-02-26 02:14:36 +05:30
|
|
|
QString compileUsage(QString progName, bool useFlags = true);
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief clear all definitions
|
|
|
|
*/
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
~Parser();
|
|
|
|
|
2013-02-20 04:37:52 +05:30
|
|
|
private:
|
2013-02-26 02:14:36 +05:30
|
|
|
FlagStyle::Enum m_flagStyle;
|
|
|
|
ArgumentStyle::Enum m_argStyle;
|
2013-02-26 01:09:07 +05:30
|
|
|
|
|
|
|
// 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
|
2013-02-26 02:14:36 +05:30
|
|
|
OptionType::Enum type;
|
2013-02-26 01:09:07 +05:30
|
|
|
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);
|
2013-02-20 04:37:52 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // CMDUTILS_H
|