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

Central registry of all command-line options with mode applicability. More...

Go to the source code of this file.

Functions

asciichat_error_t options_registry_add_all_to_builder (options_builder_t *builder)
 Add all options from registry to builder.
 
const option_descriptor_t * options_registry_find_by_name (const char *long_name)
 Get option descriptor by name.
 
const option_descriptor_t * options_registry_find_by_short (char short_name)
 Get option descriptor by short name.
 
const option_descriptor_t * options_registry_get_for_mode (asciichat_mode_t mode, size_t *num_options)
 Get all options for a specific mode.
 
const option_descriptor_t * options_registry_get_binary_options (size_t *num_options)
 Get all binary-level options.
 
const option_descriptor_t * options_registry_get_for_display (asciichat_mode_t mode, bool for_binary_help, size_t *num_options)
 Get options for help/completions display with unified filtering.
 
const option_metadata_t * options_registry_get_metadata (const char *long_name)
 Get complete metadata for an option.
 
const char ** options_registry_get_enum_values (const char *option_name, const char ***descriptions, size_t *count)
 Get enum values for an option.
 
bool options_registry_get_numeric_range (const char *option_name, int *min_out, int *max_out, int *step_out)
 Get numeric range for an option.
 
const char ** options_registry_get_examples (const char *option_name, size_t *count)
 Get example values for an option.
 
option_input_type_t options_registry_get_input_type (const char *option_name)
 Get input type for an option.
 

Detailed Description

Central registry of all command-line options with mode applicability.

This module defines the single source of truth for all command-line options that can be used across all modes (server, client, mirror, discovery service, etc.).

Architecture Overview

The registry is the single source of truth for option definitions. It works with:

  • Builder (builder.h): Use builder to construct custom option configurations, populated from the registry via options_registry_add_all_to_builder().
  • RCU Thread-Safety (rcu.h): Registered options are parsed and published to RCU for lock-free thread-safe access via GET_OPTION() macro.
  • Options System (options.h): The unified parsing system uses the registry to build option configurations for different modes.

Design Philosophy

  • Single Definition: Each option defined exactly once with all metadata (no duplication)
  • Mode Bitmasks: Each option includes mode_bitmask indicating which modes it applies to
  • Automatic Filtering: Registry functions automatically filter by mode
  • Immutable After Load: Once loaded, registry is read-only (no runtime modifications)
  • Shared with Builder: Registry options added to builder via options_registry_add_all_to_builder()
  • Completion Metadata: Each option includes shell completion hints (enums, ranges, examples)

Registry Structure

The registry is defined in registry.c as a static array of option_descriptor_t structures. Each descriptor includes complete metadata:

Identification:

  • Long name (e.g., "port")
  • Short name (e.g., 'p')
  • Argument placeholder (e.g., "NUM", "STR", "PATH")

Type and Storage:

  • Type: BOOL, INT, STRING, DOUBLE, CALLBACK, ACTION
  • Offset into options_t struct (via offsetof())

Documentation:

  • Help text (brief description for –help output)
  • Group name (for organizing help sections: "NETWORK OPTIONS", "DISPLAY OPTIONS", etc.)
  • Visibility flags (hide_from_binary_help, hide_from_mode_help)

Values and Validation:

  • Default value pointer
  • Required flag (must user provide this option?)
  • Environment variable fallback (e.g., PORT, PASSWORD_FILE)
  • Custom validator function (validates across option fields)

Parsing and Actions:

  • Custom parser for OPTION_TYPE_CALLBACK
  • Action function for OPTION_TYPE_ACTION (executes immediately, may exit)

Mode Applicability:

  • Bitmask indicating which modes this option applies to

Completion Metadata (Phase 3):

  • Enum values and descriptions (for shell completions)
  • Numeric range (min, max, step)
  • Example values
  • Input type hint (ENUM, NUMERIC, FILEPATH, CHOICE, etc.)

Mode Bitmask System

Each option includes a mode_bitmask that controls where it appears:

Mode Bitmask Values:

  • OPTION_MODE_BINARY: Parsed before mode detection (–help, –version, –log-file, –log-level)
  • OPTION_MODE_SERVER: Server-only options (–max-clients, –discovery-service, etc.)
  • OPTION_MODE_CLIENT: Client-only options (–color, –audio, –snapshot, etc.)
  • OPTION_MODE_MIRROR: Mirror mode options (local webcam preview)
  • OPTION_MODE_DISCOVERY_SVC: Discovery service (ACDS) options
  • OPTION_MODE_ALL: Available in all modes

Examples:

.mode_bitmask = OPTION_MODE_CLIENT | OPTION_MODE_MIRROR // Client and mirror modes
.mode_bitmask = OPTION_MODE_SERVER // Server mode only
.mode_bitmask = OPTION_MODE_BINARY | OPTION_MODE_CLIENT // Binary + client options
.mode_bitmask = OPTION_MODE_ALL // All modes
@ OPTION_MODE_ALL
All modes + binary.
@ OPTION_MODE_BINARY
Binary-level options (parsed before mode detection)
@ OPTION_MODE_CLIENT
Client mode (bit 1)
@ OPTION_MODE_SERVER
Server mode (bit 0)
@ OPTION_MODE_MIRROR
Mirror mode (bit 2)

How Mode Filtering Works:

  1. User runs ascii-chat client or ascii-chat server
  2. Mode detection determines detected_mode (MODE_CLIENT, MODE_SERVER, etc.)
  3. Registry functions filter options by matching mode_bitmask
  4. Parser only accepts options for the detected mode
  5. Help output only shows relevant options

