ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
internal.h File Reference

Internal declarations for builder implementation. More...

Go to the source code of this file.

Data Structures

struct  option_builder_handler_t
 Type handler for builder operations. More...
 

Macros

#define INITIAL_DESCRIPTOR_CAPACITY   32
 
#define INITIAL_DEPENDENCY_CAPACITY   16
 
#define INITIAL_POSITIONAL_ARG_CAPACITY   8
 
#define INITIAL_OWNED_STRINGS_CAPACITY   32
 
#define NUM_OPTION_TYPES   6
 

Functions

const char * get_option_help_placeholder_str (const option_descriptor_t *desc)
 Get help placeholder string for an option type.
 
int format_option_default_value_str (const option_descriptor_t *desc, char *buf, size_t bufsize)
 Format option default value as a string.
 
bool option_applies_to_mode (const option_descriptor_t *desc, asciichat_mode_t mode, bool for_binary_help)
 Check if an option applies to a specific mode using bitmask.
 
void ensure_descriptor_capacity (options_builder_t *builder)
 Grow descriptor array if needed.
 
void ensure_dependency_capacity (options_builder_t *builder)
 Grow dependency array if needed.
 
void ensure_positional_arg_capacity (options_builder_t *builder)
 Grow positional arg array if needed.
 
void ensure_owned_strings_capacity (options_builder_t *builder)
 
const option_descriptor_t * find_option (const options_config_t *config, const char *long_name)
 Find option descriptor by long name.
 
bool is_option_set (const options_config_t *config, const void *options_struct, const char *option_name)
 Check if an option is set (has non-default value)
 

Variables

const option_builder_handler_t g_builder_handlers []
 

Detailed Description

Internal declarations for builder implementation.

Shared structures and forward declarations used across builder modules.

Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
January 2026

Definition in file options/builder/internal.h.

Macro Definition Documentation

◆ INITIAL_DEPENDENCY_CAPACITY

#define INITIAL_DEPENDENCY_CAPACITY   16

Definition at line 21 of file options/builder/internal.h.

◆ INITIAL_DESCRIPTOR_CAPACITY

#define INITIAL_DESCRIPTOR_CAPACITY   32

Definition at line 20 of file options/builder/internal.h.

◆ INITIAL_OWNED_STRINGS_CAPACITY

#define INITIAL_OWNED_STRINGS_CAPACITY   32

Definition at line 23 of file options/builder/internal.h.

◆ INITIAL_POSITIONAL_ARG_CAPACITY

#define INITIAL_POSITIONAL_ARG_CAPACITY   8

Definition at line 22 of file options/builder/internal.h.

◆ NUM_OPTION_TYPES

#define NUM_OPTION_TYPES   6

Definition at line 41 of file options/builder/internal.h.

Function Documentation

◆ ensure_dependency_capacity()

void ensure_dependency_capacity ( options_builder_t *  builder)

Grow dependency array if needed.

Definition at line 230 of file builder.c.

230 {
231 if (builder->num_dependencies >= builder->dependency_capacity) {
232 size_t new_capacity = builder->dependency_capacity * 2;
233 option_dependency_t *new_dependencies =
234 SAFE_REALLOC(builder->dependencies, new_capacity * sizeof(option_dependency_t), option_dependency_t *);
235 if (!new_dependencies) {
236 log_fatal("Failed to reallocate dependencies array");
237 return;
238 }
239 builder->dependencies = new_dependencies;
240 builder->dependency_capacity = new_capacity;
241 }
242}
#define SAFE_REALLOC(ptr, size, cast)
Definition common.h:284
#define log_fatal(...)
Log a FATAL message.
Definition log/log.h:599
Option dependency.
Definition builder.h:331
size_t num_dependencies
Current count.
Definition builder.h:447
size_t dependency_capacity
Allocated capacity.
Definition builder.h:448
option_dependency_t * dependencies
Dynamic array of dependencies.
Definition builder.h:446

References options_builder_t::dependencies, options_builder_t::dependency_capacity, log_fatal, options_builder_t::num_dependencies, and SAFE_REALLOC.

Referenced by options_builder_add_dependency(), options_builder_add_dependency_conflicts(), options_builder_add_dependency_implies(), and options_builder_add_dependency_requires().

◆ ensure_descriptor_capacity()

