ArgParse.h (6401B)
1 /*************************************************************************************************** 2 3 Zyan Core Library (Zycore-C) 4 5 Original Author : Joel Hoener 6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 25 ***************************************************************************************************/ 26 27 /** 28 * @file 29 * Implements command-line argument parsing. 30 */ 31 32 #ifndef ZYCORE_ARGPARSE_H 33 #define ZYCORE_ARGPARSE_H 34 35 #include "zydis/Zycore/Types.h" 36 #include "zydis/Zycore/Status.h" 37 #include "zydis/Zycore/Vector.h" 38 #include "zydis/Zycore/String.h" 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /* ============================================================================================== */ 45 /* Structs and other types */ 46 /* ============================================================================================== */ 47 48 /** 49 * Definition of a single argument. 50 */ 51 typedef struct ZyanArgParseDefinition_ 52 { 53 /** 54 * The argument name, e.g. `--help`. 55 * 56 * Must start with either one or two dashes. Single dash arguments must consist of a single 57 * character, (e.g. `-n`), double-dash arguments can be of arbitrary length. 58 */ 59 const char* name; 60 /** 61 * Whether the argument is boolean or expects a value. 62 */ 63 ZyanBool boolean; 64 /** 65 * Whether this argument is required (error if missing). 66 */ 67 ZyanBool required; 68 } ZyanArgParseDefinition; 69 70 /** 71 * Configuration for argument parsing. 72 */ 73 typedef struct ZyanArgParseConfig_ 74 { 75 /** 76 * `argv` argument passed to `main` by LibC. 77 */ 78 const char** argv; 79 /** 80 * `argc` argument passed to `main` by LibC. 81 */ 82 ZyanUSize argc; 83 /** 84 * Minimum # of accepted unnamed / anonymous arguments. 85 */ 86 ZyanUSize min_unnamed_args; 87 /** 88 * Maximum # of accepted unnamed / anonymous arguments. 89 */ 90 ZyanUSize max_unnamed_args; 91 /** 92 * Argument definition array, or `ZYAN_NULL`. 93 * 94 * Expects a pointer to an array of `ZyanArgParseDefinition` instances. The array is 95 * terminated by setting the `.name` field of the last element to `ZYAN_NULL`. If no named 96 * arguments should be parsed, you can also set this to `ZYAN_NULL`. 97 */ 98 ZyanArgParseDefinition* args; 99 } ZyanArgParseConfig; 100 101 /** 102 * Information about a parsed argument. 103 */ 104 typedef struct ZyanArgParseArg_ 105 { 106 /** 107 * Corresponding argument definition, or `ZYAN_NULL` for unnamed args. 108 * 109 * This pointer is borrowed from the `cfg` pointer passed to `ZyanArgParse`. 110 */ 111 const ZyanArgParseDefinition* def; 112 /** 113 * Whether the argument has a value (is non-boolean). 114 */ 115 ZyanBool has_value; 116 /** 117 * If `has_value == true`, then the argument value. 118 * 119 * This is a view into the `argv` string array passed to `ZyanArgParse` via the `cfg` argument. 120 */ 121 ZyanStringView value; 122 } ZyanArgParseArg; 123 124 /* ============================================================================================== */ 125 /* Exported functions */ 126 /* ============================================================================================== */ 127 128 #ifndef ZYAN_NO_LIBC 129 130 /** 131 * Parse arguments according to a `ZyanArgParseConfig` definition. 132 * 133 * @param cfg Argument parser config to use. 134 * @param parsed Receives the parsed output. Vector of `ZyanArgParseArg`. Ownership is 135 * transferred to the user. Input is expected to be uninitialized. On error, 136 * the vector remains uninitialized. 137 * @param error_token On error, if it makes sense, receives the argument fragment causing the 138 * error. Optional, may be `ZYAN_NULL`. The pointer borrows into the `cfg` 139 * struct and doesn't have to be freed by the user. 140 * 141 * @return A `ZyanStatus` status determining whether the parsing succeeded. 142 */ 143 ZYCORE_EXPORT ZyanStatus ZyanArgParse(const ZyanArgParseConfig *cfg, ZyanVector* parsed, 144 const char** error_token); 145 146 #endif 147 148 /** 149 * Parse arguments according to a `ZyanArgParseConfig` definition. 150 * 151 * This version allows specification of a custom memory allocator and thus supports no-libc. 152 * 153 * @param cfg Argument parser config to use. 154 * @param parsed Receives the parsed output. Vector of `ZyanArgParseArg`. Ownership is 155 * transferred to the user. Input is expected to be uninitialized. On error, 156 * the vector remains uninitialized. 157 * @param error_token On error, if it makes sense, receives the argument fragment causing the 158 * error. Optional, may be `ZYAN_NULL`. The pointer borrows into the `cfg` 159 * struct and doesn't have to be freed by the user. 160 * @param allocator The `ZyanAllocator` to be used for allocating the output vector's data. 161 * 162 * @return A `ZyanStatus` status determining whether the parsing succeeded. 163 */ 164 ZYCORE_EXPORT ZyanStatus ZyanArgParseEx(const ZyanArgParseConfig *cfg, ZyanVector* parsed, 165 const char** error_token, ZyanAllocator* allocator); 166 167 /* ============================================================================================== */ 168 169 #ifdef __cplusplus 170 } 171 #endif 172 173 #endif /* ZYCORE_ARGPARSE_H */