Usage Patterns

Pattern 1: Get all options for a specific mode

size_t num_opts;
for (size_t i = 0; i < num_opts; i++) {
printf(\"%s: %s\\n\", opts[i].long_name, opts[i].help_text);
}
@ MODE_CLIENT
Client mode - network client options.
const option_descriptor_t * options_registry_get_for_mode(asciichat_mode_t mode, size_t *num_options)
Get all options for a specific mode.
Definition public_api.c:218
Option descriptor.
Definition builder.h:241

Pattern 2: Look up individual options

if (port_opt && (port_opt->mode_bitmask & OPTION_MODE_SERVER)) {
printf(\"Port option available in server mode\\n\");
}
const option_descriptor_t * options_registry_find_by_name(const char *long_name)
Get option descriptor by name.
Definition public_api.c:141

Pattern 3: Populate builder with registry options

options_registry_add_all_to_builder(builder); // Add all registered options
options_config_t * options_builder_build(options_builder_t *builder)
Build immutable options config.
Definition builder.c:482
options_builder_t * options_builder_create(size_t struct_size)
Create empty options builder.
Definition builder.c:378
asciichat_error_t options_registry_add_all_to_builder(options_builder_t *builder)
Add all options from registry to builder.
Definition public_api.c:20
Options builder.
Definition builder.h:441
Options configuration.
Definition builder.h:401
Consolidated options structure.

Pattern 4: Get shell completion metadata

const option_metadata_t *meta = options_registry_get_metadata(\"color-mode\");
if (meta && meta->input_type == OPTION_INPUT_ENUM) {
size_t count;
const char **values = options_registry_get_enum_values(\"color-mode\", NULL, &count);
// Use values for shell completion suggestions
}
const option_metadata_t * options_registry_get_metadata(const char *long_name)
Get complete metadata for an option.
Definition public_api.c:370
Metadata for shell completion generation.
Definition builder.h:192

Adding New Options to Registry

To add a new option to the registry:

  1. Add field to options_t struct in include/ascii-chat/options/options.h
  2. Add default constant in options.h (e.g., OPT_MY_OPTION_DEFAULT)
  3. Add registry entry in lib/options/registry.c with:
    • Long and short names
    • Type and storage offset (via offsetof)
    • Default value and validation function
    • Help text and group name
    • Mode bitmask(s) indicating which modes apply
    • Completion metadata (if enum, ranges, or examples needed)

Example Registry Entry:

{
.long_name = \"max-clients\",
.short_name = 'c',
.type = OPTION_TYPE_INT,
.offset = offsetof(options_t, max_clients),
.default_value = &(int){OPT_MAX_CLIENTS_DEFAULT},
.help_text = \"Maximum number of simultaneous clients\",
.group = \"NETWORK OPTIONS\",
.mode_bitmask = OPTION_MODE_SERVER,
.validate = validate_max_clients, // Custom validator
.metadata = {
.input_type = OPTION_INPUT_NUMERIC,
.numeric_range = {.min = 1, .max = 100, .step = 1},
.examples = (const char *[]){\"1\", \"4\", \"10\", NULL},
}
}

Registry Lookup Functions

Core Functions:

Completion Metadata Functions (Phase 3):

RCU Thread-Safety Integration

After registry options are parsed through the builder, they're published via RCU:

// Build config from registered options
// Parse command line
options_config_parse(config, argc, argv, &opts, MODE_DETECTION_RESULT, ...);
// Publish to RCU (lock-free access from worker threads)
// Worker threads now read lock-free via GET_OPTION() macro
asciichat_error_t options_config_parse(const options_config_t *config, int argc, char **argv, void *options_struct, option_mode_bitmask_t detected_mode, int *remaining_argc, char ***remaining_argv)
Parse command-line arguments.
Definition builder.c:1815
options_t options_t_new(void)
Initialize options by parsing command-line arguments.
asciichat_error_t options_state_init(void)
Initialize RCU options system.
Definition rcu.c:370
asciichat_error_t options_state_set(const options_t *opts)
Set options from a parsed options struct.
Definition rcu.c:439
See also
builder.h - Builder API for constructing option configurations
rcu.h - Thread-safe RCU-based access to published Options Module
options.h - Unified Options Module parsing system (uses registry internally)
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
January 2026

Definition in file registry.h.

Function Documentation

◆ options_registry_add_all_to_builder()

asciichat_error_t options_registry_add_all_to_builder ( options_builder_t *  builder)

Add all options from registry to builder.

Iterates through the central options registry and adds each option to the provided builder with its mode bitmask set.

Parameters
builderOptions builder to add options to
Returns
ASCIICHAT_OK on success, error code on failure

Definition at line 20 of file public_api.c.

20 {
21 if (!builder) {
22 return SET_ERRNO(ERROR_INVALID_PARAM, "Builder is NULL");
23 }
24
26
27 for (size_t i = 0; i < g_registry_size; i++) {
28 const registry_entry_t *entry = &g_options_registry[i];
29 if (!entry->long_name) {
30 continue;
31 }
32 // Silent - no debug logging needed
33
34 switch (entry->type) {
36 options_builder_add_string(builder, entry->long_name, entry->short_name, entry->offset,
37 entry->default_value ? (const char *)entry->default_value : "", entry->help_text,
38 entry->group, entry->required, entry->env_var_name, entry->validate_fn);
39 break;
40 case OPTION_TYPE_INT:
41 // Use metadata-aware function if metadata is present
42 if (entry->metadata.numeric_range.max != 0 ||
43 (entry->metadata.enum_values && entry->metadata.enum_values[0] != NULL)) {
45 entry->default_value ? *(const int *)entry->default_value : 0,
46 entry->help_text, entry->group, entry->required, entry->env_var_name,
47 entry->validate_fn, &entry->metadata);
48 } else {
49 options_builder_add_int(builder, entry->long_name, entry->short_name, entry->offset,
50 entry->default_value ? *(const int *)entry->default_value : 0, entry->help_text,
51 entry->group, entry->required, entry->env_var_name, entry->validate_fn);
52 }
53 break;
55 options_builder_add_bool(builder, entry->long_name, entry->short_name, entry->offset,
56 entry->default_value ? *(const bool *)entry->default_value : false, entry->help_text,
57 entry->group, entry->required, entry->env_var_name);
58 break;
60 // Use metadata-aware function if metadata is present (has numeric range)
61 if (entry->metadata.numeric_range.max != 0) {
63 entry->default_value ? *(const double *)entry->default_value : 0.0,
64 entry->help_text, entry->group, entry->required, entry->env_var_name,
65 entry->validate_fn, &entry->metadata, entry->optional_arg);
66 } else {
67 options_builder_add_double(builder, entry->long_name, entry->short_name, entry->offset,
68 entry->default_value ? *(const double *)entry->default_value : 0.0, entry->help_text,
69 entry->group, entry->required, entry->env_var_name, entry->validate_fn,
70 entry->optional_arg);
71 }
72 break;
74 // Always use metadata-aware function to preserve enum/metadata information
76 entry->default_value, entry->default_value_size, entry->parse_fn,
77 entry->help_text, entry->group, entry->required, entry->env_var_name,
78 entry->optional_arg, &entry->metadata);
79 break;
81 // Actions are now registered as options with help text
82 // Look up the corresponding action function based on option name
83 if (strcmp(entry->long_name, "list-webcams") == 0) {
85 entry->group);
86 } else if (strcmp(entry->long_name, "list-microphones") == 0) {
88 entry->help_text, entry->group);
89 } else if (strcmp(entry->long_name, "list-speakers") == 0) {
91 entry->group);
92 } else if (strcmp(entry->long_name, "show-capabilities") == 0) {
94 entry->help_text, entry->group);
95 } else if (strcmp(entry->long_name, "check-update") == 0) {
97 entry->group);
98 } else if (strcmp(entry->long_name, "help") == 0 || strcmp(entry->long_name, "version") == 0) {
99 // Help and version are handled specially in options.c, just add them for help display
100 // They don't have actual action functions - pass a dummy one
101 options_builder_add_action(builder, entry->long_name, entry->short_name, NULL, entry->help_text, entry->group);
102 }
103 break;
104 }
105
106 // Set mode bitmask on the last added descriptor
108
109 // Set custom arg_placeholder if defined
110 if (entry->arg_placeholder) {
112 }
113 }
114
115 return ASCIICHAT_OK;
116}
void options_builder_set_arg_placeholder(options_builder_t *builder, const char *arg_placeholder)
Set custom argument placeholder on the last added option descriptor.
Definition builder.c:992
void options_builder_add_action(options_builder_t *builder, const char *long_name, char short_name, void(*action_fn)(void), const char *help_text, const char *group)
Add action option (executes action and may exit)
Definition builder.c:943
void options_builder_set_mode_bitmask(options_builder_t *builder, option_mode_bitmask_t mode_bitmask)
Set mode bitmask on the last added option descriptor.
Definition builder.c:984
void options_builder_add_bool(options_builder_t *builder, const char *long_name, char short_name, size_t offset, bool default_value, const char *help_text, const char *group, bool required, const char *env_var_name)
Add boolean flag option.
Definition builder.c:657
void options_builder_add_double_with_metadata(options_builder_t *builder, const char *long_name, char short_name, size_t offset, double default_value, const char *help_text, const char *group, bool required, const char *env_var_name, bool(*validate)(const void *, char **), const option_metadata_t *metadata, bool optional_arg)
Definition builder.c:813
void options_builder_add_double(options_builder_t *builder, const char *long_name, char short_name, size_t offset, double default_value, const char *help_text, const char *group, bool required, const char *env_var_name, bool(*validate)(const void *, char **), bool optional_arg)
Definition builder.c:779
void options_builder_add_int_with_metadata(options_builder_t *builder, const char *long_name, char short_name, size_t offset, int default_value, const char *help_text, const char *group, bool required, const char *env_var_name, bool(*validate)(const void *options_struct, char **error_msg), const option_metadata_t *metadata)
Add integer option with metadata (for numeric ranges and examples)
Definition builder.c:710
void options_builder_add_int(options_builder_t *builder, const char *long_name, char short_name, size_t offset, int default_value, const char *help_text, const char *group, bool required, const char *env_var_name, bool(*validate)(const void *, char **))
Definition builder.c:681
void options_builder_add_callback_with_metadata(options_builder_t *builder, const char *long_name, char short_name, size_t offset, const void *default_value, size_t value_size, bool(*parse_fn)(const char *, void *, char **), const char *help_text, const char *group, bool required, const char *env_var_name, bool optional_arg, const option_metadata_t *metadata)
Definition builder.c:916
void options_builder_add_string(options_builder_t *builder, const char *long_name, char short_name, size_t offset, const char *default_value, const char *help_text, const char *group, bool required, const char *env_var_name, bool(*validate)(const void *, char **))
Definition builder.c:742
@ 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_CALLBACK
Custom parser function.
Definition builder.h:166
@ OPTION_TYPE_BOOL
Boolean flag (–flag, no value)
Definition builder.h:162
void registry_init_size(void)
Initialize registry size and metadata.
Definition core.c:108
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_INVALID_PARAM
void action_check_update(void)
Check for updates and display results.
void action_show_capabilities(void)
Show terminal capabilities and exit.
void action_list_microphones(void)
List available microphone devices and exit.
void action_list_webcams(void)
List available webcam devices and exit.
void action_list_speakers(void)
List available speaker devices and exit.
registry_entry_t g_options_registry[2048]
Definition registry.c:51
size_t g_registry_size
Definition registry.c:53
#define false
Definition stdbool.h:63
int max
Maximum value (or 0 if no limit)
Definition builder.h:203
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
Registry entry - stores option definition with mode bitmask and metadata.
option_type_t type
bool optional_arg
const char * group
bool required
const char * long_name
size_t default_value_size
option_mode_bitmask_t mode_bitmask
const char * env_var_name
bool(* parse_fn)(const char *arg, void *dest, char **error_msg)
const void * default_value
Default value (single value for all modes, or NULL if mode_default_getter is set)
const char * arg_placeholder
Custom argument placeholder (e.g., "SHELL [FILE]" instead of "STR")
option_metadata_t metadata
Enum values, numeric ranges, examples.
char short_name
const char * help_text
size_t offset

