ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
common.h File Reference

Common utilities and helpers for option parsing. More...

Go to the source code of this file.

Macros

#define USAGE_INDENT   " "
 
#define USAGE_HELP_LINE   USAGE_INDENT "-h --help " USAGE_INDENT "print this help\n"
 
#define USAGE_VERSION_LINE   USAGE_INDENT "-v --version " USAGE_INDENT "print version information\n"
 
#define USAGE_PORT_LINE    USAGE_INDENT "-p --port PORT " USAGE_INDENT "TCP port to listen on (default: %d)\n"
 
#define USAGE_PORT_CLIENT_LINE    USAGE_INDENT "-p --port PORT " USAGE_INDENT "override port from address (default: 27224)\n"
 
#define USAGE_RECONNECT_LINE
 
#define USAGE_MAX_CLIENTS_LINE    USAGE_INDENT " --max-clients N " USAGE_INDENT "maximum simultaneous clients (1-9, default: 9)\n"
 
#define USAGE_NO_AUDIO_MIXER_LINE    USAGE_INDENT " --no-audio-mixer " USAGE_INDENT "disable audio mixer - send silence (debug mode only)\n"
 
#define USAGE_WIDTH_LINE    USAGE_INDENT "-x --width WIDTH " USAGE_INDENT "render width (default: [auto-set])\n"
 
#define USAGE_HEIGHT_LINE    USAGE_INDENT "-y --height HEIGHT " USAGE_INDENT "render height (default: [auto-set])\n"
 
#define USAGE_WEBCAM_INDEX_LINE    USAGE_INDENT "-c --webcam-index CAMERA " USAGE_INDENT "webcam device index (0-based) (default: 0)\n"
 
#define USAGE_LIST_WEBCAMS_LINE    USAGE_INDENT " --list-webcams " USAGE_INDENT "list available webcam devices and exit\n"
 
#define USAGE_WEBCAM_FLIP_LINE
 
#define USAGE_TEST_PATTERN_CLIENT_LINE
 
#define USAGE_TEST_PATTERN_MIRROR_LINE    USAGE_INDENT " --test-pattern " USAGE_INDENT "use test pattern instead of webcam (for testing)\n"
 
#define USAGE_FPS_WIN_LINE    USAGE_INDENT " --fps FPS " USAGE_INDENT "desired frame rate 1-144 (default: 30 for Windows)\n"
 
#define USAGE_FPS_UNIX_LINE    USAGE_INDENT " --fps FPS " USAGE_INDENT "desired frame rate 1-144 (default: 60 for Unix)\n"
 
#define USAGE_COLOR_MODE_LINE
 
#define USAGE_SHOW_CAPABILITIES_LINE    USAGE_INDENT " --show-capabilities " USAGE_INDENT "show detected terminal capabilities and exit\n"
 
#define USAGE_UTF8_LINE    USAGE_INDENT " --utf8 " USAGE_INDENT "force enable UTF-8/Unicode support (default: [unset])\n"
 
#define USAGE_RENDER_MODE_LINE
 
#define USAGE_PALETTE_LINE
 
#define USAGE_PALETTE_CHARS_LINE
 
#define USAGE_STRETCH_LINE
 
#define USAGE_SNAPSHOT_LINE    USAGE_INDENT "-S --snapshot " USAGE_INDENT "capture single frame and exit (default: [unset])\n"
 
#define USAGE_SNAPSHOT_DELAY_LINE    USAGE_INDENT "-D --snapshot-delay SECONDS " USAGE_INDENT "delay SECONDS before snapshot (default: %.1f)\n"
 
#define USAGE_STRIP_ANSI_LINE
 
#define USAGE_AUDIO_LINE    USAGE_INDENT "-A --audio " USAGE_INDENT "enable audio capture and playback (default: [unset])\n"
 
#define USAGE_AUDIO_ANALYSIS_LINE
 
#define USAGE_NO_AUDIO_PLAYBACK_LINE
 
#define USAGE_LIST_MICROPHONES_LINE    USAGE_INDENT " --list-microphones " USAGE_INDENT "list available audio input devices and exit\n"
 
#define USAGE_LIST_SPEAKERS_LINE    USAGE_INDENT " --list-speakers " USAGE_INDENT "list available audio output devices and exit\n"
 
#define USAGE_MICROPHONE_INDEX_LINE    USAGE_INDENT " --microphone-index INDEX " USAGE_INDENT "microphone device index (-1 for default) (default: -1)\n"
 
#define USAGE_SPEAKERS_INDEX_LINE    USAGE_INDENT " --speakers-index INDEX " USAGE_INDENT "speakers device index (-1 for default) (default: -1)\n"
 
#define USAGE_ENCRYPT_LINE    USAGE_INDENT "-E --encrypt " USAGE_INDENT "enable packet encryption (default: [unset])\n"
 
#define USAGE_KEY_SERVER_LINE
 
#define USAGE_KEY_CLIENT_LINE
 
#define USAGE_PASSWORD_LINE
 
#define USAGE_KEYFILE_LINE
 
#define USAGE_NO_ENCRYPT_LINE    USAGE_INDENT " --no-encrypt " USAGE_INDENT "disable encryption (default: [unset])\n"
 
#define USAGE_SERVER_KEY_LINE
 
#define USAGE_CLIENT_KEYS_LINE
 
#define USAGE_COMPRESSION_LEVEL_LINE    USAGE_INDENT " --compression-level N " USAGE_INDENT "zstd compression level 1-9 (default: 1)\n"
 
#define USAGE_NO_COMPRESS_LINE    USAGE_INDENT " --no-compress " USAGE_INDENT "disable frame compression (default: [unset])\n"
 
#define USAGE_ENCODE_AUDIO_LINE    USAGE_INDENT " --encode-audio " USAGE_INDENT "enable Opus audio encoding (default: enabled)\n"
 
#define USAGE_NO_ENCODE_AUDIO_LINE   USAGE_INDENT " --no-encode-audio " USAGE_INDENT "disable Opus audio encoding\n"
 
#define USAGE_DATABASE_LINE
 
#define USAGE_LOG_FILE_LINE   USAGE_INDENT "-L --log-file FILE " USAGE_INDENT "log file path (default: stderr)\n"
 
#define USAGE_LOG_LEVEL_LINE
 

Functions

const char * find_similar_option (const char *unknown_opt, const struct option *options)
 Find a similar option name for typo suggestions.
 
int strtoint_safe (const char *str)
 Safely parse string to integer with validation.
 
char * validate_required_argument (const char *optarg, char *argbuf, size_t argbuf_size, const char *option_name, asciichat_mode_t mode)
 Validate and retrieve required argument for an option.
 
bool validate_positive_int_opt (const char *value_str, int *out_value, const char *param_name)
 Validate a positive integer value.
 
bool validate_port_opt (const char *value_str, uint16_t *out_port)
 Validate port number (1-65535)
 
bool validate_fps_opt (const char *value_str, int *out_fps)
 Validate FPS value (1-144)
 
bool validate_webcam_index (const char *value_str, unsigned short int *out_index)
 Validate webcam index using the common device index validator.
 
asciichat_error_t detect_default_ssh_key (char *key_path, size_t path_size)
 Detect default SSH key path for the current user.
 
char * strip_equals_prefix (const char *opt_value, char *buffer, size_t buffer_size)
 Strip equals sign prefix from option argument.
 
char * get_required_argument (const char *opt_value, char *buffer, size_t buffer_size, const char *option_name, asciichat_mode_t mode)
 Handle required arguments with consistent error messages.
 
char * read_password_from_stdin (const char *prompt)
 Read password from stdin with prompt.
 
