doc: update documentation

This commit is contained in:
yyc12345 2024-07-30 22:13:59 +08:00
parent e167479de3
commit 656495f22e
5 changed files with 112 additions and 29 deletions

View File

@ -1,8 +1,9 @@
namespace YYCC::ArgParser {
/** /**
\page arg_parser Universal Argument Parser \page arg_parser Universal Argument Parser
Universal argument parser provides an universal way to parsing command line arguments. YYCC::ArgParser provides an universal way to parsing command line arguments.
Universal argument parser has similar design with universal config manager, Universal argument parser has similar design with universal config manager,
it is highly recommand that read \ref config_manager chapter first, it is highly recommand that read \ref config_manager chapter first,
@ -11,6 +12,54 @@ because you will have a clear understanding of this namespace after reading univ
There is an example about how to use universal argument parser. There is an example about how to use universal argument parser.
In following content, we will describe it in detail. In following content, we will describe it in detail.
\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.
\section arg_parser__argument Argument \section arg_parser__argument Argument
\subsection arg_parser__argument__presets Argument Presets \subsection arg_parser__argument__presets Argument Presets
@ -35,6 +84,18 @@ It can not hold any value.
\section arg_parser__option_context Option Context \section arg_parser__option_context Option Context
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).
\section arg_parser__limitation Limitation \section arg_parser__limitation Limitation
This universal argument parser is a tiny parser. This universal argument parser is a tiny parser.
@ -44,7 +105,7 @@ In following content I will tell you some syntaxes which this parser \b not acce
\subsection arg_parser__limitation__flag_combination Flag Combination \subsection arg_parser__limitation__flag_combination Flag Combination
\code{sh} \code{.sh}
exec -l -s -h exec -l -s -h
exec -lsh exec -lsh
\endcode \endcode
@ -54,7 +115,7 @@ You must write these flags independently.
\subsection arg_parser__limitation__equal_symbol Equal Symbol \subsection arg_parser__limitation__equal_symbol Equal Symbol
\code \code{.sh}
exec --value 114514 exec --value 114514
exec --value=114514 exec --value=114514
exec --value:114514 exec --value:114514
@ -66,7 +127,7 @@ You must write value after the argument immediately please.
\subsection arg_parser__limitation__variable_argument Variable Argument \subsection arg_parser__limitation__variable_argument Variable Argument
\code \code{.sh}
exec -DSOME_VARABLE=SOME_VALUE exec -DSOME_VARABLE=SOME_VALUE
exec -D SOME_VARIABLE=SOME_VALUE exec -D SOME_VARIABLE=SOME_VALUE
\endcode \endcode
@ -74,4 +135,22 @@ exec -D SOME_VARIABLE=SOME_VALUE
Parser only accept second line. Parser only accept second line.
However you nned to write a custom argument or constraint to holding this value. However you nned to write a custom argument or constraint to holding this value.
*/ \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.
*/
}

View File

@ -1,8 +1,9 @@
namespace YYCC::ConfigManager {
/** /**
\page config_manager Universal Config Manager \page config_manager Universal Config Manager
Universal config manager give programmer an universal way to manage its program settings. YYCC::ConfigManager give programmer an universal way to manage its program settings.
There is an example about how to use universal config manager. There is an example about how to use universal config manager.
In following content, we will describe it in detail. In following content, we will describe it in detail.
@ -32,11 +33,11 @@ public:
YYCC::ConfigManager::CoreManager m_CoreManager; YYCC::ConfigManager::CoreManager m_CoreManager;
}; };
// init cfg manager // Initialize config manager
TestConfigManager test; TestConfigManager test;
// load string // Load settings.
test.m_CoreManager.Load() test.m_CoreManager.Load()
// get string value // Get string setting value.
auto val = test.m_StringSetting.Get(); auto val = test.m_StringSetting.Get();
\endcode \endcode
@ -49,9 +50,9 @@ Each setting describe a single configuration entry.
We currently provide 2 setting preset classes which you can directly use. We currently provide 2 setting preset classes which you can directly use.
\li YYCC::ConfigManager::NumberSetting: The setting storing a number inside. \li NumberSetting: The setting storing a number inside.
It is a template class. Support all arithmetic and enum types (integral, floating point, bool, enum). It is a template class. Support all arithmetic and enum types (integral, floating point, bool, enum).
\li YYCC::ConfigManager::StringSetting: The setting storing a string inside. \li StringSetting: The setting storing a string inside.
When constructing these settings, When constructing these settings,
you need to provide its unique name which will be used when saving to file or reading from file. you need to provide its unique name which will be used when saving to file or reading from file.
@ -67,13 +68,13 @@ See \ref constraints chapters to know how we provide constraints.
In most cases, the combination use of setting presets and constraints is enough. In most cases, the combination use of setting presets and constraints is enough.
However, if you still are urge to create your personal setting, However, if you still are urge to create your personal setting,
please inherit YYCC::ConfigManager::AbstractSetting and implement essential class functions. please inherit AbstractSetting and implement essential class functions.
For the class functions you need to implement, For the class functions you need to implement,
please refer to our setting presets, YYCC::ConfigManager::NumberSetting and YYCC::ConfigManager::StringSetting. please refer to our setting presets, NumberSetting and StringSetting.
\section config_manager__core_manager Core Manager \section config_manager__core_manager Core Manager
YYCC::ConfigManager::CoreManager manage a collection of settings. CoreManager manage a collection of settings.
And have responsibility to reading and writing config file. And have responsibility to reading and writing config file.
We highly suggest that you create a personal config manager class like example does. We highly suggest that you create a personal config manager class like example does.
@ -92,4 +93,5 @@ Core manager will reject reading and use default value for all settings.
Otherwise, core manager will try to read config file and do proper migration if possible. Otherwise, core manager will try to read config file and do proper migration if possible.
The last argument is an initializer list which contain the \b pointer to all settings this manager managed. The last argument is an initializer list which contain the \b pointer to all settings this manager managed.
*/ */
}