References action_check_update(), action_list_microphones(), action_list_speakers(), action_list_webcams(), action_show_capabilities(), registry_entry_t::arg_placeholder, ASCIICHAT_OK, registry_entry_t::default_value, registry_entry_t::default_value_size, option_metadata_t::enum_values, registry_entry_t::env_var_name, ERROR_INVALID_PARAM, g_options_registry, g_registry_size, registry_entry_t::group, registry_entry_t::help_text, registry_entry_t::long_name, option_metadata_t::max, registry_entry_t::metadata, registry_entry_t::mode_bitmask, option_metadata_t::numeric_range, registry_entry_t::offset, OPTION_TYPE_ACTION, OPTION_TYPE_BOOL, OPTION_TYPE_CALLBACK, OPTION_TYPE_DOUBLE, OPTION_TYPE_INT, OPTION_TYPE_STRING, registry_entry_t::optional_arg, options_builder_add_action(), options_builder_add_bool(), options_builder_add_callback_with_metadata(), options_builder_add_double(), options_builder_add_double_with_metadata(), options_builder_add_int(), options_builder_add_int_with_metadata(), options_builder_add_string(), options_builder_set_arg_placeholder(), options_builder_set_mode_bitmask(), registry_entry_t::parse_fn, registry_init_size(), registry_entry_t::required, SET_ERRNO, registry_entry_t::short_name, registry_entry_t::type, and registry_entry_t::validate_fn.