void ensure_descriptor_capacity ( options_builder_t *  builder)

Grow descriptor array if needed.

Definition at line 213 of file builder.c.

213 {
214 if (builder->num_descriptors >= builder->descriptor_capacity) {
215 size_t new_capacity = builder->descriptor_capacity * 2;
216 option_descriptor_t *new_descriptors =
217 SAFE_REALLOC(builder->descriptors, new_capacity * sizeof(option_descriptor_t), option_descriptor_t *);
218 if (!new_descriptors) {
219 log_fatal("Failed to reallocate descriptors array");
220 return;
221 }
222 builder->descriptors = new_descriptors;
223 builder->descriptor_capacity = new_capacity;
224 }
225}
Option descriptor.
Definition builder.h:241
size_t descriptor_capacity
Allocated capacity.
Definition builder.h:444
option_descriptor_t * descriptors
Dynamic array of descriptors.
Definition builder.h:442
size_t num_descriptors
Current count.
Definition builder.h:443

References options_builder_t::descriptor_capacity, options_builder_t::descriptors, log_fatal, options_builder_t::num_descriptors, and SAFE_REALLOC.

Referenced by options_builder_add_action(), options_builder_add_bool(), options_builder_add_callback(), options_builder_add_callback_optional(), options_builder_add_callback_with_metadata(), options_builder_add_descriptor(), options_builder_add_double(), options_builder_add_double_with_metadata(), options_builder_add_int(), options_builder_add_int_with_metadata(), and options_builder_add_string().

◆ ensure_owned_strings_capacity()

void ensure_owned_strings_capacity ( options_builder_t *  builder)

◆ ensure_positional_arg_capacity()

void ensure_positional_arg_capacity ( options_builder_t *  builder)

Grow positional arg array if needed.

Definition at line 247 of file builder.c.

247 {
248 if (builder->num_positional_args >= builder->positional_arg_capacity) {
249 size_t new_capacity = builder->positional_arg_capacity * 2;
250 if (new_capacity == 0)
251 new_capacity = INITIAL_POSITIONAL_ARG_CAPACITY;
252
255 if (!new_positional) {
256 log_fatal("Failed to reallocate positional_args array");
257 return;
258 }
259 builder->positional_args = new_positional;
260 builder->positional_arg_capacity = new_capacity;
261 }
262}
#define INITIAL_POSITIONAL_ARG_CAPACITY
positional_arg_descriptor_t * positional_args
Dynamic array of positional args.
Definition builder.h:450
size_t num_positional_args
Current count.
Definition builder.h:451
size_t positional_arg_capacity
Allocated capacity.
Definition builder.h:452
Positional argument descriptor.
Definition builder.h:357

References INITIAL_POSITIONAL_ARG_CAPACITY, log_fatal, options_builder_t::num_positional_args, options_builder_t::positional_arg_capacity, options_builder_t::positional_args, and SAFE_REALLOC.

Referenced by options_builder_add_positional().

◆ find_option()

const option_descriptor_t * find_option ( const options_config_t *  config,
const char *  long_name 
)

Find option descriptor by long name.

Definition at line 344 of file builder.c.

344 {
345 for (size_t i = 0; i < config->num_descriptors; i++) {
346 if (strcmp(config->descriptors[i].long_name, long_name) == 0) {
347 return &config->descriptors[i];
348 }
349 }
350 return NULL;
351}
const char * long_name
Long option name (e.g., "port")
Definition builder.h:243
option_descriptor_t * descriptors
Array of option descriptors.
Definition builder.h:402
size_t num_descriptors
Number of descriptors.
Definition builder.h:403

References options_config_t::descriptors, option_descriptor_t::long_name, and options_config_t::num_descriptors.

Referenced by is_option_set().

◆ format_option_default_value_str()

int format_option_default_value_str ( const option_descriptor_t *  desc,
char *  buf,
size_t  bufsize 
)

Format option default value as a string.

Parameters
descOption descriptor
bufOutput buffer
bufsizeSize of buffer
Returns
Number of characters written to buf

Definition at line 83 of file builder.c.