asciichat_error_t parse_color_mode_option (const char *value_str, options_t *opts)
 Parse –color-mode option and set opts->color_mode.
 
asciichat_error_t parse_render_mode_option (const char *value_str, options_t *opts)
 Parse –render-mode option and set opts->render_mode.
 
asciichat_error_t parse_palette_option (const char *value_str, options_t *opts)
 Parse –palette option and set opt_palette_type.
 
asciichat_error_t parse_palette_chars_option (const char *value_str, options_t *opts)
 Parse –palette-chars option and set opt_palette_custom.
 
asciichat_error_t parse_width_option (const char *value_str, options_t *opts)
 Parse –width option and set opts->width.
 
asciichat_error_t parse_height_option (const char *value_str, options_t *opts)
 Parse –height option and set opts->height.
 
asciichat_error_t parse_webcam_index_option (const char *value_str, options_t *opts)
 Parse –webcam-index option and set opts->webcam_index.
 
asciichat_error_t parse_snapshot_delay_option (const char *value_str, options_t *opts)
 Parse –snapshot-delay option and set opts->snapshot_delay.
 
asciichat_error_t parse_log_level_option (const char *value_str, options_t *opts)
 Parse –log-level option and set opt_log_level.
 
void update_dimensions_for_full_height (options_t *opts)
 Update dimensions for full-height mode.
 
void update_dimensions_to_terminal_size (options_t *opts)
 Update dimensions to current terminal size.
 

Detailed Description

Common utilities and helpers for option parsing.

Shared helper functions, validators, and utilities used by client.c, server.c, and mirror.c option parsing modules. This module provides:

  • String parsing and validation utilities
  • Option argument validation (ports, FPS, webcam indices)
  • SSH key detection
  • Terminal dimension management
  • Error handling helpers

Design Philosophy:

  • Single Responsibility: Each function does one validation task
  • Consistent Error Reporting: All validators use fprintf to stderr
  • No Side Effects: Validators don't modify global state
  • Reusability: Used by all mode-specific parsers
See also
options.h
client.h
server.h
mirror.h

Definition in file options/common.h.

Macro Definition Documentation

◆ USAGE_AUDIO_ANALYSIS_LINE

#define USAGE_AUDIO_ANALYSIS_LINE
Value:
USAGE_INDENT " --audio-analysis " USAGE_INDENT \
"track and report audio quality metrics (with --audio) (default: [unset])\n"
#define USAGE_INDENT

Definition at line 576 of file options/common.h.

578 : [unset])\n"

◆ USAGE_AUDIO_LINE

#define USAGE_AUDIO_LINE    USAGE_INDENT "-A --audio " USAGE_INDENT "enable audio capture and playback (default: [unset])\n"

Definition at line 574 of file options/common.h.

575 : [unset])\n"

◆ USAGE_CLIENT_KEYS_LINE

#define USAGE_CLIENT_KEYS_LINE
Value:
USAGE_INDENT " --client-keys KEYS" USAGE_INDENT \
"allowed client public keys (comma-separated, supports github:user, gitlab:user, gpg:keyid, or SSH " \
"pubkey) (default: [unset])\n"

Definition at line 613 of file options/common.h.

615 :user, gitlab:user, gpg:keyid, or SSH " \
616 "pubkey) (default: [unset])\n"

◆ USAGE_COLOR_MODE_LINE

#define USAGE_COLOR_MODE_LINE
Value:
USAGE_INDENT " --color-mode MODE " USAGE_INDENT \
"color modes: auto, none, 16, 256, truecolor (default: auto)\n"

Definition at line 544 of file options/common.h.

546 : auto, none, 16, 256, truecolor (default: auto)\n"

◆ USAGE_COMPRESSION_LEVEL_LINE

#define USAGE_COMPRESSION_LEVEL_LINE    USAGE_INDENT " --compression-level N " USAGE_INDENT "zstd compression level 1-9 (default: 1)\n"

Definition at line 619 of file options/common.h.

620 : 1)\n"

◆ USAGE_DATABASE_LINE

#define USAGE_DATABASE_LINE
Value:
USAGE_INDENT "-d --db PATH " USAGE_INDENT \
"SQLite database path (default: ~/.config/ascii-chat/acds.db)\n"

Definition at line 633 of file options/common.h.

635 : ~/.config/ascii-chat/acds.db)\n"

◆ USAGE_ENCODE_AUDIO_LINE

#define USAGE_ENCODE_AUDIO_LINE    USAGE_INDENT " --encode-audio " USAGE_INDENT "enable Opus audio encoding (default: enabled)\n"

Definition at line 623 of file options/common.h.

624 : enabled)\n"

◆ USAGE_ENCRYPT_LINE

#define USAGE_ENCRYPT_LINE    USAGE_INDENT "-E --encrypt " USAGE_INDENT "enable packet encryption (default: [unset])\n"

Definition at line 592 of file options/common.h.

593 : [unset])\n"

◆ USAGE_FPS_UNIX_LINE

#define USAGE_FPS_UNIX_LINE    USAGE_INDENT " --fps FPS " USAGE_INDENT "desired frame rate 1-144 (default: 60 for Unix)\n"

Definition at line 542 of file options/common.h.

543 : 60 for Unix)\n"

◆ USAGE_FPS_WIN_LINE

#define USAGE_FPS_WIN_LINE    USAGE_INDENT " --fps FPS " USAGE_INDENT "desired frame rate 1-144 (default: 30 for Windows)\n"

Definition at line 540 of file options/common.h.

541 : 30 for Windows)\n"

◆ USAGE_HEIGHT_LINE

#define USAGE_HEIGHT_LINE    USAGE_INDENT "-y --height HEIGHT " USAGE_INDENT "render height (default: [auto-set])\n"

Definition at line 522 of file options/common.h.

523 : [auto-set])\n"

◆ USAGE_HELP_LINE

#define USAGE_HELP_LINE   USAGE_INDENT "-h --help " USAGE_INDENT "print this help\n"

Definition at line 501 of file options/common.h.

◆ USAGE_INDENT

#define USAGE_INDENT   " "

Definition at line 498 of file options/common.h.

◆ USAGE_KEY_CLIENT_LINE

#define USAGE_KEY_CLIENT_LINE
Value:
USAGE_INDENT "-K --key KEY " USAGE_INDENT \
"SSH/GPG key file for authentication: /path/to/key, gpg:keyid, github:user, gitlab:user, or 'ssh' for " \
"auto-detect (implies --encrypt) (default: [unset])\n"

Definition at line 598 of file options/common.h.

600 : /path/to/key, gpg:keyid, github:user, gitlab:user, or 'ssh' for " \
601 "auto-detect (implies --encrypt) (default: [unset])\n"

◆ USAGE_KEY_SERVER_LINE

#define USAGE_KEY_SERVER_LINE
Value:
USAGE_INDENT "-K --key KEY " USAGE_INDENT \
"SSH/GPG key file for authentication: /path/to/key, gpg:keyid, github:user, gitlab:user, or 'ssh' " \
"(implies --encrypt) (default: [unset])\n"

Definition at line 594 of file options/common.h.

596 : /path/to/key, gpg:keyid, github:user, gitlab:user, or 'ssh' " \
597 "(implies --encrypt) (default: [unset])\n"

◆ USAGE_KEYFILE_LINE

#define USAGE_KEYFILE_LINE
Value:
USAGE_INDENT "-F --keyfile FILE " USAGE_INDENT \
"read encryption key from FILE (implies --encrypt) (default: [unset])\n"

Definition at line 605 of file options/common.h.

607 : [unset])\n"

◆ USAGE_LIST_MICROPHONES_LINE