Referenced by options_preset_unified().

◆ options_registry_find_by_name()

const option_descriptor_t * options_registry_find_by_name ( const char *  long_name)

Get option descriptor by name.

Looks up an option descriptor from the registry by its long name.

Parameters
long_nameLong option name (e.g., "port")
Returns
Pointer to option descriptor, or NULL if not found

Definition at line 141 of file public_api.c.

141 {
142 if (!long_name) {
143 SET_ERRNO(ERROR_INVALID_PARAM, "Long name is NULL");
144 return NULL;
145 }
146
148
149 const registry_entry_t *entry = registry_find_entry_by_name(long_name);
150 if (!entry) {
151 // Don't log error for binary-level options like "config" that aren't in registry
152 if (strcmp(long_name, "config") != 0) {
153 SET_ERRNO(ERROR_NOT_FOUND, "Option not found: %s", long_name);
154 }
155 return NULL;
156 }
157
158 /* Create descriptor from registry entry */
159 static option_descriptor_t desc;
160 desc.long_name = entry->long_name;
161 desc.short_name = entry->short_name;
162 desc.type = entry->type;
163 desc.offset = entry->offset;
164 desc.help_text = entry->help_text;
165 desc.group = entry->group;
166 desc.hide_from_mode_help = false;
167 desc.hide_from_binary_help = false;
168 desc.default_value = entry->default_value;
169 desc.required = entry->required;
170 desc.env_var_name = entry->env_var_name;
171 desc.validate = entry->validate_fn;
172 desc.parse_fn = entry->parse_fn;
173 desc.action_fn = NULL;
174 desc.owns_memory = entry->owns_memory;
175 desc.optional_arg = entry->optional_arg;
176 desc.mode_bitmask = entry->mode_bitmask;
177
178 return &desc;
179}
const registry_entry_t * registry_find_entry_by_name(const char *long_name)
Get a registry entry by long name.
Definition core.c:127
@ ERROR_NOT_FOUND
bool(* validate)(const void *options_struct, char **error_msg)
Definition builder.h:263
option_mode_bitmask_t mode_bitmask
Which modes this option applies to.
Definition builder.h:278
const char * help_text
Description for –help.
Definition builder.h:251
bool hide_from_mode_help
If true, don't show in mode-specific help (binary-level only)
Definition builder.h:254
size_t offset
offsetof(struct, field) - where to store value
Definition builder.h:248
bool hide_from_binary_help
If true, don't show in binary-level help (e.g., in release builds)
Definition builder.h:255
const char * env_var_name
Environment variable fallback (or NULL)
Definition builder.h:260
const char * group
Group name for help sections (e.g., "NETWORK OPTIONS")
Definition builder.h:252
const void * default_value
Pointer to default value (or NULL if required)
Definition builder.h:258
bool required
If true, option must be provided.
Definition builder.h:259
bool(* parse_fn)(const char *arg, void *dest, char **error_msg)
Definition builder.h:266
bool owns_memory
If true, strings are strdup'd and freed on cleanup.
Definition builder.h:272
const char * long_name
Long option name (e.g., "port")
Definition builder.h:243
char short_name
Short option char (e.g., 'p', or '\0' if none)
Definition builder.h:244
void(* action_fn)(void)
Action to execute (may call exit)
Definition builder.h:269
option_type_t type
Value type.
Definition builder.h:247
bool optional_arg
If true, argument is optional (for callbacks like –verbose)
Definition builder.h:275
bool owns_memory
bool(* validate_fn)(const void *options_struct, char **error_msg)

