solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
Loading...
Searching...
No Matches
flags.h
Go to the documentation of this file.
1
8#ifndef FLAGS_H
9#define FLAGS_H
10
11#include "cstr.h" // String comparison
12
13#include <errno.h> // errno
14#include <inttypes.h> // Printing int types
15#include <limits.h> // INT_MAX, INT8_MAX, etc.
16#include <stdarg.h> // va_list
17#include <stdbool.h> // bool
18#include <stddef.h> // size_t
19#include <stdint.h> // intN_t, uintN_t
20#include <stdio.h> // printf, snprintf
21#include <stdlib.h> // malloc, free, strtol
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27// =============================================================================
28// PUBLIC API
29// =============================================================================
30
32typedef enum {
33 FLAG_OK = 0,
34 FLAG_ERROR_ALLOCATION, // Malloc failed
35 FLAG_ERROR_UNKNOWN_FLAG, // --unknown passed
36 FLAG_ERROR_MISSING_VALUE, // --flag [EOF]
37 FLAG_ERROR_INVALID_NUMBER, // Parsing non-number or overflow
38 FLAG_ERROR_VALIDATION, // Custom validator failed
39 FLAG_ERROR_REQUIRED_MISSING, // Mandatory flag omitted
40 FLAG_ERROR_UNKNOWN_SUBCOMMAND, // Unknown command
41 FLAG_ERROR_INVALID_ARGUMENT // Null pointers passed to API
43
45typedef enum {
46 TYPE_BOOL,
47 TYPE_CHAR, // Single character
48 TYPE_STRING, // char*
49 TYPE_INT8,
50 TYPE_UINT8,
51 TYPE_INT16,
52 TYPE_UINT16,
53 TYPE_INT32,
54 TYPE_UINT32,
55 TYPE_INT64,
56 TYPE_UINT64,
57 TYPE_SIZE_T,
58 TYPE_FLOAT,
59 TYPE_DOUBLE
61
62typedef struct Flag Flag;
63typedef struct FlagParser FlagParser;
64
71typedef bool (*FlagValidator)(const void* value, const char** error_out);
72
74FlagParser* flag_parser_new(const char* name, const char* description);
75
77void flag_parser_free(FlagParser* parser);
78
80void flag_parser_set_footer(FlagParser* parser, const char* footer);
81
101void flag_add_completion_cmd(FlagParser* fp);
102
110bool flag_invoke_subcommand(FlagParser* parser, void (*pre_invoke)(void* user_data), void* user_data);
111
118void flag_set_pre_invoke(FlagParser* parser, void (*pre_invoke)(void* user_data));
119
124Flag* flag_add(FlagParser* parser, FlagDataType type, const char* name, char short_name, const char* desc,
125 void* value_ptr, bool required);
126
127// --- Type Macros (Optional Flags) ---
128#define flag_bool(parser, name, short_name, desc, value) \
129 flag_add(parser, TYPE_BOOL, name, short_name, desc, value, false)
130#define flag_char(parser, name, short_name, desc, value) \
131 flag_add(parser, TYPE_CHAR, name, short_name, desc, value, false)
132#define flag_string(parser, name, short_name, desc, value) \
133 flag_add(parser, TYPE_STRING, name, short_name, desc, value, false)
134#define flag_int(parser, name, short_name, desc, value) \
135 flag_add(parser, TYPE_INT32, name, short_name, desc, value, false) // Default int is 32
136#define flag_int8(parser, name, short_name, desc, value) \
137 flag_add(parser, TYPE_INT8, name, short_name, desc, value, false)
138#define flag_int16(parser, name, short_name, desc, value) \
139 flag_add(parser, TYPE_INT16, name, short_name, desc, value, false)
140#define flag_int32(parser, name, short_name, desc, value) \
141 flag_add(parser, TYPE_INT32, name, short_name, desc, value, false)
142#define flag_int64(parser, name, short_name, desc, value) \
143 flag_add(parser, TYPE_INT64, name, short_name, desc, value, false)
144#define flag_uint8(parser, name, short_name, desc, value) \
145 flag_add(parser, TYPE_UINT8, name, short_name, desc, value, false)
146#define flag_uint16(parser, name, short_name, desc, value) \
147 flag_add(parser, TYPE_UINT16, name, short_name, desc, value, false)
148#define flag_uint32(parser, name, short_name, desc, value) \
149 flag_add(parser, TYPE_UINT32, name, short_name, desc, value, false)
150#define flag_uint64(parser, name, short_name, desc, value) \
151 flag_add(parser, TYPE_UINT64, name, short_name, desc, value, false)
152#define flag_size_t(parser, name, short_name, desc, value) \
153 flag_add(parser, TYPE_SIZE_T, name, short_name, desc, value, false)
154#define flag_float(parser, name, short_name, desc, value) \
155 flag_add(parser, TYPE_FLOAT, name, short_name, desc, value, false)
156#define flag_double(parser, name, short_name, desc, value) \
157 flag_add(parser, TYPE_DOUBLE, name, short_name, desc, value, false)
158
159// --- Type Macros (Required Flags) ---
160// Boolean (Rarely required, but possible)
161#define flag_req_bool(parser, name, short_name, desc, value) \
162 flag_add(parser, TYPE_BOOL, name, short_name, desc, value, true)
163
164// Char & String
165#define flag_req_char(parser, name, short_name, desc, value) \
166 flag_add(parser, TYPE_CHAR, name, short_name, desc, value, true)
167#define flag_req_string(parser, name, short_name, desc, value) \
168 flag_add(parser, TYPE_STRING, name, short_name, desc, value, true)
169
170// Standard Aliases (Default to 32-bit)
171#define flag_req_int(parser, name, short_name, desc, value) \
172 flag_add(parser, TYPE_INT32, name, short_name, desc, value, true)
173#define flag_req_uint(parser, name, short_name, desc, value) \
174 flag_add(parser, TYPE_UINT32, name, short_name, desc, value, true)
175
176// Explicit Sized Integers
177#define flag_req_int8(parser, name, short_name, desc, value) \
178 flag_add(parser, TYPE_INT8, name, short_name, desc, value, true)
179#define flag_req_uint8(parser, name, short_name, desc, value) \
180 flag_add(parser, TYPE_UINT8, name, short_name, desc, value, true)
181#define flag_req_int16(parser, name, short_name, desc, value) \
182 flag_add(parser, TYPE_INT16, name, short_name, desc, value, true)
183#define flag_req_uint16(parser, name, short_name, desc, value) \
184 flag_add(parser, TYPE_UINT16, name, short_name, desc, value, true)
185#define flag_req_int32(parser, name, short_name, desc, value) \
186 flag_add(parser, TYPE_INT32, name, short_name, desc, value, true)
187#define flag_req_uint32(parser, name, short_name, desc, value) \
188 flag_add(parser, TYPE_UINT32, name, short_name, desc, value, true)
189#define flag_req_int64(parser, name, short_name, desc, value) \
190 flag_add(parser, TYPE_INT64, name, short_name, desc, value, true)
191#define flag_req_uint64(parser, name, short_name, desc, value) \
192 flag_add(parser, TYPE_UINT64, name, short_name, desc, value, true)
193
194// Memory & Floating Point
195#define flag_req_size_t(parser, name, short_name, desc, value) \
196 flag_add(parser, TYPE_SIZE_T, name, short_name, desc, value, true)
197#define flag_req_float(parser, name, short_name, desc, value) \
198 flag_add(parser, TYPE_FLOAT, name, short_name, desc, value, true)
199#define flag_req_double(parser, name, short_name, desc, value) \
200 flag_add(parser, TYPE_DOUBLE, name, short_name, desc, value, true)
201
203FlagParser* flag_add_subcommand(FlagParser* parser, const char* name, const char* desc, void (*handler)(void* data));
204
206void flag_set_validator(Flag* flag, FlagValidator validator);
207
213FlagStatus flag_parse(FlagParser* parser, int argc, char** argv);
214
223FlagStatus flag_parse_and_invoke(FlagParser* parser, int argc, char** argv, void* user_data);
224
226const char* flag_get_error(FlagParser* parser);
227
229FlagParser* flag_active_subcommand(FlagParser* parser);
230
232int flag_positional_count(FlagParser* parser);
233
235const char* flag_positional_at(FlagParser* parser, int index);
236
238bool flag_is_present(FlagParser* parser, const char* flag_name);
239
241void flag_print_usage(FlagParser* parser);
242
244const char* flag_status_str(FlagStatus status);
245
246#ifdef __cplusplus
247}
248#endif
249#endif // FLAGS_H
High-performance C string with Small String Optimization (SSO).
bool flag_invoke_subcommand(FlagParser *parser, void(*pre_invoke)(void *user_data), void *user_data)
FlagStatus flag_parse(FlagParser *parser, int argc, char **argv)
void flag_parser_set_footer(FlagParser *parser, const char *footer)
void flag_parser_free(FlagParser *parser)
Flag * flag_add(FlagParser *parser, FlagDataType type, const char *name, char short_name, const char *desc, void *value_ptr, bool required)
bool flag_is_present(FlagParser *parser, const char *flag_name)
FlagDataType
Definition flags.h:45
FlagParser * flag_add_subcommand(FlagParser *parser, const char *name, const char *desc, void(*handler)(void *data))
const char * flag_positional_at(FlagParser *parser, int index)
FlagStatus flag_parse_and_invoke(FlagParser *parser, int argc, char **argv, void *user_data)
const char * flag_status_str(FlagStatus status)
FlagStatus
Definition flags.h:32
const char * flag_get_error(FlagParser *parser)
FlagParser * flag_active_subcommand(FlagParser *parser)
bool(* FlagValidator)(const void *value, const char **error_out)
Definition flags.h:71
FlagParser * flag_parser_new(const char *name, const char *description)
void flag_set_validator(Flag *flag, FlagValidator validator)
int flag_positional_count(FlagParser *parser)
void flag_print_usage(FlagParser *parser)
void flag_set_pre_invoke(FlagParser *parser, void(*pre_invoke)(void *user_data))