2024-07-30 22:13:59 +08:00
|
|
|
namespace YYCC::ArgParser {
|
2024-07-30 10:35:41 +08:00
|
|
|
/**
|
|
|
|
|
|
|
|
\page arg_parser Universal Argument Parser
|
|
|
|
|
2024-07-30 22:13:59 +08:00
|
|
|
YYCC::ArgParser provides an universal way to parsing command line arguments.
|
2024-07-30 10:35:41 +08:00
|
|
|
|
2024-07-30 17:31:38 +08:00
|
|
|
Universal argument parser has similar design with universal config manager,
|
|
|
|
it is highly recommand that read \ref config_manager chapter first,
|
|
|
|
because you will have a clear understanding of this namespace after reading universal config manager chapter.
|
2024-07-30 10:35:41 +08:00
|
|
|
|
2024-07-30 17:31:38 +08:00
|
|
|
There is an example about how to use universal argument parser.
|
|
|
|
In following content, we will describe it in detail.
|
|
|
|
|
2024-07-30 22:13:59 +08:00
|
|
|
\code{.cpp}
|
|
|
|
class TestArgParser {
|
|
|
|
public:
|
|
|
|
TestArgParser() :
|
|
|
|
m_IntArgument(YYCC_U8("int"), YYCC_U8_CHAR('i'), YYCC_U8("integral argument"), YYCC_U8("114514")),
|
|
|
|
m_FloatArgument(nullptr, YYCC_U8_CHAR('f'), nullptr, nullptr, true),
|
|
|
|
m_StringArgument(YYCC_U8("string"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true),
|
|
|
|
m_BoolArgument(nullptr, YYCC_U8_CHAR('b'), nullptr),
|
|
|
|
m_ClampedFloatArgument(YYCC_U8("clamped-float"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true, YYCC::Constraints::GetMinMaxRangeConstraint<float>(-1.0f, 1.0f)),
|
|
|
|
m_OptionContext(YYCC_U8("TestArgParser"), YYCC_U8("This is the testbench of argument parser."), {
|
|
|
|
&m_IntArgument, &m_FloatArgument, &m_StringArgument,
|
|
|
|
&m_BoolArgument, &m_ClampedFloatArgument
|
|
|
|
}) {}
|
|
|
|
~TestArgParser() {}
|
|
|
|
|
|
|
|
YYCC::ArgParser::NumberArgument<int32_t> m_IntArgument;
|
|
|
|
YYCC::ArgParser::NumberArgument<float> m_FloatArgument;
|
|
|
|
YYCC::ArgParser::StringArgument m_StringArgument;
|
|
|
|
|
|
|
|
YYCC::ArgParser::SwitchArgument m_BoolArgument;
|
|
|
|
YYCC::ArgParser::NumberArgument<float> m_ClampedFloatArgument;
|
|
|
|
|
|
|
|
YYCC::ArgParser::OptionContext m_OptionContext;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Initialize argument parser.
|
|
|
|
TestArgParser test;
|
|
|
|
// Get argument list for parsing from standard C main function.
|
|
|
|
auto al = YYCC::ArgParser::ArgumentList::CreateFromStd(argc, argv);
|
|
|
|
// Start parsing
|
|
|
|
test.Parse(al);
|
|
|
|
// Get captured string argument
|
|
|
|
if (test.m_StringArgument.IsCaptured())
|
|
|
|
auto val = test.m_StringArgument.Get();
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
These code can resolve following command line
|
|
|
|
|
|
|
|
\code{.sh}
|
|
|
|
exec -i 114514 -f 2.0 --string fuck -b --clamped-float 0.5
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
For convenience, we define following terms used in this article.
|
|
|
|
|
|
|
|
\li Every items in command line: Argument.
|
|
|
|
\li \c -i, \c --clamped-float: \b Switch / \b Option. the argument starts with dash or double dash.
|
|
|
|
\li \c 114514: \b Value. the value of switch.
|
|
|
|
|
2024-07-30 17:31:38 +08:00
|
|
|
\section arg_parser__argument Argument
|
|
|
|
|
|
|
|
\subsection arg_parser__argument__presets Argument Presets
|
|
|
|
|
|
|
|
\subsubsection arg_parser__argument__presets__number Number Argument
|
|
|
|
|
|
|
|
\subsubsection arg_parser__argument__presets__string String Argument
|
|
|
|
|
|
|
|
\subsubsection arg_parser__argument__presets__switch Switch Argument
|
|
|
|
|
|
|
|
Switch argument must be optional argument.
|
|
|
|
Because it is true if user specify it explicit it,
|
|
|
|
and will be false if user do not give this flag.
|
|
|
|
|
|
|
|
Switch argument also doesn't contain any value.
|
|
|
|
Because it is just a switch.
|
|
|
|
It can not hold any value.
|
|
|
|
|
|
|
|
\subsection arg_parser__argument__custom Custom Argument
|
|
|
|
|
|
|
|
\section arg_parser__argument_list Argument List
|
|
|
|
|
|
|
|
\section arg_parser__option_context Option Context
|
|
|
|
|
2024-07-30 22:13:59 +08:00
|
|
|
Please note any unknow argument will let the parser return false.
|
|
|
|
This is different with other argument parsers.
|
|
|
|
In other common argument parsers,
|
|
|
|
they will collect all unknow argument ad positional argument,
|
|
|
|
or just simply ignore them.
|
|
|
|
|
|
|
|
OptionContext also will not add \c -h or \c --help switch automatically.
|
|
|
|
This is also differnent with other parsers.
|
|
|
|
You should manually add it.
|
|
|
|
However, OptionContext provide a universal help print function.
|
|
|
|
You can directly call it to output help text if you needed (fail to parse or user order help).
|
|
|
|
|
2024-07-30 17:31:38 +08:00
|
|
|
\section arg_parser__limitation Limitation
|
|
|
|
|
|
|
|
This universal argument parser is a tiny parser.
|
|
|
|
It only just fulfill my personal requirements.
|
|
|
|
So it only accepts limited command line syntax.
|
|
|
|
In following content I will tell you some syntaxes which this parser \b not accept.
|
|
|
|
|
|
|
|
\subsection arg_parser__limitation__flag_combination Flag Combination
|
|
|
|
|
2024-07-30 22:13:59 +08:00
|
|
|
\code{.sh}
|
2024-07-30 17:31:38 +08:00
|
|
|
exec -l -s -h
|
|
|
|
exec -lsh
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
Parser accept first line but not accept the second line.
|
|
|
|
You must write these flags independently.
|
|
|
|
|
|
|
|
\subsection arg_parser__limitation__equal_symbol Equal Symbol
|
|
|
|
|
2024-07-30 22:13:59 +08:00
|
|
|
\code{.sh}
|
2024-07-30 17:31:38 +08:00
|
|
|
exec --value 114514
|
|
|
|
exec --value=114514
|
|
|
|
exec --value:114514
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
Parser only accept first line command.
|
|
|
|
You can not use equal symbol or any other symbol to assign value for specified argument.
|
|
|
|
You must write value after the argument immediately please.
|
|
|
|
|
|
|
|
\subsection arg_parser__limitation__variable_argument Variable Argument
|
|
|
|
|
2024-07-30 22:13:59 +08:00
|
|
|
\code{.sh}
|
2024-07-30 17:31:38 +08:00
|
|
|
exec -DSOME_VARABLE=SOME_VALUE
|
|
|
|
exec -D SOME_VARIABLE=SOME_VALUE
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
Parser only accept second line.
|
|
|
|
However you nned to write a custom argument or constraint to holding this value.
|
2024-07-30 10:35:41 +08:00
|
|
|
|
2024-07-30 22:13:59 +08:00
|
|
|
\subsection arg_parser__limitation__switch_dependency Switch Dependency
|
|
|
|
|
|
|
|
\code{.sh}
|
|
|
|
exec --action-a --action-b
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
For command line written above,
|
|
|
|
if you hope \c --action-a and \c --action-b is exclusive,
|
|
|
|
or \c --action-b only be valid if \c --action-a specified,
|
|
|
|
you should manually implement this.
|
|
|
|
Parser don't have such features to process this switch dependency.
|
|
|
|
|
|
|
|
The thing you need to do is set these switches are \b not optional.
|
|
|
|
And after parser do a success parsing,
|
|
|
|
manually calling AbstractArgument::IsCaptured to fetch whether corresponding switches are captured,
|
|
|
|
then do your personal dependency check.
|
|
|
|
|
|
|
|
*/
|
|
|
|
}
|