References option_descriptor_t::action_fn, option_descriptor_t::default_value, registry_entry_t::default_value, option_descriptor_t::env_var_name, registry_entry_t::env_var_name, ERROR_INVALID_PARAM, ERROR_NOT_FOUND, option_descriptor_t::group, registry_entry_t::group, option_descriptor_t::help_text, registry_entry_t::help_text, option_descriptor_t::hide_from_binary_help, option_descriptor_t::hide_from_mode_help, option_descriptor_t::long_name, registry_entry_t::long_name, option_descriptor_t::mode_bitmask, registry_entry_t::mode_bitmask, option_descriptor_t::offset, registry_entry_t::offset, option_descriptor_t::optional_arg, registry_entry_t::optional_arg, option_descriptor_t::owns_memory, registry_entry_t::owns_memory, option_descriptor_t::parse_fn, registry_entry_t::parse_fn, registry_find_entry_by_name(), registry_init_size(), option_descriptor_t::required, registry_entry_t::required, SET_ERRNO, option_descriptor_t::short_name, registry_entry_t::short_name, option_descriptor_t::type, registry_entry_t::type, option_descriptor_t::validate, and registry_entry_t::validate_fn.

◆ options_registry_find_by_short()

const option_descriptor_t * options_registry_find_by_short ( char  short_name)

Get option descriptor by short name.

Looks up an option descriptor from the registry by its short name.

Parameters
short_nameShort option character (e.g., 'p')
Returns
Pointer to option descriptor, or NULL if not found

Definition at line 181 of file public_api.c.

181 {
182 if (short_name == '\0') {
183 SET_ERRNO(ERROR_INVALID_PARAM, "Short name is empty");
184 return NULL;
185 }
186
188
189 const registry_entry_t *entry = registry_find_entry_by_short(short_name);
190 if (!entry) {
191 SET_ERRNO(ERROR_NOT_FOUND, "Option not found: -%c", short_name);
192 return NULL;
193 }
194
195 /* Create descriptor from registry entry */
196 static option_descriptor_t desc;
197 desc.long_name = entry->long_name;
198 desc.short_name = entry->short_name;
199 desc.type = entry->type;
200 desc.offset = entry->offset;
201 desc.help_text = entry->help_text;
202 desc.group = entry->group;
203 desc.hide_from_mode_help = false;
204 desc.hide_from_binary_help = false;
205 desc.default_value = entry->default_value;
206 desc.required = entry->required;
207 desc.env_var_name = entry->env_var_name;
208 desc.validate = entry->validate_fn;
209 desc.parse_fn = entry->parse_fn;
210 desc.action_fn = NULL;
211 desc.owns_memory = entry->owns_memory;
212 desc.optional_arg = entry->optional_arg;
213 desc.mode_bitmask = entry->mode_bitmask;
214
215 return &desc;
216}
const registry_entry_t * registry_find_entry_by_short(char short_name)
Get a registry entry by short name.
Definition core.c:145

References option_descriptor_t::action_fn, option_descriptor_t::default_value, registry_entry_t::default_value, option_descriptor_t::env_var_name, registry_entry_t::env_var_name, ERROR_INVALID_PARAM, ERROR_NOT_FOUND, option_descriptor_t::group, registry_entry_t::group, option_descriptor_t::help_text, registry_entry_t::help_text, option_descriptor_t::hide_from_binary_help, option_descriptor_t::hide_from_mode_help, option_descriptor_t::long_name, registry_entry_t::long_name, option_descriptor_t::mode_bitmask, registry_entry_t::mode_bitmask, option_descriptor_t::offset, registry_entry_t::offset, option_descriptor_t::optional_arg, registry_entry_t::optional_arg, option_descriptor_t::owns_memory, registry_entry_t::owns_memory, option_descriptor_t::parse_fn, registry_entry_t::parse_fn, registry_find_entry_by_short(), registry_init_size(), option_descriptor_t::required, registry_entry_t::required, SET_ERRNO, option_descriptor_t::short_name, registry_entry_t::short_name, option_descriptor_t::type, registry_entry_t::type, option_descriptor_t::validate, and registry_entry_t::validate_fn.

◆ options_registry_get_binary_options()

const option_descriptor_t * options_registry_get_binary_options ( size_t *  num_options)

Get all binary-level options.

Returns an array of all binary-level options (those with OPTION_MODE_BINARY). The array is allocated and must be freed by the caller.

Parameters
num_optionsOUTPUT: Number of options returned
Returns
Array of option descriptors (caller must free), or NULL on error

Definition at line 283 of file public_api.c.