#define USAGE_LIST_MICROPHONES_LINE    USAGE_INDENT " --list-microphones " USAGE_INDENT "list available audio input devices and exit\n"

Definition at line 582 of file options/common.h.

◆ USAGE_LIST_SPEAKERS_LINE

#define USAGE_LIST_SPEAKERS_LINE    USAGE_INDENT " --list-speakers " USAGE_INDENT "list available audio output devices and exit\n"

Definition at line 584 of file options/common.h.

◆ USAGE_LIST_WEBCAMS_LINE

#define USAGE_LIST_WEBCAMS_LINE    USAGE_INDENT " --list-webcams " USAGE_INDENT "list available webcam devices and exit\n"

Definition at line 528 of file options/common.h.

◆ USAGE_LOG_FILE_LINE

#define USAGE_LOG_FILE_LINE   USAGE_INDENT "-L --log-file FILE " USAGE_INDENT "log file path (default: stderr)\n"

Definition at line 637 of file options/common.h.

◆ USAGE_LOG_LEVEL_LINE

#define USAGE_LOG_LEVEL_LINE
Value:
USAGE_INDENT "-l --log-level LEVEL " USAGE_INDENT \
"log level: dev, debug, info, warn, error, fatal (default: info)\n"

Definition at line 638 of file options/common.h.

640 : dev, debug, info, warn, error, fatal (default: info)\n"

◆ USAGE_MAX_CLIENTS_LINE

#define USAGE_MAX_CLIENTS_LINE    USAGE_INDENT " --max-clients N " USAGE_INDENT "maximum simultaneous clients (1-9, default: 9)\n"

Definition at line 514 of file options/common.h.

515 : 9)\n"

◆ USAGE_MICROPHONE_INDEX_LINE

#define USAGE_MICROPHONE_INDEX_LINE    USAGE_INDENT " --microphone-index INDEX " USAGE_INDENT "microphone device index (-1 for default) (default: -1)\n"

Definition at line 586 of file options/common.h.

587 : -1)\n"

◆ USAGE_NO_AUDIO_MIXER_LINE

#define USAGE_NO_AUDIO_MIXER_LINE    USAGE_INDENT " --no-audio-mixer " USAGE_INDENT "disable audio mixer - send silence (debug mode only)\n"

Definition at line 516 of file options/common.h.

◆ USAGE_NO_AUDIO_PLAYBACK_LINE

#define USAGE_NO_AUDIO_PLAYBACK_LINE
Value:
USAGE_INDENT " --no-audio-playback " USAGE_INDENT \
"disable speaker playback but keep recording received audio (debug mode) (default: [unset])\n"

Definition at line 579 of file options/common.h.

581 : [unset])\n"

◆ USAGE_NO_COMPRESS_LINE

#define USAGE_NO_COMPRESS_LINE    USAGE_INDENT " --no-compress " USAGE_INDENT "disable frame compression (default: [unset])\n"

Definition at line 621 of file options/common.h.

622 : [unset])\n"

◆ USAGE_NO_ENCODE_AUDIO_LINE

#define USAGE_NO_ENCODE_AUDIO_LINE   USAGE_INDENT " --no-encode-audio " USAGE_INDENT "disable Opus audio encoding\n"

Definition at line 625 of file options/common.h.

◆ USAGE_NO_ENCRYPT_LINE

#define USAGE_NO_ENCRYPT_LINE    USAGE_INDENT " --no-encrypt " USAGE_INDENT "disable encryption (default: [unset])\n"

Definition at line 608 of file options/common.h.

609 : [unset])\n"

◆ USAGE_PALETTE_CHARS_LINE

#define USAGE_PALETTE_CHARS_LINE
Value:
USAGE_INDENT "-C --palette-chars CHARS " USAGE_INDENT \
"Custom palette characters (implies --palette=custom) (default: [unset])\n"

Definition at line 557 of file options/common.h.

559 : [unset])\n"

◆ USAGE_PALETTE_LINE

#define USAGE_PALETTE_LINE
Value:
USAGE_INDENT "-P --palette PALETTE " USAGE_INDENT \
"ASCII character palette: standard, blocks, digital, minimal, cool, custom (default: standard)\n"

Definition at line 554 of file options/common.h.

556 : standard, blocks, digital, minimal, cool, custom (default: standard)\n"

◆ USAGE_PASSWORD_LINE

#define USAGE_PASSWORD_LINE
Value:
USAGE_INDENT " --password [PASS] " USAGE_INDENT \
"password for connection encryption (prompts if not provided) (implies --encrypt) (default: [unset])\n"

Definition at line 602 of file options/common.h.

604 : [unset])\n"

◆ USAGE_PORT_CLIENT_LINE

#define USAGE_PORT_CLIENT_LINE    USAGE_INDENT "-p --port PORT " USAGE_INDENT "override port from address (default: 27224)\n"

Definition at line 507 of file options/common.h.

508 : 27224)\n"

◆ USAGE_PORT_LINE

#define USAGE_PORT_LINE    USAGE_INDENT "-p --port PORT " USAGE_INDENT "TCP port to listen on (default: %d)\n"

Definition at line 505 of file options/common.h.

506 : %d)\n"

◆ USAGE_RECONNECT_LINE

#define USAGE_RECONNECT_LINE
Value:
USAGE_INDENT " --reconnect VALUE " USAGE_INDENT \
"reconnection behavior: off, auto, or 1-999 (default: auto)\n"

Definition at line 509 of file options/common.h.

511 : off, auto, or 1-999 (default: auto)\n"

◆ USAGE_RENDER_MODE_LINE

#define USAGE_RENDER_MODE_LINE
Value:
USAGE_INDENT "-M --render-mode MODE " USAGE_INDENT \
"Rendering modes: foreground, background, half-block (default: foreground)\n"

Definition at line 551 of file options/common.h.

553 : foreground, background, half-block (default: foreground)\n"

◆ USAGE_SERVER_KEY_LINE

#define USAGE_SERVER_KEY_LINE
Value:
USAGE_INDENT " --server-key KEY " USAGE_INDENT \
"expected server public key for verification (default: [unset])\n"

Definition at line 610 of file options/common.h.

612 : [unset])\n"

◆ USAGE_SHOW_CAPABILITIES_LINE

#define USAGE_SHOW_CAPABILITIES_LINE    USAGE_INDENT " --show-capabilities " USAGE_INDENT "show detected terminal capabilities and exit\n"

Definition at line 547 of file options/common.h.

◆ USAGE_SNAPSHOT_DELAY_LINE

#define USAGE_SNAPSHOT_DELAY_LINE    USAGE_INDENT "-D --snapshot-delay SECONDS " USAGE_INDENT "delay SECONDS before snapshot (default: %.1f)\n"

Definition at line 567 of file options/common.h.

568 : %.1f)\n"

◆ USAGE_SNAPSHOT_LINE

#define USAGE_SNAPSHOT_LINE    USAGE_INDENT "-S --snapshot " USAGE_INDENT "capture single frame and exit (default: [unset])\n"

Definition at line 565 of file options/common.h.

566 : [unset])\n"

◆ USAGE_SPEAKERS_INDEX_LINE

#define USAGE_SPEAKERS_INDEX_LINE    USAGE_INDENT " --speakers-index INDEX " USAGE_INDENT "speakers device index (-1 for default) (default: -1)\n"

Definition at line 588 of file options/common.h.

589 : -1)\n"

◆ USAGE_STRETCH_LINE

#define USAGE_STRETCH_LINE
Value:
USAGE_INDENT "-s --stretch " USAGE_INDENT \
"stretch or shrink video to fit (ignore aspect ratio) (default: [unset])\n"