83 {
84 if (!desc || !buf || bufsize == 0) {
85 return 0;
86 }
87
88 // For callback options with enums, look up the enum string by matching the default value
89 if (desc->type == OPTION_TYPE_CALLBACK && desc->metadata.enum_values && desc->default_value) {
90 int default_int_val = 0;
91 memcpy(&default_int_val, desc->default_value, sizeof(int));
92
93 // Try to find matching enum value
94 if (desc->metadata.enum_integer_values) {
95 for (size_t i = 0; desc->metadata.enum_values[i] != NULL; i++) {
96 if (desc->metadata.enum_integer_values[i] == default_int_val) {
97 return safe_snprintf(buf, bufsize, "%s", desc->metadata.enum_values[i]);
98 }
99 }
100 } else {
101 // Fallback: assume sequential 0-based indices if integer values not provided
102 // Count enum values to check bounds
103 size_t enum_count = 0;
104 while (desc->metadata.enum_values[enum_count] != NULL) {
105 enum_count++;
106 }
107 if (default_int_val >= 0 && (size_t)default_int_val < enum_count) {
108 return safe_snprintf(buf, bufsize, "%s", desc->metadata.enum_values[default_int_val]);
109 }
110 }
111 }
112
113 // For callback options storing numeric types (int/double/float), format them as numbers
114 if (desc->type == OPTION_TYPE_CALLBACK && desc->default_value && desc->metadata.enum_values == NULL) {
115 // Check if this is a numeric callback by looking for numeric_range metadata
116 // Numeric callbacks have min/max range constraints set (max != 0 indicates a range was set)
117 if (desc->metadata.numeric_range.max != 0 || desc->metadata.numeric_range.min != 0) {
118 // This is a numeric callback option - extract and format the value
119 // Determine if it's int or double based on range (int max is 2147483647)
120 double default_double = 0.0;
121 if (desc->metadata.numeric_range.max <= 2147483647.0 && desc->metadata.numeric_range.min >= -2147483648.0) {
122 // Integer-ranged value (like port 1-65535) - stored as int
123 int default_int = 0;
124 memcpy(&default_int, desc->default_value, sizeof(int));
125 default_double = (double)default_int;
126 } else {
127 // Double-ranged value - stored as double
128 memcpy(&default_double, desc->default_value, sizeof(double));
129 }
130
131 // Format with appropriate precision (remove trailing zeros for integers)
132 char formatted[32];
133 safe_snprintf(formatted, sizeof(formatted), "%.1f", default_double);
134
135 // Remove trailing zeros after decimal point
136 char *dot = strchr(formatted, '.');
137 if (dot) {
138 char *end = formatted + strlen(formatted) - 1;
139 while (end > dot && *end == '0') {
140 end--;
141 }
142 if (*end == '.') {
143 *end = '\0';
144 } else {
145 *(end + 1) = '\0';
146 }
147 }
148
149 return safe_snprintf(buf, bufsize, "%s", formatted);
150 }
151 }
152
153 // For callback options with string defaults (no enum, no numeric range)
154 // Treat default_value as a const char* string pointer
155 if (desc->type == OPTION_TYPE_CALLBACK && desc->default_value && desc->metadata.enum_values == NULL &&
156 desc->metadata.numeric_range.max == 0 && desc->metadata.numeric_range.min == 0) {
157 const char *str_default = (const char *)desc->default_value;
158 if (str_default && str_default[0] != '\0') {
159 return safe_snprintf(buf, bufsize, "%s", str_default);
160 }
161 }
162
163 return options_format_default_value(desc->type, desc->default_value, buf, bufsize);
164}
@ OPTION_TYPE_CALLBACK
Custom parser function.
Definition builder.h:166
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Safe formatted string printing to buffer.
Definition system.c:148
int options_format_default_value(option_type_t type, const void *default_value, char *buf, size_t bufsize)
Format option default value to string.
const void * default_value
Pointer to default value (or NULL if required)
Definition builder.h:258
option_metadata_t metadata
Metadata for shell completions (enums, ranges, examples, etc.)
Definition builder.h:281
option_type_t type
Value type.
Definition builder.h:247
int max
Maximum value (or 0 if no limit)
Definition builder.h:203
int min
Minimum value (or 0 if no limit)
Definition builder.h:202
const int * enum_integer_values
Actual enum integer values (e.g., {-1, 0, 1, 2, 3} for non-sequential enums)
Definition builder.h:198
const char ** enum_values
Enum value strings (null-terminated, e.g., {"auto", "none", "16", "256", "truecolor",...
Definition builder.h:195
struct option_metadata_t::@19 numeric_range

References option_descriptor_t::default_value, option_metadata_t::enum_integer_values, option_metadata_t::enum_values, option_metadata_t::max, option_descriptor_t::metadata, option_metadata_t::min, option_metadata_t::numeric_range, OPTION_TYPE_CALLBACK, options_format_default_value(), safe_snprintf(), and option_descriptor_t::type.

Referenced by options_config_print_options_sections_with_width(), and options_config_print_usage().

◆ get_option_help_placeholder_str()

const char * get_option_help_placeholder_str ( const option_descriptor_t *  desc)

Get help placeholder string for an option type.

Parameters
descOption descriptor
Returns
Pointer to string literal ("INTEGER", "NUMBER", "STRING", "VALUE", "[BOOLEAN]"), custom placeholder, or empty string

Definition at line 43 of file builder.c.

43 {
44 if (!desc) {
45 return "";
46 }
47 // Check for custom placeholder first
48 if (desc->arg_placeholder != NULL) {
49 return desc->arg_placeholder;
50 }
51
52 // For callback options, check if it's a boolean based on enum values
53 if (desc->type == OPTION_TYPE_CALLBACK && desc->metadata.enum_values) {
54 // Check if enum values contain "true" and "false" (boolean-like)
55 const char *const *values = desc->metadata.enum_values;
56 bool has_true = false, has_false = false;
57
58 for (int i = 0; values[i] != NULL; i++) {
59 if (strcmp(values[i], "true") == 0 || strcmp(values[i], "yes") == 0 || strcmp(values[i], "on") == 0) {
60 has_true = true;
61 }
62 if (strcmp(values[i], "false") == 0 || strcmp(values[i], "no") == 0 || strcmp(values[i], "off") == 0) {
63 has_false = true;
64 }
65 }
66
67 // If it has both true-like and false-like values, it's boolean
68 if (has_true && has_false) {
69 return "BOOLEAN";
70 }
71 }
72
74}
const char * options_get_type_placeholder(option_type_t type)
Get placeholder string for option type.
const char * arg_placeholder
Custom argument placeholder (e.g., "SHELL [FILE]" instead of "STR")
Definition builder.h:253

References option_descriptor_t::arg_placeholder, option_metadata_t::enum_values, option_descriptor_t::metadata, OPTION_TYPE_CALLBACK, options_get_type_placeholder(), and option_descriptor_t::type.

Referenced by options_config_print_options_sections_with_width(), and options_config_print_usage().

◆ is_option_set()

bool is_option_set ( const options_config_t *  config,
const void *  options_struct,
const char *  option_name 
)

Check if an option is set (has non-default value)

Definition at line 356 of file builder.c.

356 {
357 const option_descriptor_t *desc = find_option(config, option_name);
358 if (!desc)
359 return false;
360
361 const char *base = (const char *)options_struct;
362 const void *field = base + desc->offset;
363
364 // Use handler registry to check if option is set
365 if (desc->type >= 0 && desc->type < (int)(NUM_OPTION_TYPES)) {
366 if (g_builder_handlers[desc->type].is_set) {
367 return g_builder_handlers[desc->type].is_set(field, desc);
368 }
369 }
370
371 return false;
372}
const option_descriptor_t * find_option(const options_config_t *config, const char *long_name)
Find option descriptor by long name.
Definition builder.c:344
const option_builder_handler_t g_builder_handlers[]
#define NUM_OPTION_TYPES
bool(* is_set)(const void *field, const option_descriptor_t *desc)
size_t offset
offsetof(struct, field) - where to store value
Definition builder.h:248

References find_option(), g_builder_handlers, option_builder_handler_t::is_set, NUM_OPTION_TYPES, option_descriptor_t::offset, and option_descriptor_t::type.

Referenced by options_config_validate().

◆ option_applies_to_mode()

bool option_applies_to_mode ( const option_descriptor_t *  desc,
asciichat_mode_t  mode,
bool  for_binary_help 
)

Check if an option applies to a specific mode using bitmask.

Parameters
descOption descriptor
modeMode to check (use invalid value like -1 for binary help)
for_binary_helpIf true, show binary options; if false, hide them
Returns
true if option should be shown for this mode

Definition at line 177 of file builder.c.

177 {
178 if (!desc) {
179 SET_ERRNO(ERROR_INVALID_PARAM, "Descriptor is NULL");
180 return false;
181 }
182
183 // When for_binary_help is true (i.e., for 'ascii-chat --help'),
184 // show options that apply to the default mode (DISCOVERY) or binary-level options only.
185 // Don't show mode-specific options for other modes (server, client, mirror, discovery-service).
186 if (for_binary_help) {
187 // Binary-level options or options that apply to discovery mode (the default)
189 return (desc->mode_bitmask & default_modes) != 0 && !desc->hide_from_binary_help;
190 }
191
192 // For mode-specific help (non-discovery modes), show only options for that mode.
193 // Do not show binary options here unless it also specifically applies to the mode.
194 // The 'mode' parameter is the actual mode (e.g., MODE_CLIENT, MODE_SERVER).
195 if (mode < 0 || mode > MODE_DISCOVERY) { // Use MODE_INVALID as upper bound for valid modes
196 return false;
197 }
198 option_mode_bitmask_t mode_bit = (1 << mode);
199
200 // Check if it's a binary option. If so, only show if it also explicitly applies to this mode.
201 if ((desc->mode_bitmask & OPTION_MODE_BINARY) && !(desc->mode_bitmask & mode_bit)) {
202 return false; // Binary options not shown in mode-specific help unless also mode-specific
203 }
204
205 bool applies = (desc->mode_bitmask & mode_bit) != 0;
206
207 return applies && !desc->hide_from_mode_help;
208}
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
@ ERROR_INVALID_PARAM
option_mode_bitmask_t
Option mode bitmask.
@ MODE_DISCOVERY
Discovery mode - participant that can dynamically become host.
@ OPTION_MODE_BINARY
Binary-level options (parsed before mode detection)
@ OPTION_MODE_DISCOVERY
Discovery mode (bit 4)
option_mode_bitmask_t mode_bitmask
Which modes this option applies to.
Definition builder.h:278
bool hide_from_mode_help
If true, don't show in mode-specific help (binary-level only)
Definition builder.h:254
bool hide_from_binary_help
If true, don't show in binary-level help (e.g., in release builds)
Definition builder.h:255

References ERROR_INVALID_PARAM, option_descriptor_t::hide_from_binary_help, option_descriptor_t::hide_from_mode_help, option_descriptor_t::mode_bitmask, MODE_DISCOVERY, OPTION_MODE_BINARY, OPTION_MODE_DISCOVERY, and SET_ERRNO.

Referenced by options_config_print_options_sections_with_width(), and options_config_print_usage().

Variable Documentation

◆ g_builder_handlers

const option_builder_handler_t g_builder_handlers[]
extern

Definition at line 54 of file options/builder/handlers.c.

54 {
55 [OPTION_TYPE_BOOL] = {is_set_bool, apply_env_bool, apply_cli_bool, format_help_placeholder_bool},
56 [OPTION_TYPE_INT] = {is_set_int, apply_env_int, apply_cli_int, format_help_placeholder_int},
57 [OPTION_TYPE_STRING] = {is_set_string, apply_env_string, apply_cli_string, format_help_placeholder_string},
58 [OPTION_TYPE_DOUBLE] = {is_set_double, apply_env_double, apply_cli_double, format_help_placeholder_double},
59 [OPTION_TYPE_CALLBACK] = {is_set_callback, apply_env_callback, apply_cli_callback,
60 format_help_placeholder_callback},
61 [OPTION_TYPE_ACTION] = {is_set_action, apply_env_action, apply_cli_action, format_help_placeholder_action},
62};
@ OPTION_TYPE_INT
Integer value (–count 42)
Definition builder.h:163
@ OPTION_TYPE_DOUBLE
Floating point (–ratio 1.5)
Definition builder.h:165
@ OPTION_TYPE_STRING
String value (–name foo)
Definition builder.h:164
@ OPTION_TYPE_ACTION
Action that executes and may exit (–list-webcams, etc.)
Definition builder.h:167
@ OPTION_TYPE_BOOL
Boolean flag (–flag, no value)
Definition builder.h:162

Referenced by is_option_set(), options_config_set_defaults(), and options_config_validate().