283 {
284 if (!num_options) {
285 SET_ERRNO(ERROR_INVALID_PARAM, "Number of options is NULL");
286 return NULL;
287 }
288
290
291 /* Count binary-level options */
292 size_t count = 0;
293 for (size_t i = 0; i < g_registry_size; i++) {
294 if (g_options_registry[i].mode_bitmask & OPTION_MODE_BINARY) {
295 count++;
296 }
297 }
298
299 if (count == 0) {
300 *num_options = 0;
301 return NULL;
302 }
303
304 /* Allocate array for binary options */
306 if (!binary_opts) {
307 SET_ERRNO(ERROR_INVALID_STATE, "Failed to allocate binary options array");
308 *num_options = 0;
309 return NULL;
310 }
311
312 /* Copy binary options */
313 size_t idx = 0;
314 for (size_t i = 0; i < g_registry_size; i++) {
315 if (g_options_registry[i].mode_bitmask & OPTION_MODE_BINARY) {
316 binary_opts[idx++] = registry_entry_to_descriptor(&g_options_registry[i]);
317 }
318 }
319
320 *num_options = count;
321 return binary_opts;
322}
option_descriptor_t registry_entry_to_descriptor(const registry_entry_t *entry)
Convert registry entry to option descriptor.
Definition core.c:161
#define SAFE_MALLOC(size, cast)
Definition common.h:264
@ ERROR_INVALID_STATE

References ERROR_INVALID_PARAM, ERROR_INVALID_STATE, g_options_registry, g_registry_size, OPTION_MODE_BINARY, registry_entry_to_descriptor(), registry_init_size(), SAFE_MALLOC, and SET_ERRNO.

◆ options_registry_get_enum_values()

const char ** options_registry_get_enum_values ( const char *  option_name,
const char ***  descriptions,
size_t *  count 
)

Get enum values for an option.

Retrieves enum values and descriptions for an option that has OPTION_INPUT_ENUM type in its metadata.

Parameters
option_nameLong name of option
descriptionsOUTPUT: Pointer to descriptions array (or NULL if not needed)
countOUTPUT: Number of values/descriptions
Returns
Array of enum value strings, or NULL if not found or not an enum type

Example:

const char **values;
const char **descs;
size_t count;
values = options_registry_get_enum_values("color-mode", &descs, &count);
if (values) {
for (size_t i = 0; i < count; i++) {
printf("%s: %s\n", values[i], descs[i]);
}
}
const char ** options_registry_get_enum_values(const char *option_name, const char ***descriptions, size_t *count)
Get enum values for an option.
Definition public_api.c:391

Definition at line 391 of file public_api.c.

391 {
392 if (!option_name || !count) {
393 SET_ERRNO(ERROR_INVALID_PARAM, "Option name is NULL or count is NULL");
394 if (count)
395 *count = 0;
396 return NULL;
397 }
398
399 const option_metadata_t *meta = options_registry_get_metadata(option_name);
400 if (!meta || meta->input_type != OPTION_INPUT_ENUM || !meta->enum_values || meta->enum_values[0] == NULL) {
401 SET_ERRNO(ERROR_NOT_FOUND, "Option '%s' not found", option_name);
402 *count = 0;
403 if (descriptions)
404 *descriptions = NULL;
405 return NULL;
406 }
407
408 // Count enum values (NULL-terminated array)
409 size_t enum_count = 0;
410 while (meta->enum_values[enum_count] != NULL) {
411 enum_count++;
412 }
413
414 *count = enum_count;
415 if (descriptions) {
416 *descriptions = meta->enum_descriptions;
417 }
418 return meta->enum_values;
419}
@ OPTION_INPUT_ENUM
Choose from fixed set of enum values.
Definition builder.h:178
const char ** enum_descriptions
Descriptions parallel to enum_values (null-terminated, e.g., "Auto-detect from terminal")
Definition builder.h:197
option_input_type_t input_type
What kind of input this option expects.
Definition builder.h:214

References option_metadata_t::enum_descriptions, option_metadata_t::enum_values, ERROR_INVALID_PARAM, ERROR_NOT_FOUND, option_metadata_t::input_type, OPTION_INPUT_ENUM, options_registry_get_metadata(), and SET_ERRNO.

◆ options_registry_get_examples()

const char ** options_registry_get_examples ( const char *  option_name,
size_t *  count 
)

Get example values for an option.

Retrieves example values or command invocations for an option.

Parameters
option_nameLong name of option
countOUTPUT: Number of examples
Returns
Array of example strings, or NULL if no examples defined

Definition at line 441 of file public_api.c.

441 {
442 if (!option_name || !count) {
443 SET_ERRNO(ERROR_INVALID_PARAM, "Option name is NULL or count is NULL");
444 if (count)
445 *count = 0;
446 return NULL;
447 }
448
449 const option_metadata_t *meta = options_registry_get_metadata(option_name);
450 if (!meta || !meta->examples || meta->examples[0] == NULL) {
451 *count = 0;
452 return NULL;
453 }
454
455 // Count examples by finding NULL terminator
456 size_t example_count = 0;
457 for (size_t i = 0; meta->examples[i] != NULL; i++) {
458 example_count++;
459 }
460
461 *count = example_count;
462 return meta->examples;
463}
const char ** examples
Example values or command invocations (null-terminated array)
Definition builder.h:208

References ERROR_INVALID_PARAM, option_metadata_t::examples, options_registry_get_metadata(), and SET_ERRNO.

◆ options_registry_get_for_display()