Definition at line 560 of file options/common.h.

562 : [unset])\n"

◆ USAGE_STRIP_ANSI_LINE

#define USAGE_STRIP_ANSI_LINE
Value:
USAGE_INDENT " --strip-ansi " USAGE_INDENT \
"remove all ANSI escape codes from output (default: [unset])\n"

Definition at line 569 of file options/common.h.

571 : [unset])\n"

◆ USAGE_TEST_PATTERN_CLIENT_LINE

#define USAGE_TEST_PATTERN_CLIENT_LINE
Value:
USAGE_INDENT " --test-pattern " USAGE_INDENT \
"use test pattern instead of webcam (for testing multiple clients)\n"

Definition at line 533 of file options/common.h.

◆ USAGE_TEST_PATTERN_MIRROR_LINE

#define USAGE_TEST_PATTERN_MIRROR_LINE    USAGE_INDENT " --test-pattern " USAGE_INDENT "use test pattern instead of webcam (for testing)\n"

Definition at line 536 of file options/common.h.

◆ USAGE_UTF8_LINE

#define USAGE_UTF8_LINE    USAGE_INDENT " --utf8 " USAGE_INDENT "force enable UTF-8/Unicode support (default: [unset])\n"

Definition at line 549 of file options/common.h.

550 : [unset])\n"

◆ USAGE_VERSION_LINE

#define USAGE_VERSION_LINE   USAGE_INDENT "-v --version " USAGE_INDENT "print version information\n"

Definition at line 502 of file options/common.h.

◆ USAGE_WEBCAM_FLIP_LINE

#define USAGE_WEBCAM_FLIP_LINE
Value:
USAGE_INDENT "-f --webcam-flip " USAGE_INDENT \
"toggle horizontal flip of webcam image (default: flipped)\n"

Definition at line 530 of file options/common.h.

532 : flipped)\n"

◆ USAGE_WEBCAM_INDEX_LINE

#define USAGE_WEBCAM_INDEX_LINE    USAGE_INDENT "-c --webcam-index CAMERA " USAGE_INDENT "webcam device index (0-based) (default: 0)\n"

Definition at line 526 of file options/common.h.

527 : 0)\n"

◆ USAGE_WIDTH_LINE

#define USAGE_WIDTH_LINE    USAGE_INDENT "-x --width WIDTH " USAGE_INDENT "render width (default: [auto-set])\n"

Definition at line 520 of file options/common.h.

521 : [auto-set])\n"

Function Documentation

◆ detect_default_ssh_key()

asciichat_error_t detect_default_ssh_key ( char *  key_path,
size_t  path_size 
)

Detect default SSH key path for the current user.

Checks if ~/.ssh/id_ed25519 exists and is a regular file. Only supports Ed25519 keys (modern, secure, fast).

Parameters
key_pathBuffer to store detected key path
path_sizeSize of key_path buffer
Returns
ASCIICHAT_OK if found, ERROR_CRYPTO_KEY with helpful message otherwise
Note
Uses expand_path() to resolve tilde (~) in path
Prints message to stderr suggesting key generation if not found

Example:

char key_path[OPTIONS_BUFF_SIZE];
if (detect_default_ssh_key(key_path, sizeof(key_path)) == ASCIICHAT_OK) {
log_debug("Using default SSH key: %s", key_path);
}
#define SAFE_SNPRINTF(buffer, buffer_size,...)
Definition common.h:412
@ ASCIICHAT_OK
Definition error_codes.h:48
#define log_debug(...)
Log a DEBUG message.
#define OPTIONS_BUFF_SIZE
Buffer size for option string values.
Definition options.h:176
ASCIICHAT_API char opt_encrypt_key[OPTIONS_BUFF_SIZE]
asciichat_error_t detect_default_ssh_key(char *key_path, size_t path_size)
Detect default SSH key path for the current user.

Definition at line 165 of file options/common.c.

165 {
166 // Use expand_path utility to resolve ~/.ssh/id_ed25519
167 char *full_path = expand_path("~/.ssh/id_ed25519");
168 if (!full_path) {
169 return SET_ERRNO(ERROR_CONFIG, "Could not expand SSH key path");
170 }
171
172 // Check if the Ed25519 private key file exists
173 struct stat st;
174 bool found = (stat(full_path, &st) == 0 && S_ISREG(st.st_mode));
175
176 if (found) {
177 SAFE_SNPRINTF(key_path, path_size, "%s", full_path);
178 log_debug("Found default SSH key: %s", full_path);
179 SAFE_FREE(full_path);
180 return ASCIICHAT_OK;
181 }
182
183 (void)fprintf(stderr, "No Ed25519 SSH key found at %s\n", full_path);
184 SAFE_FREE(full_path);
185 return SET_ERRNO(
187 "Only Ed25519 keys are supported (modern, secure, fast). Generate a new key with: ssh-keygen -t ed25519");
188}
#define SAFE_FREE(ptr)
Definition common.h:320
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
@ ERROR_CRYPTO_KEY
Definition error_codes.h:89
@ ERROR_CONFIG
Definition error_codes.h:54
char * expand_path(const char *path)
Expand path with tilde (~) support.
Definition path.c:183

References ASCIICHAT_OK, ERROR_CONFIG, ERROR_CRYPTO_KEY, expand_path(), log_debug, SAFE_FREE, SAFE_SNPRINTF, and SET_ERRNO.

◆ find_similar_option()

const char * find_similar_option ( const char *  unknown_opt,
const struct option *  options 
)

Find a similar option name for typo suggestions.

Uses Levenshtein distance to find the most similar option name from the provided options array. Only suggests options within a reasonable edit distance.

Parameters
unknown_optThe unknown/misspelled option name
optionsArray of valid option structures (must be NULL-terminated)
Returns
Suggested option name, or NULL if no good match found
Note
Uses LEVENSHTEIN_SUGGESTION_THRESHOLD to filter poor matches

Example:

const char *suggestion = find_similar_option("--colr", client_options);
if (suggestion) {
fprintf(stderr, "Did you mean '--%s'?\n", suggestion);
}
const char * find_similar_option(const char *unknown_opt, const struct option *options)
Find a similar option name for typo suggestions.

Definition at line 42 of file options/common.c.

42 {
43 if (!unknown_opt || !options) {
44 return NULL;
45 }
46
47 const char *best_match = NULL;
48 size_t best_distance = SIZE_MAX;
49
50 for (int i = 0; options[i].name != NULL; i++) {
51 size_t dist = levenshtein(unknown_opt, options[i].name);
52 if (dist < best_distance) {
53 best_distance = dist;
54 best_match = options[i].name;
55 }
56 }
57
58 // Only suggest if the distance is within our threshold
59 if (best_distance <= LEVENSHTEIN_SUGGESTION_THRESHOLD) {
60 return best_match;
61 }
62
63 return NULL;
64}
#define LEVENSHTEIN_SUGGESTION_THRESHOLD
Maximum edit distance to suggest an option.
Definition levenshtein.h:29
size_t levenshtein(const char *a, const char *b)
Calculate Levenshtein distance between two strings.
Definition levenshtein.c:72

References levenshtein(), and LEVENSHTEIN_SUGGESTION_THRESHOLD.

◆ get_required_argument()

char * get_required_argument ( const char *  opt_value,
char *  buffer,
size_t  buffer_size,
const char *  option_name,
asciichat_mode_t  mode 
)

Handle required arguments with consistent error messages.

Validates that an option has a non-empty argument and processes it. Returns NULL on error with appropriate error message printed.

