ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
options/parsing/actions.c
Go to the documentation of this file.
1
14#include <string.h>
15#include <stddef.h>
16
18#include <ascii-chat/common.h>
19#include <ascii-chat/log/log.h>
29#include <ascii-chat/version.h>
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38
39// ============================================================================
40// Action Exit Helper
41// ============================================================================
42
50static _Noreturn void action_exit(int code) {
51 fflush(NULL);
52 _Exit(code);
53}
54
55// ============================================================================
56// Deferred Action Tracking System
57// ============================================================================
58
65static struct {
69} g_deferred_action_state = {
70 .action = ACTION_NONE,
71 .args = {0},
72 .has_action = false,
73};
74
76 // Only remember the first action found
77 if (g_deferred_action_state.has_action) {
78 return; // Action already deferred, ignore subsequent actions
79 }
80
81 g_deferred_action_state.action = action;
82 g_deferred_action_state.has_action = true;
83
84 // Copy arguments if provided
85 if (args) {
86 memcpy(&g_deferred_action_state.args, args, sizeof(action_args_t));
87 } else {
88 memset(&g_deferred_action_state.args, 0, sizeof(action_args_t));
89 }
90}
91
93 return g_deferred_action_state.action;
94}
95
97 if (!g_deferred_action_state.has_action) {
98 return NULL;
99 }
100 return &g_deferred_action_state.args;
101}
102
103// ============================================================================
104// Webcam Action
105// ============================================================================
106
108 // Defer execution until after options are fully parsed
110}
111
118static void execute_list_webcams(void) {
119 webcam_device_info_t *devices = NULL;
120 unsigned int device_count = 0;
121
122 asciichat_error_t result = webcam_list_devices(&devices, &device_count);
123 if (result != ASCIICHAT_OK) {
124 log_error("Failed to enumerate webcam devices");
125 action_exit(ERROR_WEBCAM);
126 }
127
128 if (device_count == 0) {
129 log_plain_stdout("No webcam devices found.");
130 } else {
131 log_plain_stdout("Available Webcam Devices:");
132 for (unsigned int i = 0; i < device_count; i++) {
133 log_plain_stdout(" %u %s", devices[i].index, devices[i].name);
134 }
135 }
136
138 action_exit(0);
139}
140
141// ============================================================================
142// Audio Device Actions
143// ============================================================================
144
146 // Defer execution until after options are fully parsed
148}
149
156static void execute_list_microphones(void) {
157 audio_device_info_t *devices = NULL;
158 unsigned int device_count = 0;
159
160 asciichat_error_t result = audio_list_input_devices(&devices, &device_count);
161 if (result != ASCIICHAT_OK) {
162 log_error("Failed to enumerate audio input devices");
163 action_exit(ERROR_AUDIO);
164 }
165
166 if (device_count == 0) {
167 log_plain_stdout("No microphone devices found.");
168 } else {
169 log_plain_stdout("Available Microphone Devices:");
170 for (unsigned int i = 0; i < device_count; i++) {
171 if (devices[i].is_default_input) {
172 log_plain_stdout(" %d %s (default)", devices[i].index, devices[i].name);
173 } else {
174 log_plain_stdout(" %d %s", devices[i].index, devices[i].name);
175 }
176 }
177 }
178
179 audio_free_device_list(devices);
180 action_exit(0);
181}
182
184 // Defer execution until after options are fully parsed
186}
187
194static void execute_list_speakers(void) {
195 audio_device_info_t *devices = NULL;
196 unsigned int device_count = 0;
197
198 asciichat_error_t result = audio_list_output_devices(&devices, &device_count);
199 if (result != ASCIICHAT_OK) {
200 log_error("Failed to enumerate audio output devices");
201 action_exit(ERROR_AUDIO);
202 }
203
204 if (device_count == 0) {
205 log_plain_stdout("No speaker devices found.");
206 } else {
207 log_plain_stdout("Available Speaker Devices:");
208 for (unsigned int i = 0; i < device_count; i++) {
209 if (devices[i].is_default_output) {
210 log_plain_stdout(" %d %s (default)", devices[i].index, devices[i].name);
211 } else {
212 log_plain_stdout(" %d %s", devices[i].index, devices[i].name);
213 }
214 }
215 }
216
217 audio_free_device_list(devices);
218 action_exit(0);
219}
220
221// ============================================================================
222// Terminal Capabilities Action
223// ============================================================================
224
230
231 // Determine if we should use colored output
232 bool use_colors = terminal_should_color_output(STDOUT_FILENO);
233
234 // Override color level if colors should not be shown
235 if (!use_colors) {
237 caps.color_count = 0;
239 }
240
241 // Use detected terminal size (immediate execution doesn't have parsed options yet)
242 terminal_size_t size;
243 terminal_get_size(&size);
244 unsigned short width = size.cols;
245 unsigned short height = size.rows;
246
247 log_color_t label_color = use_colors ? LOG_COLOR_DEBUG : LOG_COLOR_GREY;
248 log_color_t string_color = use_colors ? LOG_COLOR_DEBUG : LOG_COLOR_GREY;
249 log_color_t good_color = use_colors ? LOG_COLOR_INFO : LOG_COLOR_GREY;
250 log_color_t bad_color = use_colors ? LOG_COLOR_ERROR : LOG_COLOR_GREY;
251 log_color_t number_color = use_colors ? LOG_COLOR_DEBUG : LOG_COLOR_GREY;
252
253 printf("%s\n", colored_string(LOG_COLOR_WARN, "Terminal Capabilities:"));
254
255 char size_buf[64];
256 snprintf(size_buf, sizeof(size_buf), "%ux%u", width, height);
257 printf(" %s: %s\n", colored_string(label_color, "Terminal Size"), colored_string(number_color, size_buf));
258
259 const char *color_level_name = terminal_color_level_name(caps.color_level);
260 log_color_t color_level_color = (caps.color_level == TERM_COLOR_NONE) ? bad_color : string_color;
261 printf(" %s: %s\n", colored_string(label_color, "Color Level"),
262 colored_string(color_level_color, (char *)color_level_name));
263
264 char colors_buf[64];
265 snprintf(colors_buf, sizeof(colors_buf), "%u", caps.color_count);
266 printf(" %s: %s\n", colored_string(label_color, "Max Colors"), colored_string(number_color, colors_buf));
267
268 log_color_t utf8_color = caps.utf8_support ? good_color : bad_color;
269 printf(" %s: %s\n", colored_string(label_color, "UTF-8 Support"),
270 colored_string(utf8_color, (char *)(caps.utf8_support ? "Yes" : "No")));
271
272 const char *render_mode_str = "unknown";
274 render_mode_str = "foreground";
275 } else if (caps.render_mode == RENDER_MODE_BACKGROUND) {
276 render_mode_str = "background";
277 } else if (caps.render_mode == RENDER_MODE_HALF_BLOCK) {
278 render_mode_str = "half-block";
279 }
280 printf(" %s: %s\n", colored_string(label_color, "Render Mode"),
281 colored_string(string_color, (char *)render_mode_str));
282 printf(" %s: %s\n", colored_string(label_color, "TERM"), colored_string(string_color, (char *)caps.term_type));
283 printf(" %s: %s\n", colored_string(label_color, "COLORTERM"),
284 colored_string(string_color, (char *)(strlen(caps.colorterm) ? caps.colorterm : "(not set)")));
285
286 log_color_t reliable_color = caps.detection_reliable ? good_color : bad_color;
287 printf(" %s: %s\n", colored_string(label_color, "Detection Reliable"),
288 colored_string(reliable_color, (char *)(caps.detection_reliable ? "Yes" : "No")));
289
290 char bitmask_buf[64];
291 snprintf(bitmask_buf, sizeof(bitmask_buf), "0x%08x", caps.capabilities);
292 printf(" %s: %s\n", colored_string(label_color, "Capabilities Bitmask"), colored_string(number_color, bitmask_buf));
293
294 fflush(stdout);
295 action_exit(0);
296}
297
299 // Defer execution until after options are fully parsed and dimensions updated
300 // This ensures --width and --height flags are properly reflected in the output
302}
303
304// ============================================================================
305// Update Check Action
306// ============================================================================
307
312 printf("Checking for updates...\n");
315 if (err != ASCIICHAT_OK) {
316 printf("\nFailed to check for updates.\n\n");
317 action_exit(1);
318 }
319 if (result.update_available) {
320 char notification[1024];
321 update_check_format_notification(&result, notification, sizeof(notification));
322 printf("\n%s\n\n", notification);
323 } else {
324 printf("\nYou are already on the latest version: %s (%.8s)\n\n", result.current_version, result.current_sha);
325 }
326 action_exit(0);
327}
328
330 // Defer execution until after options are fully parsed
332}
333
344static void execute_show_capabilities(void) {
346
347 // Determine if we should use colored output
348 bool use_colors = terminal_should_color_output(STDOUT_FILENO);
349
350 // Override color level if colors should not be shown
351 if (!use_colors) {
352 // User requested no colors or output is piped or CLAUDECODE is set
354 caps.color_count = 0;
356 }
357
358 // Get width and height from parsed options (respects --width and --height flags)
359 const options_t *opts = options_get();
360 unsigned short width = opts ? opts->width : 110;
361 unsigned short height = opts ? opts->height : 70;
362
363 // Color scheme:
364 // - Labels: grey
365 // - Regular string values: blue (DEBUG - cyan/blue)
366 // - Affirmative values (Yes, true): green (INFO)
367 // - Bad/negative values (No, false, error): red (ERROR)
368 // - Numbers and hex: magenta (FATAL)
369 log_color_t label_color = use_colors ? LOG_COLOR_DEBUG : LOG_COLOR_GREY;
370 log_color_t string_color = use_colors ? LOG_COLOR_DEBUG : LOG_COLOR_GREY;
371 log_color_t good_color = use_colors ? LOG_COLOR_INFO : LOG_COLOR_GREY;
372 log_color_t bad_color = use_colors ? LOG_COLOR_ERROR : LOG_COLOR_GREY;
373 log_color_t number_color = use_colors ? LOG_COLOR_DEBUG : LOG_COLOR_GREY;
374
375 printf("%s\n", colored_string(LOG_COLOR_WARN, "Terminal Capabilities:"));
376
377 char size_buf[64];
378 snprintf(size_buf, sizeof(size_buf), "%ux%u", width, height);
379 printf(" %s: %s\n", colored_string(label_color, "Terminal Size"), colored_string(number_color, size_buf));
380
381 // Color Level: green if good, red if none/bad
382 const char *color_level_name = terminal_color_level_name(caps.color_level);
383 log_color_t color_level_color = (caps.color_level == TERM_COLOR_NONE) ? bad_color : string_color;
384 printf(" %s: %s\n", colored_string(label_color, "Color Level"),
385 colored_string(color_level_color, (char *)color_level_name));
386
387 char colors_buf[64];
388 snprintf(colors_buf, sizeof(colors_buf), "%u", caps.color_count);
389 printf(" %s: %s\n", colored_string(label_color, "Max Colors"), colored_string(number_color, colors_buf));
390
391 // UTF-8: green if Yes, red if No
392 log_color_t utf8_color = caps.utf8_support ? good_color : bad_color;
393 printf(" %s: %s\n", colored_string(label_color, "UTF-8 Support"),
394 colored_string(utf8_color, (char *)(caps.utf8_support ? "Yes" : "No")));
395
396 const char *render_mode_str = "unknown";
398 render_mode_str = "foreground";
399 } else if (caps.render_mode == RENDER_MODE_BACKGROUND) {
400 render_mode_str = "background";
401 } else if (caps.render_mode == RENDER_MODE_HALF_BLOCK) {
402 render_mode_str = "half-block";
403 }
404 printf(" %s: %s\n", colored_string(label_color, "Render Mode"),
405 colored_string(string_color, (char *)render_mode_str));
406 printf(" %s: %s\n", colored_string(label_color, "TERM"), colored_string(string_color, (char *)caps.term_type));
407 printf(" %s: %s\n", colored_string(label_color, "COLORTERM"),
408 colored_string(string_color, (char *)(strlen(caps.colorterm) ? caps.colorterm : "(not set)")));
409
410 // Detection Reliable: green if Yes, red if No
411 log_color_t reliable_color = caps.detection_reliable ? good_color : bad_color;
412 printf(" %s: %s\n", colored_string(label_color, "Detection Reliable"),
413 colored_string(reliable_color, (char *)(caps.detection_reliable ? "Yes" : "No")));
414
415 char bitmask_buf[64];
416 snprintf(bitmask_buf, sizeof(bitmask_buf), "0x%08x", caps.capabilities);
417 printf(" %s: %s\n", colored_string(label_color, "Capabilities Bitmask"), colored_string(number_color, bitmask_buf));
418
419 fflush(stdout);
420
421 action_exit(0);
422}
423
424// ============================================================================
425// Version Action
426// ============================================================================
427
429 bool use_colors = terminal_should_color_output(STDOUT_FILENO);
430 if (use_colors) {
431 printf("%s %s (%s, %s)\n", colored_string(LOG_COLOR_WARN, "ascii-chat"),
435 } else {
436 printf("ascii-chat %s (%s, %s)\n", ASCII_CHAT_VERSION_FULL, ASCII_CHAT_BUILD_TYPE, ASCII_CHAT_BUILD_DATE);
437 }
438
439 action_exit(0);
440}
441
442// ============================================================================
443// Help Actions
444// ============================================================================
445
447 usage(stdout, MODE_SERVER);
448 action_exit(0);
449}
450
452 usage(stdout, MODE_CLIENT);
453 action_exit(0);
454}
455
457 usage(stdout, MODE_MIRROR);
458 action_exit(0);
459}
460
463 action_exit(0);
464}
465
467 usage(stdout, MODE_DISCOVERY);
468 action_exit(0);
469}
470
471// ============================================================================
472// Man Page Generation Action
473// ============================================================================
474
475void action_create_manpage(const char *output_path) {
476 // Get binary-level config
477 const options_config_t *config = options_preset_unified(NULL, NULL);
478
479 if (!config) {
480 log_error("Failed to get binary options config");
481 action_exit(ERROR_FILE_OPERATION);
482 }
483
484 // Determine output path: use provided path, or NULL for stdout
485 const char *path_to_use = NULL;
486 if (output_path && strlen(output_path) > 0 && strcmp(output_path, "-") != 0) {
487 // User provided explicit path - use it
488 path_to_use = output_path;
489 } else {
490 // No path or "-" means stdout
491 path_to_use = NULL;
492 }
493
494 // Generate merged man page from embedded or filesystem resources
495 // Resources are loaded automatically based on build type:
496 // - Production (Release): From embedded binary data
497 // - Development (Debug): From filesystem files
499 options_config_generate_manpage_merged(config, "ascii-chat", NULL, path_to_use, "Video chat in your terminal");
500
501 if (err != ASCIICHAT_OK) {
503 if (HAS_ERRNO(&err_ctx)) {
504 log_error("%s", err_ctx.context_message);
505 } else {
506 log_error("Failed to generate man page");
507 }
508 action_exit(ERROR_FILE_OPERATION);
509 }
510
511 if (path_to_use) {
512 log_info("Man page written to: %s", path_to_use);
513 } else {
514 log_info("Man page written to stdout");
515 }
516
517 action_exit(0);
518}
519
520// ============================================================================
521// Config Creation Action
522// ============================================================================
523
524void action_create_config(const char *output_path) {
525 // Build the schema first so config_create_default can generate options from it
526 const options_config_t *unified_config = options_preset_unified(NULL, NULL);
527 if (unified_config) {
528 asciichat_error_t schema_build_result = config_schema_build_from_configs(&unified_config, 1);
529 if (schema_build_result != ASCIICHAT_OK) {
530 // Schema build failed, but continue anyway
531 (void)schema_build_result;
532 }
533 // options_config_destroy(unified_config);
534 }
535
536 const char *config_path = NULL;
537
538 // Determine output path: use provided path, or NULL for stdout
539 if (output_path && strlen(output_path) > 0 && strcmp(output_path, "-") != 0) {
540 // User provided explicit path - use it as-is
541 config_path = output_path;
542 } else {
543 // No path or "-" means stdout
544 config_path = NULL;
545 }
546
547 // Create config with default options
548 asciichat_error_t result = config_create_default(config_path);
549 if (result != ASCIICHAT_OK) {
551 if (HAS_ERRNO(&err_ctx)) {
552 log_error("Error creating config: %s", err_ctx.context_message);
553 } else {
554 log_error("Failed to create config file");
555 }
556 action_exit(ERROR_CONFIG);
557 }
558
559 if (config_path) {
560 log_info("Created default config file at: %s", config_path);
561 } else {
562 log_info("Config written to stdout");
563 }
564 action_exit(0);
565}
566
567// ============================================================================
568// Shell Completions Action
569// ============================================================================
570
571void action_completions(const char *shell_name, const char *output_path) {
572 if (!shell_name || strlen(shell_name) == 0) {
573 log_error("--completions requires shell name (bash, fish, zsh, powershell)");
574 action_exit(ERROR_USAGE);
575 }
576
578 if (format == COMPLETION_FORMAT_UNKNOWN) {
579 log_error("Unknown shell '%s' (supported: bash, fish, zsh, powershell)", shell_name);
580 action_exit(ERROR_USAGE);
581 }
582
583 FILE *output = stdout;
584 bool should_close = false;
585
586 // Determine output: use provided path if given and not "-", otherwise stdout
587 if (output_path && strlen(output_path) > 0 && strcmp(output_path, "-") != 0) {
588 // Check if file already exists and prompt for confirmation
589 struct stat st;
590 if (stat(output_path, &st) == 0) {
591 // File exists - ask user if they want to overwrite
592 log_plain("Completions file already exists: %s", output_path);
593
594 bool overwrite = platform_prompt_yes_no("Overwrite", false); // Default to No
595 if (!overwrite) {
596 log_plain("Completions generation cancelled.");
597 action_exit(0);
598 }
599
600 log_plain("Overwriting existing completions file...");
601 }
602
603 output = platform_fopen("file_stream", output_path, "w");
604 if (!output) {
605 log_error("Failed to open %s for writing", output_path);
606 action_exit(ERROR_FILE_OPERATION);
607 }
608 should_close = true;
609 }
610
611 asciichat_error_t result = completions_generate_for_shell(format, output);
612
613 if (should_close) {
614 fclose(output);
615 }
616
617 if (result != ASCIICHAT_OK) {
618 log_error("Failed to generate %s completions", completions_get_shell_name(format));
619 action_exit(ERROR_USAGE);
620 }
621
622 // Silently exit - completions are written (either to file or stdout)
623 action_exit(0);
624}
625
632static void execute_check_update(void) {
633 printf("Checking for updates...\n");
634
637
638 if (err != ASCIICHAT_OK) {
640 if (HAS_ERRNO(&ctx)) {
641 fprintf(stderr, "Update check failed: %s\n", ctx.context_message);
642 }
643 action_exit(1);
644 }
645
646 // Display results
647 if (result.update_available) {
648 char notification[1024];
649 update_check_format_notification(&result, notification, sizeof(notification));
650 printf("\n%s\n\n", notification);
651 } else {
652 printf("\nYou are already on the latest version: %s (%.8s)\n\n", result.current_version, result.current_sha);
653 }
654
655 action_exit(0);
656}
657
658// ============================================================================
659// Deferred Action Execution
660// ============================================================================
661
664
665 switch (action) {
666 case ACTION_NONE:
667 // No action to execute
668 break;
669
671 execute_list_webcams();
672 break;
673
675 execute_list_microphones();
676 break;
677
679 execute_list_speakers();
680 break;
681
683 execute_show_capabilities();
684 break;
685
687 execute_check_update();
688 break;
689
690 default:
691 log_warn("Unknown deferred action: %d", action);
692 break;
693 }
694}
Action option callbacks for ascii-chat.
deferred_action_t
Action type enumeration.
Definition actions.h:17
@ ACTION_CHECK_UPDATE
Definition actions.h:23
@ ACTION_LIST_SPEAKERS
Definition actions.h:21
@ ACTION_LIST_MICROPHONES
Definition actions.h:20
@ ACTION_NONE
Definition actions.h:18
@ ACTION_LIST_WEBCAMS
Definition actions.h:19
@ ACTION_SHOW_CAPABILITIES
Definition actions.h:22
⚠️‼️ Comprehensive thread-local error context system for ascii-chat
⚙️ Common definitions, error codes, macros, and types shared throughout the application
completion_format_t completions_parse_shell_name(const char *shell_name)
Parse shell name string to completion format.
Definition completions.c:54
asciichat_error_t completions_generate_for_shell(completion_format_t format, FILE *output)
Generate shell completions and write to output stream.
Definition completions.c:20
const char * completions_get_shell_name(completion_format_t format)
Get human-readable shell name for format.
Definition completions.c:39
Auto-generated shell completions from options registry.
completion_format_t
Supported shell completion formats.
Definition completions.h:66
@ COMPLETION_FORMAT_UNKNOWN
Definition completions.h:71
TOML configuration file support for ascii-chat.
void audio_free_device_list(audio_device_info_t *devices)
Free device list allocated by audio_list_input_devices/audio_list_output_devices.
asciichat_error_t audio_list_input_devices(audio_device_info_t **out_devices, unsigned int *out_count)
List available audio input devices (microphones)
asciichat_error_t audio_list_output_devices(audio_device_info_t **out_devices, unsigned int *out_count)
List available audio output devices (speakers)
unsigned int uint32_t
Definition common.h:58
asciichat_error_t config_create_default(const char *config_path)
Create default configuration file with all default values.
Definition config.c:1254
#define HAS_ERRNO(var)
Check if an error occurred and get full context.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ERROR_AUDIO
Definition error_codes.h:67
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_CONFIG
Definition error_codes.h:57
@ ERROR_FILE_OPERATION
@ ERROR_USAGE
Definition error_codes.h:53
@ ERROR_WEBCAM
Definition error_codes.h:64
#define log_warn(...)
Log a WARN message.
Definition log/log.h:574
log_color_t
Color enum for logging - indexes into color arrays.
Definition log/log.h:130
#define log_error(...)
Log an ERROR message.
Definition log/log.h:587
#define log_plain_stdout(...)
Plain logging to stdout with newline.
Definition log/log.h:632
#define log_info(...)
Log an INFO message.
Definition log/log.h:561
#define log_plain(...)
Plain logging - writes to both log file and stderr without timestamps or log levels.
Definition log/log.h:618
@ LOG_COLOR_GREY
Definition log/log.h:137
@ LOG_COLOR_ERROR
Definition log/log.h:135
@ LOG_COLOR_DEBUG
Definition log/log.h:132
@ LOG_COLOR_INFO
Definition log/log.h:133
@ LOG_COLOR_WARN
Definition log/log.h:134
asciichat_error_t update_check_perform(update_check_result_t *result)
Check for updates from GitHub releases API.
void update_check_format_notification(const update_check_result_t *result, char *buffer, size_t buffer_size)
Format update notification message.
const options_t * options_get(void)
Get current options (lock-free read)
Definition rcu.c:496
void usage(FILE *desc, asciichat_mode_t mode)
Print usage information for a specific mode.
asciichat_error_t options_config_generate_manpage_merged(const options_config_t *config, const char *program_name, const char *mode_name, const char *output_path, const char *brief_description)
Generate merged man page template preserving manual content.
@ MODE_CLIENT
Client mode - network client options.
@ 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.
bool platform_prompt_yes_no(const char *question, bool default_yes)
Prompt the user for a yes/no answer.
Definition util.c:83
asciichat_error_t terminal_get_size(terminal_size_t *size)
Get terminal size.
FILE * platform_fopen(const char *name, const char *filename, const char *mode)
Safe file open stream (fopen replacement)
const char * colored_string(log_color_t color, const char *text)
Build a colored string for terminal output.
asciichat_error_t webcam_list_devices(webcam_device_info_t **out_devices, unsigned int *out_count)
Enumerate available webcam devices.
void webcam_free_device_list(webcam_device_info_t *devices)
Free device list returned by webcam_list_devices()
🔊 Audio Capture and Playback Interface for ascii-chat
📝 Logging API with multiple log levels and terminal output control
Man page template generation from options builder.
void action_check_update_immediate(void)
Execute update check immediately (for early binary-level execution)
const action_args_t * actions_get_args(void)
Get the arguments for the deferred action.
void action_check_update(void)
Check for updates and display results.
deferred_action_t actions_get_deferred(void)
Get the deferred action (if any) that was set.
void actions_defer(deferred_action_t action, const action_args_t *args)
Set which action to defer until options are fully initialized.
bool has_action
void action_help_acds(void)
Show discovery-service mode help and exit.
void action_show_capabilities(void)
Show terminal capabilities and exit.
void action_help_server(void)
Show server mode help and exit.
void action_help_discovery(void)
Show discovery mode help and exit.
action_args_t args
void action_create_manpage(const char *output_path)
Generate man page template from options builder.
void action_completions(const char *shell_name, const char *output_path)
Generate shell completions and output to stdout or file.
deferred_action_t action
void action_list_microphones(void)
List available microphone devices and exit.
void action_show_version(void)
Show version information and exit.
void action_help_mirror(void)
Show mirror mode help and exit.
void action_create_config(const char *output_path)
Create default configuration file and exit.
void action_list_webcams(void)
List available webcam devices and exit.
void action_list_speakers(void)
List available speaker devices and exit.
void action_help_client(void)
Show client mode help and exit.
void actions_execute_deferred(void)
Execute the deferred action (if any)
void action_show_capabilities_immediate(void)
Execute show capabilities immediately (for early binary-level execution)
📂 Path Manipulation Utilities
bool terminal_should_color_output(int fd)
Determine if color output should be used.
terminal_capabilities_t detect_terminal_capabilities(void)
Detect terminal capabilities.
options_config_t * options_preset_unified(const char *program_name, const char *description)
Build unified options config with ALL options (binary + all modes)
Definition presets.c:51
Preset option configurations for ascii-chat modes.
Cross-platform interactive prompting utilities.
asciichat_error_t config_schema_build_from_configs(const options_config_t **configs, size_t num_configs)
Build schema dynamically from options builder configs.
Definition schema.c:240
Schema metadata for config file options.
Cross-platform stat and file type checking macros.
Action argument structure.
Definition actions.h:31
Error context structure.
char * context_message
Optional custom message (dynamically allocated, owned by system)
Audio device information structure.
Options configuration.
Definition builder.h:401
Consolidated options structure.
int height
Terminal height in characters (int for OPTION_TYPE_INT compat)
int width
Terminal width in characters (int for OPTION_TYPE_INT compat)
Complete terminal capabilities structure.
Definition terminal.h:709
terminal_color_mode_t color_level
Detected color support level (terminal_color_mode_t)
Definition terminal.h:711
render_mode_t render_mode
Preferred rendering mode (render_mode_t)
Definition terminal.h:721
bool utf8_support
True if terminal supports UTF-8 encoding.
Definition terminal.h:717
uint32_t capabilities
Capability flags bitmask (terminal_capability_flags_t)
Definition terminal.h:713
uint32_t color_count
Maximum number of colors (2, 16, 256, or 16777216)
Definition terminal.h:715
char term_type[64]
$TERM environment variable value (for debugging)
Definition terminal.h:723
char colorterm[64]
$COLORTERM environment variable value (for debugging)
Definition terminal.h:725
bool detection_reliable
True if detection is confident (reliable detection)
Definition terminal.h:719
Terminal size structure.
Definition terminal.h:163
int cols
Number of columns (width) in terminal.
Definition terminal.h:165
int rows
Number of rows (height) in terminal.
Definition terminal.h:164
Update check result data.
char current_sha[41]
Current commit SHA.
char current_version[64]
Current version string.
bool update_available
True if newer version exists.
Webcam device information structure.
Definition webcam.h:86
🖥️ Cross-platform terminal interface for ascii-chat
const char * terminal_color_level_name(terminal_color_mode_t level)
Get name of color level.
@ TERM_CAP_COLOR_256
256-color support (TERM_CAP_COLOR_256)
Definition terminal.h:643
@ TERM_CAP_COLOR_16
16-color support (TERM_CAP_COLOR_16)
Definition terminal.h:641
@ TERM_CAP_COLOR_TRUE
Truecolor support (TERM_CAP_COLOR_TRUE)
Definition terminal.h:645
@ RENDER_MODE_FOREGROUND
Foreground colors only (text color)
Definition terminal.h:664
@ RENDER_MODE_BACKGROUND
Background colors (block colors)
Definition terminal.h:666
@ RENDER_MODE_HALF_BLOCK
Unicode half-block characters (mixed foreground/background)
Definition terminal.h:668
@ TERM_COLOR_NONE
No color support (monochrome terminal)
Definition terminal.h:582
🔄 Update checker for GitHub releases with DNS connectivity test and cache
🔤 String Manipulation and Shell Escaping Utilities
#define ASCII_CHAT_VERSION_FULL
Definition version.h:21
#define ASCII_CHAT_BUILD_TYPE
Definition version.h:14
#define ASCII_CHAT_BUILD_DATE
Definition version.h:16