const option_descriptor_t * options_registry_get_for_display ( asciichat_mode_t  mode,
bool  for_binary_help,
size_t *  num_options 
)

Get options for help/completions display with unified filtering.

Returns options filtered using the same logic as the help system. This ensures help output and completions are always in sync.

Uses the same filtering rules as options_print_help_for_mode():

  • For binary-level help (mode == MODE_DISCOVERY): shows all options that apply to any mode
  • For mode-specific help: shows only options for that mode (binary options excluded unless also mode-specific)
  • Respects hide_from_binary_help and hide_from_mode_help flags
Parameters
modeMode to filter for (use MODE_DISCOVERY for binary-level help)
for_binary_helpIf true, use binary-help filtering; if false, use mode-specific filtering
num_optionsOUTPUT: Number of options returned
Returns
Array of option descriptors (caller must free), or NULL on error
Note
This is the AUTHORITATIVE filtering function for both help and completions. Always use this function to ensure consistency across the application.

Definition at line 324 of file public_api.c.

325 {
326 if (!num_options) {
327 SET_ERRNO(ERROR_INVALID_PARAM, "num_options is NULL");
328 return NULL;
329 }
330
332
333 // Count matching options
334 size_t count = 0;
335 for (size_t i = 0; i < g_registry_size; i++) {
336 if (registry_entry_applies_to_mode(&g_options_registry[i], mode, for_binary_help)) {
337 count++;
338 }
339 }
340
341 if (count == 0) {
342 *num_options = 0;
343 return NULL;
344 }
345
346 // Allocate array
348 if (!descriptors) {
349 SET_ERRNO(ERROR_MEMORY, "Failed to allocate descriptors array");
350 *num_options = 0;
351 return NULL;
352 }
353
354 // Copy matching options
355 size_t idx = 0;
356 for (size_t i = 0; i < g_registry_size; i++) {
357 if (registry_entry_applies_to_mode(&g_options_registry[i], mode, for_binary_help)) {
358 descriptors[idx++] = registry_entry_to_descriptor(&g_options_registry[i]);
359 }
360 }
361
362 *num_options = count;
363 return descriptors;
364}
bool registry_entry_applies_to_mode(const registry_entry_t *entry, asciichat_mode_t mode, bool for_binary_help)
Check if an option applies to the given mode for display purposes.
Definition core.c:200
@ ERROR_MEMORY
Definition error_codes.h:56

References ERROR_INVALID_PARAM, ERROR_MEMORY, g_options_registry, g_registry_size, registry_entry_applies_to_mode(), registry_entry_to_descriptor(), registry_init_size(), SAFE_MALLOC, and SET_ERRNO.

Referenced by completions_generate_fish(), completions_generate_powershell(), and completions_generate_zsh().

◆ options_registry_get_for_mode()

const option_descriptor_t * options_registry_get_for_mode ( asciichat_mode_t  mode,
size_t *  num_options 
)

Get all options for a specific mode.

Returns an array of option descriptors that apply to the given mode. The array is allocated and must be freed by the caller.

Parameters
modeMode to filter by
num_optionsOUTPUT: Number of options returned
Returns
Array of option descriptors (caller must free), or NULL on error

Definition at line 218 of file public_api.c.

218 {
219 if (!num_options) {
220 SET_ERRNO(ERROR_INVALID_PARAM, "Number of options is NULL");
221 return NULL;
222 }
223
225
226 /* Convert mode to bitmask */
227 option_mode_bitmask_t mode_bitmask = 0;
228 switch (mode) {
229 case MODE_SERVER:
230 mode_bitmask = OPTION_MODE_SERVER;
231 break;
232 case MODE_CLIENT:
233 mode_bitmask = OPTION_MODE_CLIENT;
234 break;
235 case MODE_MIRROR:
236 mode_bitmask = OPTION_MODE_MIRROR;
237 break;
239 mode_bitmask = OPTION_MODE_DISCOVERY_SVC;
240 break;
241 case MODE_DISCOVERY:
242 mode_bitmask = OPTION_MODE_DISCOVERY;
243 break;
244 default:
245 SET_ERRNO(ERROR_INVALID_PARAM, "Invalid mode: %d", mode);
246 *num_options = 0;
247 return NULL;
248 }
249
250 /* Count matching options */
251 size_t count = 0;
252 for (size_t i = 0; i < g_registry_size; i++) {
253 if (g_options_registry[i].mode_bitmask & mode_bitmask) {
254 count++;
255 }
256 }
257
258 if (count == 0) {
259 *num_options = 0;
260 return NULL;
261 }
262
263 /* Allocate array for matching options */
265 if (!filtered) {
266 SET_ERRNO(ERROR_INVALID_STATE, "Failed to allocate filtered options array");
267 *num_options = 0;
268 return NULL;
269 }
270
271 /* Copy matching options */
272 size_t idx = 0;
273 for (size_t i = 0; i < g_registry_size; i++) {
274 if (g_options_registry[i].mode_bitmask & mode_bitmask) {
276 }
277 }
278
279 *num_options = count;
280 return filtered;
281}
option_mode_bitmask_t
Option mode bitmask.
@ MODE_DISCOVERY_SERVICE
Discovery server mode - session management and WebRTC signaling.
@ MODE_SERVER
Server mode - network server options.
@ MODE_MIRROR
Mirror mode - local webcam viewing (no network)
@ MODE_DISCOVERY
Discovery mode - participant that can dynamically become host.
@ OPTION_MODE_DISCOVERY
Discovery mode (bit 4)
@ OPTION_MODE_DISCOVERY_SVC
Discovery server mode (bit 3)