Handles edge cases:

  • NULL or empty opt_value
  • getopt_long bug where option name is returned as argument
  • Arguments with '=' prefix (GNU-style –option=value)
Parameters
opt_valueArgument value from getopt_long
bufferBuffer for storing processed argument
buffer_sizeSize of buffer
option_nameName of the option (for error messages)
modeCurrent mode (client/server/mirror) for error messages
Returns
Pointer to processed argument string in buffer, or NULL on error
Note
Prints "option '--<name>' requires an argument" to stderr on error
Used internally by validate_required_argument()

Example:

char argbuf[OPTIONS_BUFF_SIZE];
char *value = get_required_argument(optarg, argbuf, sizeof(argbuf), "key", MODE_CLIENT);
if (!value) {
return option_error_invalid();
}
@ MODE_CLIENT
Client mode - network client options.
Definition options.h:428
char * get_required_argument(const char *opt_value, char *buffer, size_t buffer_size, const char *option_name, asciichat_mode_t mode)
Handle required arguments with consistent error messages.

Definition at line 215 of file options/common.c.

216 {
217 // Check if opt_value is NULL or empty
218 if (!opt_value || strlen(opt_value) == 0) {
219 goto error;
220 }
221
222 // Check if getopt_long returned the option name itself as the argument
223 // This happens when a long option requiring an argument is at the end of argv
224 if (opt_value && option_name && strcmp(opt_value, option_name) == 0) {
225 goto error;
226 }
227
228 // Process the argument normally
229 char *value_str = strip_equals_prefix(opt_value, buffer, buffer_size);
230 if (!value_str) {
231 goto error;
232 }
233
234 return value_str;
235
236error:
237 (void)fprintf(stderr, "%s: option '--%s' requires an argument\n",
238 mode == MODE_SERVER ? "server" : (mode == MODE_MIRROR ? "mirror" : "client"), option_name);
239 (void)fflush(stderr);
240 return NULL; // Signal error to caller
241}
@ MODE_SERVER
Server mode - network server options.
Definition options.h:427
@ MODE_MIRROR
Mirror mode - local webcam viewing (no network)
Definition options.h:429
char * strip_equals_prefix(const char *opt_value, char *buffer, size_t buffer_size)
Strip equals sign prefix from option argument.

References MODE_MIRROR, MODE_SERVER, and strip_equals_prefix().

Referenced by validate_required_argument().

◆ parse_color_mode_option()

asciichat_error_t parse_color_mode_option ( const char *  value_str,
options_t opts 
)

Parse –color-mode option and set opts->color_mode.

Validates color mode string and sets opts->color_mode field. Accepts: "auto", "none", "mono", "16", "16color", "256", "256color", "truecolor", "24bit"

Parameters
value_strColor mode string from command line
optsOptions struct to update
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM on invalid mode
Note
Prints error message to stderr on failure
Sets opts->color_mode on success

Definition at line 361 of file options/common.c.

361 {
362 if (!value_str || !opts) {
363 return ERROR_INVALID_PARAM;
364 }
365
366 if (strcmp(value_str, "auto") == 0) {
368 } else if (strcmp(value_str, "none") == 0 || strcmp(value_str, "mono") == 0) {
370 } else if (strcmp(value_str, "16") == 0 || strcmp(value_str, "16color") == 0) {
372 } else if (strcmp(value_str, "256") == 0 || strcmp(value_str, "256color") == 0) {
374 } else if (strcmp(value_str, "truecolor") == 0 || strcmp(value_str, "24bit") == 0) {
376 } else {
377 (void)fprintf(stderr, "Error: Invalid color mode '%s'. Valid modes: auto, none, 16, 256, truecolor\n", value_str);
378 return ERROR_INVALID_PARAM;
379 }
380
381 return ASCIICHAT_OK;
382}
@ ERROR_INVALID_PARAM
#define COLOR_MODE_16_COLOR
16-color mode (full name)
Definition options.h:159
#define COLOR_MODE_256_COLOR
256-color mode (full name)
Definition options.h:161
#define COLOR_MODE_TRUECOLOR
24-bit truecolor mode
Definition options.h:162
#define COLOR_MODE_AUTO
Backward compatibility aliases for color mode enum values.
Definition options.h:156
#define COLOR_MODE_NONE
Monochrome mode.
Definition options.h:157
terminal_color_mode_t color_mode
Color mode (auto/none/16/256/truecolor)
Definition options.h:507

References ASCIICHAT_OK, options_state::color_mode, COLOR_MODE_16_COLOR, COLOR_MODE_256_COLOR, COLOR_MODE_AUTO, COLOR_MODE_NONE, COLOR_MODE_TRUECOLOR, and ERROR_INVALID_PARAM.

◆ parse_height_option()

asciichat_error_t parse_height_option ( const char *  value_str,
options_t opts 
)

Parse –height option and set opts->height.

Validates height value and sets opts->height and opts->auto_height fields.

Parameters
value_strHeight value from command line
optsOptions struct to update
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM if invalid
Note
Prints error message to stderr on failure
Sets opts->height and opts->auto_height = false on success

Definition at line 465 of file options/common.c.

465 {
466 if (!opts) {
467 return ERROR_INVALID_PARAM;
468 }
469
470 int height_val;
471 if (!validate_positive_int_opt(value_str, &height_val, "height")) {
472 return ERROR_INVALID_PARAM;
473 }
474
475 opts->height = (unsigned short int)height_val;
476 opts->auto_height = false;
477
478 return ASCIICHAT_OK;
479}
bool validate_positive_int_opt(const char *value_str, int *out_value, const char *param_name)
Validate a positive integer value.
bool auto_height
Auto-detect height from terminal.
Definition options.h:457
unsigned short int height
Terminal height in characters.
Definition options.h:455

References ASCIICHAT_OK, options_state::auto_height, ERROR_INVALID_PARAM, options_state::height, and validate_positive_int_opt().

◆ parse_log_level_option()

asciichat_error_t parse_log_level_option ( const char *  value_str,
options_t opts 
)

Parse –log-level option and set opt_log_level.

Validates log level string and sets global opt_log_level variable. Accepts: "dev", "debug", "info", "warn", "error", "fatal" (case-insensitive)

Parameters
value_strLog level string from command line
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM if invalid
Note
Prints error message to stderr on failure
Sets opt_log_level global variable on success
Uses validate_opt_log_level() from validation.h

Definition at line 513 of file options/common.c.

513 {
514 if (!opts) {
515 return ERROR_INVALID_PARAM;
516 }
517
518 char error_msg[256];
519 int log_level = validate_opt_log_level(value_str, error_msg, sizeof(error_msg));
520
521 if (log_level == -1) {
522 (void)fprintf(stderr, "Error: %s\n", error_msg);
523 return ERROR_INVALID_PARAM;
524 }
525
526 opts->log_level = (log_level_t)log_level;
527
528 return ASCIICHAT_OK;
529}
log_level_t
Logging levels enumeration.
Definition log/logging.h:59
int validate_opt_log_level(const char *value_str, char *error_msg, size_t error_msg_size)
Validate log level string.
Definition validation.c:190
log_level_t log_level
Log level threshold.
Definition options.h:536

References ASCIICHAT_OK, ERROR_INVALID_PARAM, options_state::log_level, and validate_opt_log_level().

◆ parse_palette_chars_option()

asciichat_error_t parse_palette_chars_option ( const char *  value_str,
options_t opts 
)

Parse –palette-chars option and set opt_palette_custom.

Validates custom palette characters and sets global opt_palette_custom, opt_palette_custom_set, and opt_palette_type variables.