View File

@ -1,8 +1,9 @@
namespace YYCC::Constraints {
/** /**
\page constraints Constraints \page constraints Constraints
YYCC::Constraints namespace provide YYCC::Constraints::Constraint struct declaration YYCC::Constraints namespace provide Constraint struct declaration
and various common constraint generator function. and various common constraint generator function.
This namespace is specifically used by YYCC::ConfigManager and YYCC::ArgParser namespaces. This namespace is specifically used by YYCC::ConfigManager and YYCC::ArgParser namespaces.
@ -10,12 +11,12 @@ See \ref config_manager chapter and \ref arg_parser chapter for how to utlize th
\section constraints__prototype Prototype \section constraints__prototype Prototype
YYCC::Constraints::Constraint instruct library how check whether given value is in range, Constraint instruct library how check whether given value is in range,
and how to clamp it if it is invalid. and how to clamp it if it is invalid.
For example, you can use constraint to limit a number in given minimum maximum value, For example, you can use constraint to limit a number in given minimum maximum value,
or limit a string in specific format by using regex and etc. or limit a string in specific format by using regex and etc.
YYCC::Constraints::Constraint is a template struct. Constraint is a template struct.
The argument of template is the underlying data type which need to be checked. The argument of template is the underlying data type which need to be checked.
The struct with different template argument is not compatible. The struct with different template argument is not compatible.
@ -25,23 +26,24 @@ which is used for detecting whether given value is in range / valid.
\subsection constraints__presets Constraint Presets \subsection constraints__presets Constraint Presets
YYCC::Constraints provides some constraint presets which are commonly used. YYCC::Constraints provides some constraint presets which are commonly used.
All functions inside this namespace will return a YYCC::Constraints::Constraint instance, All functions inside this namespace will return a Constraint instance,
and you can directly use it. and you can directly use it.
There is a list of all provided functions: There is a list of all provided functions:
\li YYCC::Constraints::GetMinMaxRangeConstraint: Limit the number value in given minimum maximum value range (inclusive). \li GetMinMaxRangeConstraint(): Limit the number value in given minimum maximum value range (inclusive).
\li YYCC::Constraints::GetEnumEnumerationConstraint: Limit the enum value by given all possible value set. \li GetEnumEnumerationConstraint(): Limit the enum value by given all possible value set.
\li YYCC::Constraints::GetStringEnumerationConstraint: Limit the string by given all possible value set. \li GetStringEnumerationConstraint(): Limit the string by given all possible value set.
\subsection config_manager__constraint__custom Custom Constraint \subsection config_manager__constraint__custom Custom Constraint
For creating your personal constraint, For creating your personal constraint,
you need to create YYCC::Constraints::Constraint instance manually. you need to create Constraint instance manually.
You can browse all existing constraint preset functions code for know how to write it. You can browse all existing constraint preset functions code for know how to write it.
The things you need to do is simple. The things you need to do is simple.
First, you need decide the template argument of YYCC::Constraints::Constraint. First, you need decide the template argument of Constraint.
Second, you need assign class member of YYCC::Constraints::Constraint by C++ lambda syntax. Second, you need assign class member of Constraint by C++ lambda syntax.
*/ */
}

View File

@ -29,12 +29,12 @@ During programming, I found Windows is super lack in UTF8 supports.
Programmer loves UTF8, because it can handle all charcaters over the world in one encoding and is still compatible with C-Style string. Programmer loves UTF8, because it can handle all charcaters over the world in one encoding and is still compatible with C-Style string.
However, Windows use a weird way to achieve internationalization, 2 different function trailing, A and W for legacy code and modern code respectively. However, Windows use a weird way to achieve internationalization, 2 different function trailing, A and W for legacy code and modern code respectively.
The worst things is that the char type W trailing function used, \c WCHAR, is defined as 2 bytes long, not 4 bytes long as Linux does (\c wchar_t). The worst things is that the char type W trailing function used, \c WCHAR, is defined as 2 bytes long, not 4 bytes long as Linux does (\c wchar_t).
It mean that one emoji charcater will be torn into 2 \c WCHAR on Windows because emoji code unit is higher than the manimum value of \c WCHAR. It mean that one emoji charcater will be torn into 2 \c WCHAR on Windows because emoji code unit is higher than the maximum value of \c WCHAR.
Also, there are various issues which should not be presented. Also, there are various issues which should not be presented.
For example, Microsoft invents various \e safe standard library functions to prevent possible overflow issues raised by \c std::fgets and etc. For example, Microsoft invents various \e safe standard library functions to prevent possible overflow issues raised by \c std::fgets and etc.
also, MSVC may throw weird error when you using some specific standard library functions. also, MSVC may throw weird error when you using some specific standard library functions.
You need to define some weird macro to disable this shitty behavior. You need to define some weird macros to disable this shitty behavior.
There are various non-standard issue you may faced on Windows programming. There are various non-standard issue you may faced on Windows programming.
All in all, programming on Windows is a tough work. All in all, programming on Windows is a tough work.

View File

@ -14,7 +14,7 @@ namespace YYCC::Constraints {
/** /**
* @brief The constraint applied to settings to limit its stored value. * @brief The constraint applied to settings to limit its stored value.
* @tparam _Ty The internal data type stroed in corresponding setting. * @tparam _Ty The data type this constraint need to be processed with.
*/ */
template<typename _Ty> template<typename _Ty>
struct Constraint { struct Constraint {