References ERROR_INVALID_PARAM, ERROR_INVALID_STATE, g_options_registry, g_registry_size, MODE_CLIENT, MODE_DISCOVERY, MODE_DISCOVERY_SERVICE, MODE_MIRROR, MODE_SERVER, OPTION_MODE_CLIENT, OPTION_MODE_DISCOVERY, OPTION_MODE_DISCOVERY_SVC, OPTION_MODE_MIRROR, OPTION_MODE_SERVER, registry_entry_to_descriptor(), registry_init_size(), SAFE_MALLOC, and SET_ERRNO.

Referenced by completions_collect_all_modes_unique().

◆ options_registry_get_input_type()

option_input_type_t options_registry_get_input_type ( const char *  option_name)

Get input type for an option.

Retrieves the input type (OPTION_INPUT_ENUM, OPTION_INPUT_NUMERIC, etc.) for the given option.

Parameters
option_nameLong name of option
Returns
Input type (OPTION_INPUT_NONE if not found)

Definition at line 465 of file public_api.c.

465 {
466 if (!option_name) {
467 SET_ERRNO(ERROR_INVALID_PARAM, "Option name is NULL");
468 return OPTION_INPUT_NONE;
469 }
470
471 const option_metadata_t *meta = options_registry_get_metadata(option_name);
472 if (!meta) {
473 SET_ERRNO(ERROR_NOT_FOUND, "Option '%s' not found", option_name);
474 return OPTION_INPUT_NONE;
475 }
476
477 return meta->input_type;
478}
@ OPTION_INPUT_NONE
No input (boolean flag)
Definition builder.h:177

References ERROR_INVALID_PARAM, ERROR_NOT_FOUND, option_metadata_t::input_type, OPTION_INPUT_NONE, options_registry_get_metadata(), and SET_ERRNO.

◆ options_registry_get_metadata()

const option_metadata_t * options_registry_get_metadata ( const char *  long_name)

Get complete metadata for an option.

Retrieves all completion metadata for the given option, including enum values, numeric ranges, examples, input type, etc.

Parameters
long_nameLong name of option to look up
Returns
Pointer to metadata structure, or NULL if option not found
Note
The returned pointer points to data within the registry and should not be modified or freed.

Definition at line 370 of file public_api.c.

370 {
371 if (!long_name) {
372 SET_ERRNO(ERROR_INVALID_PARAM, "Long name is NULL");
373 return NULL;
374 }
375
376 // Look up option in registry and return its metadata
378 for (size_t i = 0; i < g_registry_size; i++) {
379 const registry_entry_t *entry = &g_options_registry[i];
380 if (entry->long_name && strcmp(entry->long_name, long_name) == 0) {
381 // Return the metadata from the registry entry
382 return &entry->metadata;
383 }
384 }
385
386 // If not found, return empty metadata
387 static option_metadata_t empty_metadata = {0};
388 return &empty_metadata;
389}

References ERROR_INVALID_PARAM, g_options_registry, g_registry_size, registry_entry_t::long_name, registry_entry_t::metadata, registry_init_size(), and SET_ERRNO.

Referenced by options_registry_get_enum_values(), options_registry_get_examples(), options_registry_get_input_type(), and options_registry_get_numeric_range().

◆ options_registry_get_numeric_range()

bool options_registry_get_numeric_range ( const char *  option_name,
int *  min_out,
int *  max_out,
int *  step_out 
)

Get numeric range for an option.

Retrieves min/max/step values for an option that has OPTION_INPUT_NUMERIC type in its metadata.

Parameters
option_nameLong name of option
min_outOUTPUT: Minimum value (or 0 if no limit)
max_outOUTPUT: Maximum value (or 0 if no limit)
step_outOUTPUT: Step size (or 0 if continuous)
Returns
true if option found and has numeric range, false otherwise

Example:

int min, max, step;
if (options_registry_get_numeric_range("compression-level", &min, &max, &step)) {
printf("Range: %d-%d (step: %d)\n", min, max, step);
}
bool options_registry_get_numeric_range(const char *option_name, int *min_out, int *max_out, int *step_out)
Get numeric range for an option.
Definition public_api.c:421

Definition at line 421 of file public_api.c.

421 {
422 if (!option_name || !min_out || !max_out || !step_out) {
423 SET_ERRNO(ERROR_INVALID_PARAM, "Option name is NULL or min_out, max_out, or step_out is NULL");
424 return false;
425 }
426
427 const option_metadata_t *meta = options_registry_get_metadata(option_name);
428 if (!meta || meta->input_type != OPTION_INPUT_NUMERIC) {
429 *min_out = 0;
430 *max_out = 0;
431 *step_out = 0;
432 return false;
433 }
434
435 *min_out = meta->numeric_range.min;
436 *max_out = meta->numeric_range.max;
437 *step_out = meta->numeric_range.step;
438 return true;
439}
@ OPTION_INPUT_NUMERIC
Numeric value with optional min/max/step.
Definition builder.h:179
int min
Minimum value (or 0 if no limit)
Definition builder.h:202
int step
Step size (0 = no step, continuous)
Definition builder.h:204

References ERROR_INVALID_PARAM, option_metadata_t::input_type, option_metadata_t::max, option_metadata_t::min, option_metadata_t::numeric_range, OPTION_INPUT_NUMERIC, options_registry_get_metadata(), SET_ERRNO, and option_metadata_t::step.