Parameters
value_strCustom palette characters from command line
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM if too long
Note
Prints error message to stderr on failure
Sets opt_palette_custom, opt_palette_custom_set, and opt_palette_type on success
Maximum length is 255 characters (sizeof(opt_palette_custom) - 1)

Definition at line 430 of file options/common.c.

430 {
431 if (!value_str || !opts) {
432 return ERROR_INVALID_PARAM;
433 }
434
435 if (strlen(value_str) >= sizeof(opts->palette_custom)) {
436 (void)fprintf(stderr, "Invalid palette-chars: too long (%zu chars, max %zu)\n", strlen(value_str),
437 sizeof(opts->palette_custom) - 1);
438 return ERROR_INVALID_PARAM;
439 }
440
441 SAFE_STRNCPY(opts->palette_custom, value_str, sizeof(opts->palette_custom));
442 opts->palette_custom[sizeof(opts->palette_custom) - 1] = '\0';
443 opts->palette_custom_set = true;
445
446 return ASCIICHAT_OK;
447}
#define SAFE_STRNCPY(dst, src, size)
Definition common.h:358
@ PALETTE_CUSTOM
User-defined via –palette-chars.
Definition palette.h:96
char palette_custom[256]
Custom palette characters.
Definition options.h:582
bool palette_custom_set
True if custom palette was set.
Definition options.h:583
palette_type_t palette_type
Selected palette type.
Definition options.h:581

References ASCIICHAT_OK, ERROR_INVALID_PARAM, options_state::palette_custom, PALETTE_CUSTOM, options_state::palette_custom_set, options_state::palette_type, and SAFE_STRNCPY.

◆ parse_palette_option()

asciichat_error_t parse_palette_option ( const char *  value_str,
options_t opts 
)

Parse –palette option and set opt_palette_type.

Validates palette type string and sets global opt_palette_type variable. Accepts: "standard", "blocks", "digital", "minimal", "cool", "custom"

Parameters
value_strPalette type string from command line
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM on invalid palette
Note
Prints error message to stderr on failure
Sets opt_palette_type global variable on success

Definition at line 404 of file options/common.c.

404 {
405 if (!value_str || !opts) {
406 return ERROR_INVALID_PARAM;
407 }
408
409 if (strcmp(value_str, "standard") == 0) {
411 } else if (strcmp(value_str, "blocks") == 0) {
413 } else if (strcmp(value_str, "digital") == 0) {
415 } else if (strcmp(value_str, "minimal") == 0) {
417 } else if (strcmp(value_str, "cool") == 0) {
419 } else if (strcmp(value_str, "custom") == 0) {
421 } else {
422 (void)fprintf(stderr, "Invalid palette '%s'. Valid palettes: standard, blocks, digital, minimal, cool, custom\n",
423 value_str);
424 return ERROR_INVALID_PARAM;
425 }
426
427 return ASCIICHAT_OK;
428}
@ PALETTE_BLOCKS
Unicode block characters: " ░░▒▒▓▓██".
Definition palette.h:88
@ PALETTE_COOL
Ascending blocks: " ▁▂▃▄▅▆▇█".
Definition palette.h:94
@ PALETTE_STANDARD
Standard ASCII palette: " ...',;:clodxkO0KXNWM".
Definition palette.h:86
@ PALETTE_DIGITAL
Digital/glitch aesthetic: " -=≡≣▰▱◼".
Definition palette.h:90
@ PALETTE_MINIMAL
Simple ASCII: " .-+*#".
Definition palette.h:92

References ASCIICHAT_OK, ERROR_INVALID_PARAM, PALETTE_BLOCKS, PALETTE_COOL, PALETTE_CUSTOM, PALETTE_DIGITAL, PALETTE_MINIMAL, PALETTE_STANDARD, and options_state::palette_type.

◆ parse_render_mode_option()

asciichat_error_t parse_render_mode_option ( const char *  value_str,
options_t opts 
)

Parse –render-mode option and set opts->render_mode.

Validates render mode string and sets opts->render_mode field. Accepts: "foreground", "fg", "background", "bg", "half-block", "halfblock"

Parameters
value_strRender mode string from command line
optsOptions struct to update
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM on invalid mode
Note
Prints error message to stderr on failure
Sets opts->render_mode on success

Definition at line 384 of file options/common.c.

384 {
385 if (!value_str || !opts) {
386 return ERROR_INVALID_PARAM;
387 }
388
389 if (strcmp(value_str, "foreground") == 0 || strcmp(value_str, "fg") == 0) {
391 } else if (strcmp(value_str, "background") == 0 || strcmp(value_str, "bg") == 0) {
393 } else if (strcmp(value_str, "half-block") == 0 || strcmp(value_str, "halfblock") == 0) {
395 } else {
396 (void)fprintf(stderr, "Error: Invalid render mode '%s'. Valid modes: foreground, background, half-block\n",
397 value_str);
398 return ERROR_INVALID_PARAM;
399 }
400
401 return ASCIICHAT_OK;
402}
@ RENDER_MODE_FOREGROUND
Foreground colors only (text color)
Definition terminal.h:469
@ RENDER_MODE_BACKGROUND
Background colors (block colors)
Definition terminal.h:471
@ RENDER_MODE_HALF_BLOCK
Unicode half-block characters (mixed foreground/background)
Definition terminal.h:473
render_mode_t render_mode
Render mode (foreground/background/half-block)
Definition options.h:508

References ASCIICHAT_OK, ERROR_INVALID_PARAM, options_state::render_mode, RENDER_MODE_BACKGROUND, RENDER_MODE_FOREGROUND, and RENDER_MODE_HALF_BLOCK.

◆ parse_snapshot_delay_option()

asciichat_error_t parse_snapshot_delay_option ( const char *  value_str,
options_t opts 
)

Parse –snapshot-delay option and set opts->snapshot_delay.

Validates snapshot delay (non-negative float) and sets opts->snapshot_delay field.

Parameters
value_strSnapshot delay in seconds from command line
optsOptions struct to update
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM if invalid
Note
Prints error message to stderr on failure
Sets opts->snapshot_delay on success

Definition at line 496 of file options/common.c.

496 {
497 if (!value_str || !opts) {
498 return ERROR_INVALID_PARAM;
499 }
500
501 char *endptr;
502 float delay = strtof(value_str, &endptr);
503 if (endptr == value_str || *endptr != '\0' || delay < 0.0f) {
504 (void)fprintf(stderr, "Invalid snapshot delay '%s'. Must be a non-negative number.\n", value_str);
505 return ERROR_INVALID_PARAM;
506 }
507
508 opts->snapshot_delay = delay;
509
510 return ASCIICHAT_OK;
511}
double snapshot_delay
Snapshot delay in seconds.
Definition options.h:533

References ASCIICHAT_OK, ERROR_INVALID_PARAM, and options_state::snapshot_delay.

◆ parse_webcam_index_option()

asciichat_error_t parse_webcam_index_option ( const char *  value_str,
options_t opts 
)

Parse –webcam-index option and set opts->webcam_index.

Validates webcam index and sets opts->webcam_index field.

Parameters
value_strWebcam index from command line
optsOptions struct to update
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM if invalid
Note
Prints error message to stderr on failure
Sets opts->webcam_index on success

Definition at line 481 of file options/common.c.

481 {
482 if (!opts) {
483 return ERROR_INVALID_PARAM;
484 }
485
486 unsigned short int index_val;
487 if (!validate_webcam_index(value_str, &index_val)) {
488 return ERROR_INVALID_PARAM;
489 }
490
491 opts->webcam_index = index_val;
492
493 return ASCIICHAT_OK;
494}
bool validate_webcam_index(const char *value_str, unsigned short int *out_index)
Validate webcam index using the common device index validator.
unsigned short int webcam_index
Webcam device index (0 = first)
Definition options.h:499

