libGimbal 0.2.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_cmd_parser.h
Go to the documentation of this file.
1/*! \file
2 * \brief Modular command-line argument parser
3 * \ingroup utils
4 *
5 * \todo More descriptive errors and version options,
6 * use virtual methods for customization points,
7 * implement signals for events (probably),
8 * process(..) top-level method for handling exiting
9 * upon failure, version, or help.
10 *
11 * \author 2023, 2026 Falco Girgis
12 * \author 2026 Agustín Bellagamba
13 * \copyright MIT License
14 */
15#ifndef GIMBAL_CMD_PARSER_H
16#define GIMBAL_CMD_PARSER_H
17
19#include "../strings/gimbal_string_buffer.h"
20
21/*! \name Type System
22 * \brief Type UUID and cast operators
23 * @{
24 */
25#define GBL_CMD_PARSER_TYPE (GBL_TYPEID(GblCmdParser)) //!< Type UUID of GblCmdParser
26#define GBL_CMD_PARSER(self) (GBL_CAST(GblCmdParser, self)) //!< Function-style GblInstance cast
27#define GBL_CMD_PARSER_CLASS(klass) (GBL_CLASS_CAST(GblCmdParser, klass)) //!< Function-style GblClass cast
28#define GBL_CMD_PARSER_CLASSOF(self) (GBL_CLASSOF(GblCmdParser, self)) //!< Get a GblCmdParserClass from GblInstance
29//! @}
30
31#define GBL_SELF_TYPE GblCmdParser
32
34
35GBL_FORWARD_DECLARE_STRUCT(GblCmdParser);
36
37//! Attributes of a single command-line argument
38typedef struct GblCmdArg {
39 GblStringRef* pName; //!< Name of the command-line argument
40 GblStringRef* pDesc; //!< Description of the command-line argument
41} GblCmdArg;
42
43/*! \struct GblCmdParserClass
44 * \extends GblObjectClass
45 * \brief GblClass for GblCmdParser
46 *
47 * GblCmdParserClass offers a polymorphic virtual table
48 * for processing command-line arguments.
49 *
50 * \sa GblCmdParser
51 */
52GBL_CLASS_DERIVE(GblCmdParser, GblObject)
53 //! Parses the command given by \p cmd and returns a GBL_RESULT code
54 GBL_RESULT (*pFnParse) (GBL_SELF,
55 GblStringView cmd);
56 //! Checks to see if unknown command-line option values can be used, returning number used
57 GBL_RESULT (*pFnTryUnknownOption)(GBL_SELF,
58 GblStringView key,
59 GblStringView value,
60 size_t* pUsed);
62
63/*! \struct GblCmdParser
64 * \extends GblObject
65 * \ingroup utils
66 * \brief General-purpose command-line argument parser
67 *
68 * GblCmdParser is a configurable, modular, generalized
69 * parser for processing command-line arguments. A
70 * parser may contain a single "main" option group and
71 * a collection of secondary option groups.
72 * This modularity allows each library or framework
73 * within an application to add its own individual option
74 * group to the main command parser.
75 *
76 * \sa GblOptionGroup
77 */
79 GblStringRef* pErrorMsg; //!< Current, pending error message
80 GBL_RESULT parseResult; //!< Result of last parse operation
81 uint8_t allowExtraArgs : 1; //!< Toggle for allowing extra positional arguments beyond the ones added
82 uint8_t allowUnknownOptions : 1; //!< Toggle for allowing unknown options not handled by a GblCmdOptionGroup
83 uint8_t firstArgAsExecutable : 1; //!< Toggle for determining whether to treat the first argument as the executable name
84 uint8_t enableVersionOption : 1; //!< Toggle for optionally enabling a version command-line option
85 uint8_t enableHelpOption : 1; //!< Toggle for optionally enabling an autogenerated help option
87
88//! \cond
89GBL_PROPERTIES(GblCmdParser,
90 (allowExtraArgs, GBL_GENERIC, (READ, WRITE), GBL_BOOL_TYPE),
91 (allowUnknownOptions, GBL_GENERIC, (READ, WRITE), GBL_BOOL_TYPE),
92 (firstArgAsExecutable, GBL_GENERIC, (READ, WRITE), GBL_BOOL_TYPE),
93 (enableVersionOption, GBL_GENERIC, (READ, WRITE), GBL_BOOL_TYPE),
94 (enableHelpOption, GBL_GENERIC, (READ, WRITE), GBL_BOOL_TYPE),
95 (mainOptionGroup, GBL_GENERIC, (READ, WRITE, ACQUIRE, RELEASE), GBL_OPTION_GROUP_TYPE),
96 (optionGroups, GBL_GENERIC, (READ, WRITE, ACQUIRE, RELEASE), GBL_RING_LIST_TYPE),
97 (positionalArgs, GBL_GENERIC, (READ, WRITE, ACQUIRE, RELEASE), GBL_RING_LIST_TYPE)
98)
99
100GBL_SIGNALS(GblCmdParser,
101 (parsePrePass, (GBL_INSTANCE_TYPE, pReceiver), (GBL_POINTER_TYPE, pInitialArgs)),
102 (parsePostPass, (GBL_INSTANCE_TYPE, pReceiver), (GBL_POINTER_TYPE, pRemainingArgs)),
103 (parseExtraArgs, (GBL_INSTANCE_TYPE, pReceiver), (GBL_POINTER_TYPE, pExtraArgs)),
104 (parseUnknownOptions, (GBL_INSTANCE_TYPE, pReceiver), (GBL_POINTER_TYPE, pRemaininArgs)),
105 (parseError, (GBL_INSTANCE_TYPE, pReceiver), (GBL_ENUM_TYPE, errorCode))
106)
107//! \endcond
108
109//! Returns the GblType UUID associated with GblCmdParser
111
112/*! \name Lifetime Management
113 * \brief Methods for controlling lifetime of a GblCmdParser
114 * @{
115 */
116//! Creates a GblCmdParser object, initializes it, and returns a pointer to it
118//! Unreferences a GblCmdParser, destroying it if it's the last one, returning the remaining reference count
120//! @}
121
122/*! \name Option Groups
123 * \brief Methods for managing GblCmdOptionGroup subobjects
124 * \relatesalso GblCmdParser
125 * @{
126 */
127//! Adds the GblOptionGroup \p pGroup to the list of option groups handled by the GblCmdParser
129 GblOptionGroup* pGroup) GBL_NOEXCEPT;
130//! Replaces option groups from a borrowed ring list, reusing existing references and acquiring ownership of new ones
132 const GblRingList* pGroups) GBL_NOEXCEPT;
133//! Returns a pointer to the GblOptionGroup at the given index
135//! Finds a GblOptionGroup from the internal list by its GblObject::name.
137 const char* pName) GBL_NOEXCEPT;
138//! Returns the number of option groups held within the internal list of them
140//! Sets the main option group for the parser to the one given by \p pGroup, returning the result
142 GblOptionGroup* pGroup) GBL_NOEXCEPT;
143//! Returns the GblOptionGroup previously set as the main option group for the GblCmdParser
145//! @}
146
147/*! \name Positional Arguments
148 * \brief Methods for managing positional arguments
149 * \relatesalso GblCmdParser
150 * @{
151 */
152//! Dynamically creates a GblCmdArg struct from the given args and adds it to the internal list
154 const char* pName,
155 const char* pDesc) GBL_NOEXCEPT;
156//! Replaces positional arguments by copying the GblCmdArg entries from a borrowed ring list
158 const GblRingList* pArgs) GBL_NOEXCEPT;
159//! Clears the currently held internal list of GblCmdArg structures, resetting its size to 0
161//! Returns the size of the internally managed list of GblCmdArg structures represengin command-line arguments
163//! Returns a pointer to the GblCmdArg structure in the internally maintained list at the given index
165//! After parsing, this function returns the number of positional arguments extracted
167//! After parsing, returns the GblStringList maintained internally, containing the extracted positional argument values
169//! After parsing, this function converts the value of the argument at the given \p index to the desired \p toType, copying its value to \p pData, and returning the result
171 size_t index,
172 GblType toType,
173 void* pData) GBL_NOEXCEPT;
174//! @}
175
176/*! \name Parsing
177 * \brief Methods for parsing arguments or managing parsed values
178 * @{
179 */
180//! After parsing, returns a GblStringRef to the name of the current executable (first positional argument)
182//! After parsing, retuns a GblStringList to the internally maintained list of unknown command-line options
184//! Returns whether the last parse requested --help or -h, so the caller can display help and skip execution
186//! Replaces a constructed buffer with help generated from option groups and positional arguments
188 GblStringBuffer* pBuffer) GBL_NOEXCEPT;
189//! Parses the list of arguments given by \p pArgs, populating internal structures, and returning the result
192//! @}
193
195
196#undef GBL_SELF_TYPE
197
198#endif // GIMBAL_CMD_PARSER_H
GblBool GblCmdParser_helpRequested(const GblCmdParser *pSelf)
Returns whether the last parse requested –help or -h, so the caller can display help and skip executi...
const GblStringList * GblCmdParser_unknownOptions(const GblCmdParser *pSelf)
After parsing, retuns a GblStringList to the internally maintained list of unknown command-line optio...
GBL_RESULT GblCmdParser_formatHelp(const GblCmdParser *pSelf, GblStringBuffer *pBuffer)
Replaces a constructed buffer with help generated from option groups and positional arguments.
GblStringRef * GblCmdParser_executable(const GblCmdParser *pSelf)
After parsing, returns a GblStringRef to the name of the current executable (first positional argumen...
GBL_RESULT GblCmdParser_parse(GblCmdParser *pSelf, GblStringList *pArgs)
Parses the list of arguments given by pArgs, populating internal structures, and returning the result...
GblCmdParser * GblCmdParser_create(void)
Creates a GblCmdParser object, initializes it, and returns a pointer to it.
GblRefCount GblCmdParser_unref(GblCmdParser *pSelf)
Unreferences a GblCmdParser, destroying it if it's the last one, returning the remaining reference co...
GblType GblCmdParser_type(void)
Returns the GblType UUID associated with GblCmdParser.
#define GBL_NOEXCEPT
#define GBL_DECLS_BEGIN
#define GBL_FORWARD_DECLARE_STRUCT(S)
#define GBL_TYPEID(instanceStruct)
#define GBL_INSTANCE_DERIVE(derivedInstance, baseInstance)
#define GBL_CLASS_DERIVE(...)
#define GBL_INSTANCE_END
#define GBL_EXPORT
#define GBL_CLASS_END
#define GBL_OPTION_GROUP_TYPE
Type UUID for GblOptionGroup.
#define GBL_BOOL_TYPE
Builtin ID for boolean GblVariant type.
#define GBL_PROPERTIES(object,...)
Declares a list of properties for the given object/instance structure.
#define GBL_RING_LIST_TYPE
Type UUID for GblRingList.
#define GBL_SIGNALS(instanceStruct,...)
Declares a list of signals to be associated with the given instanceStruct.
uint8_t GblBool
Basic boolean type, standardized to sizeof(char)
uint16_t GblRefCount
Type able to hold a reference counter across the codebase.
uintptr_t GblType
Meta Type UUID.
Definition gimbal_type.h:52
GblRingList GblStringList
List of strings with array-like API.
const char GblStringRef
Reference-counted, const char*-compatible string type.
Attributes of a single command-line argument.
GblStringRef * pName
Name of the command-line argument.
GblStringRef * pDesc
Description of the command-line argument.
General-purpose command-line argument parser.
size_t GblCmdParser_positionalArgValueCount(const GblCmdParser *pSelf)
After parsing, this function returns the number of positional arguments extracted.
const GblStringList * GblCmdParser_positionalArgValues(const GblCmdParser *pSelf)
After parsing, returns the GblStringList maintained internally, containing the extracted positional a...
GBL_RESULT GblCmdParser_setOptionGroups(GblCmdParser *pSelf, const GblRingList *pGroups)
Replaces option groups from a borrowed ring list, reusing existing references and acquiring ownership...
GblOptionGroup * GblCmdParser_optionGroup(const GblCmdParser *pSelf, size_t idx)
Returns a pointer to the GblOptionGroup at the given index.
uint8_t firstArgAsExecutable
Toggle for determining whether to treat the first argument as the executable name.
GblOptionGroup * GblCmdParser_mainOptionGroup(const GblCmdParser *pSelf)
Returns the GblOptionGroup previously set as the main option group for the GblCmdParser.
GBL_RESULT GblCmdParser_addPositionalArg(GblCmdParser *pSelf, const char *pName, const char *pDesc)
Dynamically creates a GblCmdArg struct from the given args and adds it to the internal list.
GBL_RESULT GblCmdParser_positionalArgValue(const GblCmdParser *pSelf, size_t index, GblType toType, void *pData)
After parsing, this function converts the value of the argument at the given index to the desired toT...
size_t GblCmdParser_optionGroupCount(const GblCmdParser *pSelf)
Returns the number of option groups held within the internal list of them.
GBL_RESULT GblCmdParser_clearPositionalArgs(GblCmdParser *pSelf)
Clears the currently held internal list of GblCmdArg structures, resetting its size to 0.
GBL_RESULT GblCmdParser_setPositionalArgs(GblCmdParser *pSelf, const GblRingList *pArgs)
Replaces positional arguments by copying the GblCmdArg entries from a borrowed ring list.
GBL_RESULT parseResult
Result of last parse operation.
GBL_RESULT GblCmdParser_addOptionGroup(GblCmdParser *pSelf, GblOptionGroup *pGroup)
Adds the GblOptionGroup pGroup to the list of option groups handled by the GblCmdParser.
size_t GblCmdParser_positionalArgCount(const GblCmdParser *pSelf)
Returns the size of the internally managed list of GblCmdArg structures represengin command-line argu...
GblStringRef * pErrorMsg
Current, pending error message.
uint8_t allowExtraArgs
Toggle for allowing extra positional arguments beyond the ones added.
GBL_RESULT GblCmdParser_setMainOptionGroup(GblCmdParser *pSelf, GblOptionGroup *pGroup)
Sets the main option group for the parser to the one given by pGroup, returning the result.
uint8_t enableVersionOption
Toggle for optionally enabling a version command-line option.
const GblCmdArg * GblCmdParser_positionalArg(const GblCmdParser *pSelf, size_t index)
Returns a pointer to the GblCmdArg structure in the internally maintained list at the given index.
uint8_t enableHelpOption
Toggle for optionally enabling an autogenerated help option.
uint8_t allowUnknownOptions
Toggle for allowing unknown options not handled by a GblCmdOptionGroup.
GblOptionGroup * GblCmdParser_findOptionGroup(const GblCmdParser *pSelf, const char *pName)
Finds a GblOptionGroup from the internal list by its GblObject::name.