26static bool parse_verbose_flag(
const char *arg,
void *dest,
char **error_msg) {
29 unsigned short int *verbose_level = (
unsigned short int *)dest;
31 if (!arg || arg[0] ==
'\0') {
39 long value = strtol(arg, &endptr, 10);
40 if (*endptr ==
'\0' && value >= 0 && value <= 100) {
41 *verbose_level = (
unsigned short int)value;
58 false,
"ASCII_CHAT_LOG_FILE", NULL);
63 "Set log level: dev, debug, info, warn, error, fatal",
"LOGGING",
false, NULL);
66 &(
unsigned short int){0},
67 sizeof(
unsigned short int), parse_verbose_flag,
68 "Increase log verbosity (stackable: -VV, -VVV, or --verbose)",
"LOGGING",
false,
73 "Disable console logging (log to file only)",
"LOGGING",
false, NULL);
86 "Terminal width in characters",
"TERMINAL",
false, NULL, NULL);
89 "Terminal height in characters",
"TERMINAL",
false, NULL, NULL);
98 "Webcam device index",
"WEBCAM",
false, NULL, NULL);
101 "Flip webcam horizontally",
"WEBCAM",
false, NULL);
104 "Use test pattern instead of webcam",
"WEBCAM",
false,
"WEBCAM_DISABLED");
115 "Terminal color level (auto, none, 16, 256, truecolor)",
"DISPLAY",
false, NULL);
120 "Render mode (foreground, background, half-block)",
"DISPLAY",
false, NULL);
125 "ASCII palette type (standard, blocks, digital, minimal, cool, custom)",
"DISPLAY",
false, NULL);
129 "Custom palette characters (implies --palette=custom)",
"DISPLAY",
false, NULL);
132 "Show terminal capabilities and exit",
"DISPLAY",
false, NULL);
138 "DISPLAY",
false, NULL);
141 "DISPLAY",
false, NULL);
144 "DISPLAY",
false, NULL, NULL);
153 "Snapshot mode (one frame and exit)",
"SNAPSHOT",
false, NULL);
156 "Snapshot delay in seconds",
"SNAPSHOT",
false, NULL, NULL);
173 "PERFORMANCE",
false, NULL);
176 "Enable Opus audio encoding",
"PERFORMANCE",
false, NULL);
179 "Disable Opus audio encoding",
"PERFORMANCE",
false, NULL);
193 "SECURITY",
false, NULL);
196 false,
"ASCII_CHAT_KEY", NULL);
199 "Shared password for authentication",
"SECURITY",
false,
"ASCII_CHAT_PASSWORD", NULL);
202 "SECURITY",
false, NULL, NULL);
216static void add_port_option(
options_builder_t *b,
const char *default_port,
const char *env_var) {
231 "ACDS discovery server address (default: 127.0.0.1)",
"DISCOVERY",
false, NULL, NULL);
234 "DISCOVERY",
false, NULL, NULL);
237 "Use WebRTC P2P mode (default: Direct TCP)",
"DISCOVERY",
false, NULL);
249static const char *g_server_bind_address_examples[] = {
250 "(none) bind to 127.0.0.1 and ::1 (localhost)",
251 "192.168.1.100 bind to IPv4 address only",
":: bind to all IPv6 addresses",
252 "0.0.0.0 bind to all IPv4 addresses",
253 "192.168.1.100 :: bind to IPv4 and IPv6 (dual-stack)"};
260static const char *g_client_address_examples[] = {
261 "(none) connect to localhost:27224",
262 "hostname connect to hostname:27224",
263 "hostname:port connect to hostname:port",
264 "192.168.1.1 connect to IPv4:27224",
265 "192.168.1.1:8080 connect to IPv4:port",
266 "::1 connect to IPv6:27224",
267 "[::1]:8080 connect to IPv6:port (brackets required with port)"};
279 b->
program_name = program_name ? program_name :
"ascii-chat";
280 b->
description = description ? description :
"Video chat in your terminal";
286 "GENERAL",
false, NULL);
289 add_binary_logging_options(b);
306 b->
program_name = program_name ? program_name :
"ascii-chat server";
307 b->
description = description ? description :
"Start ascii-chat server";
314 "Maximum concurrent clients",
"NETWORK",
false,
"ASCII_CHAT_MAX_CLIENTS", NULL);
317 add_compression_options(b);
320 "Disable audio mixer (debug)",
"PERFORMANCE",
false, NULL);
323 add_crypto_common_options(b);
326 "Allowed client keys whitelist",
"SECURITY",
false, NULL, NULL);
329 "Explicitly allow public IP disclosure in ACDS sessions (requires ACDS, opt-in only)",
330 "SECURITY",
false, NULL);
333 "SECURITY",
false, NULL);
337 "Enable ACDS session registration (requires --key or --password or --acds-expose-ip)",
338 "DISCOVERY",
false, NULL);
341 add_acds_discovery_options(b);
344 "Enable UPnP/NAT-PMP for automatic port mapping (enables direct TCP for most home users)",
345 "DISCOVERY",
false,
"ASCII_CHAT_UPNP");
348 "Disable UPnP/NAT-PMP port mapping (requires manual port forwarding)",
"DISCOVERY",
false,
352 "Disable mDNS service advertisement on local network (LAN discovery won't find this server)",
353 "DISCOVERY",
false, NULL);
357 add_binary_logging_options(b);
364 "Cannot use --no-compress with --compression-level");
366 "Cannot use both --encode-audio and --no-encode-audio");
375 "List available microphone devices and exit",
"ACTIONS");
385 "BIND ADDRESS FORMATS", g_server_bind_address_examples,
386 sizeof(g_server_bind_address_examples) /
sizeof(g_server_bind_address_examples[0]),
404 b->
program_name = program_name ? program_name :
"ascii-chat client";
405 b->
description = description ? description :
"Connect to ascii-chat server";
412 "Reconnection attempts (-1=infinite)",
"NETWORK",
false, NULL, NULL);
415 "Scan for ASCII-Chat servers on local network (mDNS)",
"NETWORK",
false, NULL);
418 add_terminal_dimension_options(b);
419 add_webcam_options(b);
420 add_display_options(b);
421 add_snapshot_options(b);
425 "AUDIO",
false, NULL);
432 "Speakers device index (-1=default)",
"AUDIO",
false, NULL, NULL);
435 "Enable audio analysis (debug)",
"AUDIO",
false, NULL);
438 "Disable speaker playback (debug)",
"AUDIO",
false, NULL);
441 add_compression_options(b);
444 add_acds_discovery_options(b);
448 "Try WebRTC before Direct TCP (useful when Direct TCP fails)",
"NETWORK",
false, NULL);
451 "Disable WebRTC, use Direct TCP only",
"NETWORK",
false, NULL);
454 "Skip WebRTC+STUN stage, go straight to TURN relay",
"NETWORK",
false, NULL);
457 "Disable WebRTC+TURN relay, use STUN only",
"NETWORK",
false, NULL);
462 "Comma-separated STUN server URLs (debug/test only - ACDS provides in production)",
463 "WEBRTC",
false,
"ASCII_CHAT_STUN_SERVERS", NULL);
466 "Comma-separated TURN server URLs (debug/test only - ACDS provides in production)",
467 "WEBRTC",
false,
"ASCII_CHAT_TURN_SERVERS", NULL);
470 "TURN authentication username (debug/test only - ACDS provides in production)",
"WEBRTC",
471 false,
"ASCII_CHAT_TURN_USERNAME", NULL);
474 "TURN authentication credential (debug/test only - ACDS provides in production)",
"WEBRTC",
475 false,
"ASCII_CHAT_TURN_CREDENTIAL", NULL);
478 add_crypto_common_options(b);
481 "SECURITY",
false, NULL, NULL);
484 "Skip server key verification (MITM-vulnerable, requires explicit opt-in)",
"SECURITY",
489 add_binary_logging_options(b);
493 "Option --snapshot-delay requires --snapshot");
495 "Cannot use --no-compress with --compression-level");
497 "Cannot use both --encode-audio and --no-encode-audio");
506 "List available microphone devices and exit",
"ACTIONS");
512 "Show terminal capabilities and exit",
"ACTIONS");
516 b,
"address",
"[address][:port] - Server address (IPv4, IPv6, or hostname) with optional port",
518 "ADDRESS FORMATS", g_client_address_examples,
519 sizeof(g_client_address_examples) /
sizeof(g_client_address_examples[0]),
parse_client_address);
536 b->
program_name = program_name ? program_name :
"ascii-chat mirror";
537 b->
description = description ? description :
"Local webcam viewing (no network)";
540 add_terminal_dimension_options(b);
541 add_webcam_options(b);
542 add_display_options(b);
543 add_snapshot_options(b);
547 add_binary_logging_options(b);
551 "Option --snapshot-delay requires --snapshot");
560 "Show terminal capabilities and exit",
"ACTIONS");
577 b->
program_name = program_name ? program_name :
"ascii-chat discovery service";
578 b->
description = description ? description :
"session management and WebRTC signaling";
585 add_port_option(b,
"27225",
"ACDS_PORT");
589 "Path to ACDS identity key file (default: ~/.ascii-chat/acds_identity)",
"ACDS",
false,
590 "ACDS_KEY_PATH", NULL);
593 "Path to ACDS database file (default: ~/.ascii-chat/acds.db)",
"ACDS",
false,
594 "ACDS_DATABASE_PATH", NULL);
599 false,
"ASCII_CHAT_LOG_FILE", NULL);
603 "Set log level: dev, debug, info, warn, error, fatal",
"LOGGING",
false, NULL);
607 "SECURITY",
false, NULL);
610 false,
"ASCII_CHAT_KEY", NULL);
613 "Shared password for authentication",
"SECURITY",
false,
"ASCII_CHAT_PASSWORD", NULL);
616 "SECURITY",
false, NULL, NULL);
619 "SECURITY",
false, NULL);
623 "Require servers to provide signed Ed25519 identity when creating sessions",
"SECURITY",
627 "Require clients to provide signed Ed25519 identity when joining sessions",
"SECURITY",
631 "ACDS policy: require servers to verify client identity during handshake",
"SECURITY",
false,
635 "ACDS policy: require clients to verify server identity during handshake",
"SECURITY",
false,
640 "stun:stun.ascii-chat.com:3478,stun:stun.l.google.com:19302",
641 "Comma-separated list of STUN server URLs",
"WEBRTC",
false,
"ASCII_CHAT_STUN_SERVERS",
645 "turn:turn.ascii-chat.com:3478",
"Comma-separated list of TURN server URLs",
"WEBRTC",
646 false,
"ASCII_CHAT_TURN_SERVERS", NULL);
649 "Username for TURN server authentication",
"WEBRTC",
false,
"ASCII_CHAT_TURN_USERNAME",
653 "0aa9917b4dad1b01631e87a32b875e09",
"Credential/password for TURN server authentication",
654 "WEBRTC",
false,
"ASCII_CHAT_TURN_CREDENTIAL", NULL);
657 "Shared secret for dynamic TURN credential generation (HMAC-SHA1)",
"WEBRTC",
false,
658 "ASCII_CHAT_TURN_SECRET", NULL);
661 "Enable UPnP/NAT-PMP for automatic port mapping (enables direct TCP for most home users)",
662 "WEBRTC",
false,
"ASCII_CHAT_UPNP");
665 "Disable UPnP/NAT-PMP port mapping (requires manual port forwarding)",
"WEBRTC",
false,
674 "BIND ADDRESS FORMATS", g_server_bind_address_examples,
675 sizeof(g_server_bind_address_examples) /
sizeof(g_server_bind_address_examples[0]),
void action_show_capabilities(void)
Show terminal capabilities and exit.
void action_help_server(void)
Show server mode help and exit.
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_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.
Action option callbacks for ascii-chat.
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 **))
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)
void options_builder_add_callback_optional(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)
Add callback option with optional argument support.
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.
void options_builder_add_dependency_requires(options_builder_t *builder, const char *option_name, const char *depends_on, const char *error_message)
Add dependency: if option_name is set, depends_on must be set.
void options_builder_add_dependency_conflicts(options_builder_t *builder, const char *option_name, const char *conflicts_with, const char *error_message)
Add anti-dependency: if option_name is set, conflicts_with must NOT be set.
void options_builder_add_callback(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)
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 **))
void options_builder_destroy(options_builder_t *builder)
Free options builder.
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 **))
options_config_t * options_builder_build(options_builder_t *builder)
Build immutable options config.
void options_builder_add_positional(options_builder_t *builder, const char *name, const char *help_text, bool required, const char *section_heading, const char **examples, size_t num_examples, int(*parse_fn)(const char *arg, void *config, char **remaining, int num_remaining, char **error_msg))
Add positional argument descriptor.
options_builder_t * options_builder_create(size_t struct_size)
Create empty options builder.
Options builder API for flexible command-line option configuration.
log_level_t
Logging levels enumeration.
#define log_file(...)
File-only logging - writes to log file only, no stderr output.
#define OPT_MICROPHONE_INDEX_DEFAULT
Default microphone device index (-1 means system default)
#define OPT_ENCODE_AUDIO_DEFAULT
Default audio encoding state (true = Opus encoding enabled)
#define OPT_RECONNECT_ATTEMPTS_DEFAULT
Default reconnect attempts (-1 means auto/infinite)
#define OPT_WEBCAM_FLIP_DEFAULT
Default webcam flip state (true = horizontally flipped)
#define OPT_COMPRESSION_LEVEL_DEFAULT
Default compression level (1-9)
#define OPT_PORT_DEFAULT
Default TCP port for client/server communication.
#define OPT_WEBCAM_INDEX_DEFAULT
Default webcam device index.
#define OPT_HEIGHT_DEFAULT
Default terminal height in characters.
#define SNAPSHOT_DELAY_DEFAULT
Default snapshot delay in seconds.
#define OPT_MAX_CLIENTS_DEFAULT
Default maximum concurrent clients (server only)
#define OPT_SPEAKERS_INDEX_DEFAULT
Default speakers device index (-1 means system default)
#define OPT_WIDTH_DEFAULT
Default terminal width in characters.
palette_type_t
Built-in palette type enumeration.
@ PALETTE_STANDARD
Standard ASCII palette: " ...',;:clodxkO0KXNWM".
📝 Logging API with multiple log levels and terminal output control
⚙️ Command-line options parsing and configuration management for ascii-chat
ASCII Palette Management for Video-to-ASCII Conversion.
bool parse_render_mode(const char *arg, void *dest, char **error_msg)
Parse render mode option.
int parse_server_bind_address(const char *arg, void *config, char **remaining, int num_remaining, char **error_msg)
Parse server bind address positional argument.
bool parse_palette_type(const char *arg, void *dest, char **error_msg)
Parse palette type option.
bool parse_log_level(const char *arg, void *dest, char **error_msg)
Parse log level option.
int parse_client_address(const char *arg, void *config, char **remaining, int num_remaining, char **error_msg)
Parse client address positional argument.
bool parse_color_mode(const char *arg, void *dest, char **error_msg)
Parse terminal color level option.
bool parse_palette_chars(const char *arg, void *dest, char **error_msg)
Parse custom palette characters option.
Custom option parsers for enum types.
const options_config_t * options_preset_client(const char *program_name, const char *description)
Get client mode options preset.
const options_config_t * options_preset_acds(const char *program_name, const char *description)
Get acds mode options preset.
const options_config_t * options_preset_mirror(const char *program_name, const char *description)
Get mirror mode options preset.
const options_config_t * options_preset_server(const char *program_name, const char *description)
Get server mode options preset.
const options_config_t * options_preset_binary(const char *program_name, const char *description)
Get binary-level options preset.
const char * program_name
Program name for usage.
const char * description
Program description for usage.
Consolidated options structure.
🖥️ Cross-platform terminal interface for ascii-chat
Common SIMD utilities and structures.