References ASCIICHAT_OK, ERROR_INVALID_PARAM, validate_webcam_index(), and options_state::webcam_index.

◆ parse_width_option()

asciichat_error_t parse_width_option ( const char *  value_str,
options_t opts 
)

Parse –width option and set opts->width.

Validates width value and sets opts->width and opts->auto_width fields.

Parameters
value_strWidth value from command line
optsOptions struct to update
Returns
ASCIICHAT_OK on success, ERROR_INVALID_PARAM if invalid
Note
Prints error message to stderr on failure
Sets opts->width and opts->auto_width = false on success

Definition at line 449 of file options/common.c.

449 {
450 if (!opts) {
451 return ERROR_INVALID_PARAM;
452 }
453
454 int width_val;
455 if (!validate_positive_int_opt(value_str, &width_val, "width")) {
456 return ERROR_INVALID_PARAM;
457 }
458
459 opts->width = (unsigned short int)width_val;
460 opts->auto_width = false;
461
462 return ASCIICHAT_OK;
463}
unsigned short int width
Terminal width in characters.
Definition options.h:454
bool auto_width
Auto-detect width from terminal.
Definition options.h:456

References ASCIICHAT_OK, options_state::auto_width, ERROR_INVALID_PARAM, validate_positive_int_opt(), and options_state::width.

◆ read_password_from_stdin()

char * read_password_from_stdin ( const char *  prompt)

Read password from stdin with prompt.

Parameters
promptPrompt message to display to user
Returns
Allocated password string (caller must free), or NULL on error

Prompts user for password input using prompt_password_simple() from util/password.h. Returns dynamically allocated string that must be freed by caller.

Note
Returns NULL if password input fails or if not running in a TTY.
Caller must use SAFE_FREE() to deallocate returned string.

Definition at line 244 of file options/common.c.

244 {
245 char *password_buf = SAFE_MALLOC(PASSWORD_MAX_LEN, char *);
246 if (!password_buf) {
247 return NULL;
248 }
249
250 if (prompt_password_simple(prompt, password_buf, PASSWORD_MAX_LEN) != 0) {
251 SAFE_FREE(password_buf);
252 return NULL;
253 }
254
255 return password_buf; // Caller must free
256}
#define SAFE_MALLOC(size, cast)
Definition common.h:208
#define PASSWORD_MAX_LEN
Buffer size for password input.
Definition password.h:30
int prompt_password_simple(const char *prompt, char *password, size_t max_len)
Prompt the user for a password with simple formatting.
Definition password.c:46

References PASSWORD_MAX_LEN, prompt_password_simple(), SAFE_FREE, and SAFE_MALLOC.

◆ strip_equals_prefix()

char * strip_equals_prefix ( const char *  opt_value,
char *  buffer,
size_t  buffer_size 
)

Strip equals sign prefix from option argument.

Internal helper that handles GNU-style long options with = syntax (–option=value). Copies argument to buffer and returns pointer past the '=' if present.

Parameters
opt_valueRaw option value from getopt_long
bufferBuffer to store processed value
buffer_sizeSize of buffer
Returns
Pointer to value in buffer (past '=' if present), or NULL if empty
Note
Returns NULL for empty strings after stripping '='
Buffer is always null-terminated via SAFE_SNPRINTF

Example:

char argbuf[OPTIONS_BUFF_SIZE];
char *value = strip_equals_prefix("=1234", argbuf, sizeof(argbuf));
// value points to "1234" in argbuf

Definition at line 195 of file options/common.c.

195 {
196 if (!opt_value)
197 return NULL;
198
199 SAFE_SNPRINTF(buffer, buffer_size, "%s", opt_value);
200 char *value_str = buffer;
201 if (value_str[0] == '=') {
202 value_str++; // Skip the equals sign
203 }
204
205 // Return NULL for empty strings (treat as missing argument)
206 if (strlen(value_str) == 0) {
207 return NULL;
208 }
209
210 return value_str;
211}

References SAFE_SNPRINTF.

Referenced by get_required_argument().

◆ strtoint_safe()

int strtoint_safe ( const char *  str)

Safely parse string to integer with validation.

Parses a string to integer using parse_int32() with full range checking. Returns INT_MIN on error (NULL input, empty string, invalid format, out of range).

Parameters
strString to parse
Returns
Parsed integer value, or INT_MIN on error
Warning
INT_MIN is used as error sentinel, so cannot represent INT_MIN value

Example:

int val = strtoint_safe(optarg);
if (val == INT_MIN) {
fprintf(stderr, "Invalid integer: %s\n", optarg);
}
int strtoint_safe(const char *str)
Safely parse string to integer with validation.

Definition at line 67 of file options/common.c.

67 {
68 if (!str || *str == '\0') {
69 return INT_MIN; // Error: NULL or empty string
70 }
71
72 int32_t result = 0;
73 // Use safe parsing utility with full int32 range validation
74 if (parse_int32(str, &result, INT_MIN, INT_MAX) != ASCIICHAT_OK) {
75 return INT_MIN; // Error: invalid input or out of range
76 }
77
78 return (int)result;
79}
asciichat_error_t parse_int32(const char *str, int32_t *out_value, int32_t min_value, int32_t max_value)
Parse signed 32-bit integer with range validation.
Definition parsing.c:240

◆ update_dimensions_for_full_height()

void update_dimensions_for_full_height ( options_t opts)

Update dimensions for full-height mode.

Sets opt_height to terminal height when auto-detected. Used during initialization to maximize vertical space usage.

Behavior:

  • Both auto: Set both width and height to terminal size
  • Only height auto: Set height to terminal height
  • Only width auto: Set width to terminal width
  • Neither auto: No change
Note
Does not use log_debug because logging may not be initialized yet
Fails silently if terminal size detection fails (keeps defaults)

Example:

// During options_init():
}
void update_dimensions_for_full_height(options_t *opts)
Update dimensions for full-height mode.
ASCIICHAT_API bool auto_width
ASCIICHAT_API bool auto_height

Definition at line 535 of file options/common.c.

535 {
536 if (!opts) {
537 return;
538 }
539
540 unsigned short int term_width, term_height;
541
542 // Note: Logging is not available during options_init, so we can't use log_debug here
543 asciichat_error_t result = get_terminal_size(&term_width, &term_height);
544 if (result == ASCIICHAT_OK) {
545 // If both dimensions are auto, set height to terminal height and let
546 // aspect_ratio calculate width
547 if (opts->auto_height && opts->auto_width) {
548 opts->height = term_height;
549 opts->width = term_width; // Also set width when both are auto
550 }
551 // If only height is auto, use full terminal height
552 else if (opts->auto_height) {
553 opts->height = term_height;
554 }
555 // If only width is auto, use full terminal width
556 else if (opts->auto_width) {
557 opts->width = term_width;
558 }
559 } else {
560 // Terminal size detection failed, but we can still continue with defaults
561 }
562}
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:46
asciichat_error_t get_terminal_size(unsigned short int *width, unsigned short int *height)
Get terminal size with multiple fallback methods.

◆ update_dimensions_to_terminal_size()

void update_dimensions_to_terminal_size ( options_t opts)

Update dimensions to current terminal size.

Updates opt_width and opt_height to current terminal size for auto-detected dimensions. Used after logging is initialized (can use log_debug).

Behavior:

  • auto_width: Set width to terminal width
  • auto_height: Set height to terminal height
  • Neither: No change
Note
Logs debug messages about dimension updates
Logs debug message if terminal size detection fails

Example:

// After logging initialization:
log_info("Terminal dimensions: %dx%d", opt_width, opt_height);
#define log_info(...)
Log an INFO message.
void update_dimensions_to_terminal_size(options_t *opts)
Update dimensions to current terminal size.
ASCIICHAT_API unsigned short int opt_height
ASCIICHAT_API unsigned short int opt_width

Definition at line 564 of file options/common.c.

564 {
565 if (!opts) {
566 return;
567 }
568
569 unsigned short int term_width, term_height;
570 // Get current terminal size (get_terminal_size already handles ioctl first, then $COLUMNS/$LINES fallback)
571 asciichat_error_t terminal_result = get_terminal_size(&term_width, &term_height);
572 if (terminal_result == ASCIICHAT_OK) {
573 if (opts->auto_width) {
574 opts->width = term_width;
575 }
576 if (opts->auto_height) {
577 opts->height = term_height;
578 }
579 log_debug("After update_dimensions_to_terminal_size: width=%d, height=%d", opts->width, opts->height);
580 } else {
581 // Terminal detection failed - keep the default values set in options_init()
582 log_debug(
583 "Failed to get terminal size in update_dimensions_to_terminal_size, keeping defaults: width=%d, height=%d",
584 opts->width, opts->height);
585 }
586}

◆ validate_fps_opt()

bool validate_fps_opt ( const char *  value_str,
int *  out_fps 
)

Validate FPS value (1-144)

Internal option parsing helper that validates FPS is in reasonable range. Range chosen to support 1 FPS (slideshows) to 144 FPS (high refresh monitors).

Parameters
value_strString to validate
out_fpsOutput parameter for validated FPS
Returns
true if valid, false otherwise

Example:

int fps;
if (!validate_fps_opt(optarg, &fps)) {
return option_error_invalid();
}
opt_fps = fps;
bool validate_fps_opt(const char *value_str, int *out_fps)
Validate FPS value (1-144)

Definition at line 127 of file options/common.c.

127 {
128 if (!value_str || !out_fps) {
129 return false;
130 }
131
132 int fps_val = strtoint_safe(value_str);
133 if (fps_val == INT_MIN || fps_val < 1 || fps_val > 144) {
134 (void)fprintf(stderr, "Invalid FPS value '%s'. FPS must be between 1 and 144.\n", value_str);
135 return false;
136 }
137
138 *out_fps = fps_val;
139 return true;
140}

References strtoint_safe().

◆ validate_port_opt()

bool validate_port_opt ( const char *  value_str,
uint16_t out_port 
)

Validate port number (1-65535)

Internal option parsing helper that validates a port number is in valid range. Uses parse_port() for robust validation.

Parameters
value_strString to validate
out_portOutput parameter for validated port
Returns
true if valid, false otherwise

Example:

uint16_t port;
if (!validate_port_opt(optarg, &port)) {
return option_error_invalid();
}
opt_port = port;
unsigned short uint16_t
Definition common.h:57
ASCIICHAT_API char opt_port[OPTIONS_BUFF_SIZE]
bool validate_port_opt(const char *value_str, uint16_t *out_port)
Validate port number (1-65535)

Definition at line 112 of file options/common.c.

112 {
113 if (!value_str || !out_port) {
114 return false;
115 }
116
117 // Use safe integer parsing with range validation
118 if (parse_port(value_str, out_port) != ASCIICHAT_OK) {
119 (void)fprintf(stderr, "Invalid port value '%s'. Port must be a number between 1 and 65535.\n", value_str);
120 return false;
121 }
122
123 return true;
124}
asciichat_error_t parse_port(const char *str, uint16_t *out_port)
Parse port number (1-65535) from string.
Definition parsing.c:221

References ASCIICHAT_OK, and parse_port().

◆ validate_positive_int_opt()

bool validate_positive_int_opt ( const char *  value_str,
int *  out_value,
const char *  param_name 
)

Validate a positive integer value.

Internal option parsing helper that validates a string represents a positive integer (> 0). Prints error message on failure.

Parameters
value_strString to validate
out_valueOutput parameter for validated integer
param_nameParameter name for error messages
Returns
true if valid, false otherwise

Example:

int fps;
if (!validate_positive_int_opt(optarg, &fps, "FPS")) {
return option_error_invalid();
}

Definition at line 96 of file options/common.c.

96 {
97 if (!value_str || !out_value) {
98 return false;
99 }
100
101 int val = strtoint_safe(value_str);
102 if (val == INT_MIN || val <= 0) {
103 (void)fprintf(stderr, "Invalid %s value '%s'. %s must be a positive integer.\n", param_name, value_str, param_name);
104 return false;
105 }
106
107 *out_value = val;
108 return true;
109}

References strtoint_safe().

Referenced by parse_height_option(), and parse_width_option().

◆ validate_required_argument()

char * validate_required_argument ( const char *  optarg,
char *  argbuf,
size_t  argbuf_size,
const char *  option_name,
asciichat_mode_t  mode 
)

Validate and retrieve required argument for an option.

Wrapper around get_required_argument() that also sets error code on failure. Used for options that must have an argument.

Parameters
optargArgument value from getopt_long
argbufBuffer for storing processed argument
argbuf_sizeSize of argbuf
option_nameName of the option (for error messages)
modeCurrent mode (client/server/mirror) for error messages
Returns
Pointer to processed argument string in argbuf, or NULL on error
Note
On error, prints message to stderr and calls option_error_invalid()

Example:

char argbuf[OPTIONS_BUFF_SIZE];
char *value = validate_required_argument(optarg, argbuf, sizeof(argbuf), "port", MODE_CLIENT);
if (!value) {
return option_error_invalid();
}
char * validate_required_argument(const char *optarg, char *argbuf, size_t argbuf_size, const char *option_name, asciichat_mode_t mode)
Validate and retrieve required argument for an option.

Definition at line 86 of file options/common.c.

87 {
88 char *value = get_required_argument(optarg, argbuf, argbuf_size, option_name, mode);
89 if (!value) {
90 (void)option_error_invalid();
91 }
92 return value;
93}

References get_required_argument().

◆ validate_webcam_index()

bool validate_webcam_index ( const char *  value_str,
unsigned short int *  out_index 
)

Validate webcam index using the common device index validator.

Validates webcam index is a non-negative integer. Unlike audio device indices, webcam indices do not support -1 (default).

Parameters
value_strString to validate
out_indexOutput parameter for validated index
Returns
true if valid, false otherwise

Example:

unsigned short int webcam_idx;
if (!validate_webcam_index(optarg, &webcam_idx)) {
return option_error_invalid();
}
opt_webcam_index = webcam_idx;
ASCIICHAT_API unsigned short int opt_webcam_index

Definition at line 143 of file options/common.c.

143 {
144 if (!value_str || !out_index) {
145 return false;
146 }
147
148 char error_msg[256];
149 int parsed_index = validate_opt_device_index(value_str, error_msg, sizeof(error_msg));
150 if (parsed_index == INT_MIN) {
151 (void)fprintf(stderr, "Invalid webcam index: %s\n", error_msg);
152 return false;
153 }
154 // Webcam index doesn't support -1 (default), must be >= 0
155 if (parsed_index < 0) {
156 (void)fprintf(stderr, "Invalid webcam index '%s'. Webcam index must be a non-negative integer.\n", value_str);
157 return false;
158 }
159
160 *out_index = (unsigned short int)parsed_index;
161 return true;
162}
int validate_opt_device_index(const char *value_str, char *error_msg, size_t error_msg_size)
Validate device index (-1 for default, 0+ for specific device)
Definition validation.c:422

References validate_opt_device_index().

Referenced by parse_webcam_index_option().