diff --git a/doc/src/arg_parser.dox b/doc/src/arg_parser.dox index 87fa4e3..e3b9993 100644 --- a/doc/src/arg_parser.dox +++ b/doc/src/arg_parser.dox @@ -1,8 +1,9 @@ +namespace YYCC::ArgParser { /** \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, 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. 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(-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 m_IntArgument; + YYCC::ArgParser::NumberArgument m_FloatArgument; + YYCC::ArgParser::StringArgument m_StringArgument; + + YYCC::ArgParser::SwitchArgument m_BoolArgument; + YYCC::ArgParser::NumberArgument 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 \subsection arg_parser__argument__presets Argument Presets @@ -35,6 +84,18 @@ It can not hold any value. \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 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 -\code{sh} +\code{.sh} exec -l -s -h exec -lsh \endcode @@ -54,7 +115,7 @@ You must write these flags independently. \subsection arg_parser__limitation__equal_symbol Equal Symbol -\code +\code{.sh} 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 -\code +\code{.sh} exec -DSOME_VARABLE=SOME_VALUE exec -D SOME_VARIABLE=SOME_VALUE \endcode @@ -74,4 +135,22 @@ exec -D SOME_VARIABLE=SOME_VALUE Parser only accept second line. However you nned to write a custom argument or constraint to holding this value. -*/ \ No newline at end of file +\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. + +*/ +} \ No newline at end of file diff --git a/doc/src/config_manager.dox b/doc/src/config_manager.dox index d18c7aa..536f25c 100644 --- a/doc/src/config_manager.dox +++ b/doc/src/config_manager.dox @@ -1,8 +1,9 @@ +namespace YYCC::ConfigManager { /** \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. In following content, we will describe it in detail. @@ -32,11 +33,11 @@ public: YYCC::ConfigManager::CoreManager m_CoreManager; }; -// init cfg manager +// Initialize config manager TestConfigManager test; -// load string +// Load settings. test.m_CoreManager.Load() -// get string value +// Get string setting value. auto val = test.m_StringSetting.Get(); \endcode @@ -49,9 +50,9 @@ Each setting describe a single configuration entry. 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). -\li YYCC::ConfigManager::StringSetting: The setting storing a string inside. +\li StringSetting: The setting storing a string inside. When constructing these settings, 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. 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, -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 -YYCC::ConfigManager::CoreManager manage a collection of settings. +CoreManager manage a collection of settings. And have responsibility to reading and writing config file. 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. The last argument is an initializer list which contain the \b pointer to all settings this manager managed. -*/ \ No newline at end of file +*/ +} \ No newline at end of file diff --git a/doc/src/constraints.dox b/doc/src/constraints.dox index 2a5a639..90780f0 100644 --- a/doc/src/constraints.dox +++ b/doc/src/constraints.dox @@ -1,8 +1,9 @@ +namespace YYCC::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. 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 -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. 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. -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 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 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. There is a list of all provided functions: -\li YYCC::Constraints::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 YYCC::Constraints::GetStringEnumerationConstraint: Limit the string by given all possible value set. +\li GetMinMaxRangeConstraint(): Limit the number value in given minimum maximum value range (inclusive). +\li GetEnumEnumerationConstraint(): Limit the enum value by given all possible value set. +\li GetStringEnumerationConstraint(): Limit the string by given all possible value set. \subsection config_manager__constraint__custom Custom 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. The things you need to do is simple. -First, you need decide the template argument of YYCC::Constraints::Constraint. -Second, you need assign class member of YYCC::Constraints::Constraint by C++ lambda syntax. +First, you need decide the template argument of Constraint. +Second, you need assign class member of Constraint by C++ lambda syntax. -*/ \ No newline at end of file +*/ +} \ No newline at end of file diff --git a/doc/src/intro.dox b/doc/src/intro.dox index 86334af..63bf00e 100644 --- a/doc/src/intro.dox +++ b/doc/src/intro.dox @@ -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. 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). -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. 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. -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. All in all, programming on Windows is a tough work. diff --git a/src/Constraints.hpp b/src/Constraints.hpp index 9c132f7..2b879d4 100644 --- a/src/Constraints.hpp +++ b/src/Constraints.hpp @@ -14,7 +14,7 @@ namespace YYCC::Constraints { /** * @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 struct Constraint {