ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
presets.c File Reference

Preset option configurations for ascii-chat modes. More...

Go to the source code of this file.

Functions

void options_builder_add_logging_group (options_builder_t *b)
 Add binary-level logging options to a builder.
 
options_config_t * options_preset_unified (const char *program_name, const char *description)
 Build unified options config with ALL options (binary + all modes)
 

Detailed Description

Preset option configurations for ascii-chat modes.

Definition in file presets.c.

Function Documentation

◆ options_builder_add_logging_group()

void options_builder_add_logging_group ( options_builder_t *  b)

Add binary-level logging options to a builder.

Deprecated:
This function is deprecated. Use options_registry_add_all_to_builder() instead. All option definitions are now centralized in the registry.

Definition at line 31 of file presets.c.

31 {
32 (void)b;
33 // Kept for backward compatibility but no longer used
34}

◆ options_preset_unified()

options_config_t * options_preset_unified ( const char *  program_name,
const char *  description 
)

Build unified options config with ALL options (binary + all modes)

This is the single source of truth for all options. Each option has a mode_bitmask indicating which modes it applies to. The config includes all options, and validation happens after parsing based on detected mode.

Definition at line 51 of file presets.c.

51 {
52 options_builder_t *b = options_builder_create(sizeof(options_t));
53 if (!b) {
54 SET_ERRNO(ERROR_MEMORY, "Failed to create options builder");
55 return NULL;
56 }
57
58 b->program_name = program_name ? program_name : "ascii-chat";
59 b->description = description ? description : "Video chat in your terminal";
60
61 // Add ALL options from registry (binary + all modes)
62 asciichat_error_t err = options_registry_add_all_to_builder(b);
63 if (err != ASCIICHAT_OK) {
65 SET_ERRNO(err, "Failed to add all options to builder");
66 return NULL;
67 }
68
69 // Add positional arguments for each mode
70 // These allow parsing of positional arguments like "192.168.1.1" for client mode
71 // and "[bind-address]" for server mode
72
73 // Generate random session strings for examples
74 // Use static buffers so they persist after the function returns
75 static char session_buf1[SESSION_STRING_BUFFER_SIZE];
76 static char session_buf2[SESSION_STRING_BUFFER_SIZE];
77 static char session_buf3[SESSION_STRING_BUFFER_SIZE];
78 static char session_buf4[SESSION_STRING_BUFFER_SIZE];
79 static char session_buf5[SESSION_STRING_BUFFER_SIZE];
80 static char session_buf6[SESSION_STRING_BUFFER_SIZE];
81 static char session_buf7[SESSION_STRING_BUFFER_SIZE];
82 static char session_buf8[SESSION_STRING_BUFFER_SIZE];
83 static char session_buf9[SESSION_STRING_BUFFER_SIZE];
84 static char session_buf10[SESSION_STRING_BUFFER_SIZE];
85
86 // Fallback strings if generation fails
87 char *example_session_string1 = "adjective-noun-noun";
88 char *example_session_string2 = "adjective-noun-noun";
89 char *example_session_string3 = "adjective-noun-noun";
90 char *example_session_string4 = "adjective-noun-noun";
91 char *example_session_string5 = "adjective-noun-noun";
92 char *example_session_string6 = "adjective-noun-noun";
93 char *example_session_string7 = "adjective-noun-noun";
94 char *example_session_string8 = "adjective-noun-noun";
95 char *example_session_string9 = "adjective-noun-noun";
96 char *example_session_string10 = "adjective-noun-noun";
97
98 // Generate session strings for examples (sodium_init called as needed by acds_string_generate)
99 acds_string_generate(session_buf1, sizeof(session_buf1));
100 if (session_buf1[0] != '\0') {
101 example_session_string1 = session_buf1;
102 }
103 acds_string_generate(session_buf2, sizeof(session_buf2));
104 if (session_buf2[0] != '\0') {
105 example_session_string2 = session_buf2;
106 }
107 acds_string_generate(session_buf3, sizeof(session_buf3));
108 if (session_buf3[0] != '\0') {
109 example_session_string3 = session_buf3;
110 }
111 acds_string_generate(session_buf4, sizeof(session_buf4));
112 if (session_buf4[0] != '\0') {
113 example_session_string4 = session_buf4;
114 }
115 acds_string_generate(session_buf5, sizeof(session_buf5));
116 if (session_buf5[0] != '\0') {
117 example_session_string5 = session_buf5;
118 }
119 acds_string_generate(session_buf6, sizeof(session_buf6));
120 if (session_buf6[0] != '\0') {
121 example_session_string6 = session_buf6;
122 }
123 acds_string_generate(session_buf7, sizeof(session_buf7));
124 if (session_buf7[0] != '\0') {
125 example_session_string7 = session_buf7;
126 }
127 acds_string_generate(session_buf8, sizeof(session_buf8));
128 if (session_buf8[0] != '\0') {
129 example_session_string8 = session_buf8;
130 }
131 acds_string_generate(session_buf9, sizeof(session_buf9));
132 if (session_buf9[0] != '\0') {
133 example_session_string9 = session_buf9;
134 }
135 acds_string_generate(session_buf10, sizeof(session_buf10));
136 if (session_buf10[0] != '\0') {
137 example_session_string10 = session_buf10;
138 }
139
140 // Build session string examples dynamically for discovery mode
141 // These appear at the beginning of the examples section, right after "start new session"
142 static char example_buf1[SESSION_STRING_BUFFER_SIZE];
143 static char example_buf2[SESSION_STRING_BUFFER_SIZE];
144 static char example_buf3[SESSION_STRING_BUFFER_SIZE];
145 static char example_buf4[SESSION_STRING_BUFFER_SIZE];
146 static char example_buf5[SESSION_STRING_BUFFER_SIZE];
147 static char example_buf6[SESSION_STRING_BUFFER_SIZE];
148 static char example_buf7[SESSION_STRING_BUFFER_SIZE];
149 static char example_buf8[SESSION_STRING_BUFFER_SIZE];
150 static char example_buf9[SESSION_STRING_BUFFER_SIZE];
151 static char example_buf10[SESSION_STRING_BUFFER_SIZE];
152
153 safe_snprintf(example_buf1, sizeof(example_buf1), "%s", example_session_string1);
154 safe_snprintf(example_buf2, sizeof(example_buf2), "%s --discovery-service discovery.example.com",
155 example_session_string2);
156 safe_snprintf(example_buf3, sizeof(example_buf3), "%s -f video.mp4", example_session_string3);
157 safe_snprintf(example_buf4, sizeof(example_buf4), "%s --url 'https://youtu.be/7ynHVGCehoM'", example_session_string4);
158 safe_snprintf(example_buf5, sizeof(example_buf5), "%s -f '-'", example_session_string5);
159 safe_snprintf(example_buf6, sizeof(example_buf6), "%s --palette-chars '@%%#*+=-:. '", example_session_string6);
160 safe_snprintf(example_buf7, sizeof(example_buf7), "%s", example_session_string7);
161 safe_snprintf(example_buf8, sizeof(example_buf8), "%s", example_session_string8);
162 safe_snprintf(example_buf9, sizeof(example_buf9), "%s", example_session_string9);
163 safe_snprintf(example_buf10, sizeof(example_buf10), "%s --matrix --color-filter rainbow", example_session_string10);
164
165 // Client mode: [address] - can be IP, hostname, hostname:port, or WebSocket URL
166 static const char *client_examples[] = {"localhost",
167 "ascii-chat.com",
168 "0.0.0.0",
169 "::",
170 "192.168.1.1:8080",
171 "[2001:db8::42]:27224",
172 "233.27.48.203:27224",
173 "62fb:759e:2bce:21d7:9e5d:13f8:3c11:5084:27224",
174 "ws://example.com:8080",
175 "wss://secure.example.com:443"};
176 // Discovery mode: [session-string] - session string or empty to start new session
177 // Use simple static examples for positional arguments section (dynamic strings shown in examples section)
178 static const char *discovery_examples[] = {"(empty) start new session", (const char *)example_buf7,
179 (const char *)example_buf8, (const char *)example_buf9,
180 (const char *)example_buf10};
182 b, "session-string", "(optional) Random three words in format adjective-noun-noun that connect you to a call.",
183 false, "POSITIONAL ARGUMENTS", discovery_examples, ARRAY_SIZE(discovery_examples), OPTION_MODE_DISCOVERY,
185
186 // Server and Discovery Service modes: [bind-address] [bind-address] - can be IP or hostname, up to 2 for IPv4/IPv6
187 static const char *server_examples[] = {"localhost",
188 "ascii-chat.com",
189 "0.0.0.0",
190 "::",
191 "234.50.188.236",
192 "9631:54e7:5b5c:80dc:0f62:1f01:7ccf:5512",
193 "105.137.19.11 3a08:7276:ccb4:7b31:e934:5330:9b3a:9598",
194 "::1 192.168.1.100"};
195 options_builder_add_positional(b, "bind-address",
196 "(optional) 0-2 addresses for a server to bind to, one IPv4 and the other IPv6.",
197 false, "POSITIONAL ARGUMENTS", server_examples, ARRAY_SIZE(server_examples),
198 OPTION_MODE_SERVER | OPTION_MODE_DISCOVERY_SVC, parse_server_bind_address);
199
200 options_builder_add_positional(b, "address", "(optional) Server address for client to connect to.", false,
201 "POSITIONAL ARGUMENTS", client_examples, ARRAY_SIZE(client_examples),
202 OPTION_MODE_CLIENT, parse_client_address);
203
204 // Add usage lines for all modes
205 options_builder_add_usage(b, NULL, NULL, true, "Start a new session (share the session string)");
206 options_builder_add_usage(b, NULL, "<session-string>", true, "Join an existing session");
207 options_builder_add_usage(b, NULL, "<mode>", true, "Run in a specific mode");
208 options_builder_add_usage(b, "server", "[bind-address] [bind-address]", true,
209 "Start server (can specify 0-2 bind addresses, one IPv4 and the other IPv6)");
210 options_builder_add_usage(b, "client", "[address]", true, "Connect to server (defaults to localhost:27224)");
211 options_builder_add_usage(b, "mirror", NULL, true, "View local webcam or media file as ASCII art");
212 options_builder_add_usage(b, "discovery-service", "[bind-address] [bind-address]", true,
213 "Start discovery service (can specify 0-2 bind addresses, one IPv4 and the other IPv6)");
214
215 // Add examples for binary-level help and discovery mode
216 options_builder_add_example(b, OPTION_MODE_BINARY, NULL, "Start new session (share the session string)", false);
217 options_builder_add_example(b, OPTION_MODE_BINARY, example_buf1, "Join a session using the session string", true);
218 options_builder_add_example(b, OPTION_MODE_BINARY, example_buf2, "Join session via custom discovery server", true);
219 options_builder_add_example(b, OPTION_MODE_BINARY, example_buf3, "Join session and stream from local video file",
220 true);
221 options_builder_add_example(b, OPTION_MODE_BINARY, example_buf4, "Join session and stream from YouTube video", true);
222 options_builder_add_example(b, OPTION_MODE_BINARY, example_buf5,
223 "Join session and stream media from stdin (cat file.mov | ascii-chat ... -f '-')", true);
224 options_builder_add_example(b, OPTION_MODE_BINARY, example_buf6, "Join session with custom ASCII palette characters",
225 true);
226
227 // Add examples for server-like modes (server + discovery-service)
228 options_builder_add_example(b, OPTION_MODE_SERVER_LIKE, NULL, "Start on localhost (127.0.0.1 and ::1)", false);
229 options_builder_add_example(b, OPTION_MODE_SERVER_LIKE, "0.0.0.0", "Start on all IPv4 interfaces", false);
230 options_builder_add_example(b, OPTION_MODE_SERVER_LIKE,
231 "0.0.0.0 ::", "Start on all IPv4 and IPv6 interfaces (dual-stack)", false);
232 options_builder_add_example(b, OPTION_MODE_SERVER_LIKE, "--port 8080", "Start on custom port", false);
233
234 // Server-specific examples
235 options_builder_add_example(b, OPTION_MODE_SERVER, "--key ~/.ssh/id_ed25519 --discovery",
236 "Start with identity key and discovery registration", false);
237
238 // Add examples for client-like modes (client + mirror)
239 options_builder_add_example(b, OPTION_MODE_CLIENT_LIKE, "--url 'https://youtu.be/7ynHVGCehoM'",
240 "Stream from YouTube URL (also supports RTSP, HTTP, and HTTPS URLs)", false);
241 options_builder_add_example(b, OPTION_MODE_CLIENT_LIKE, "--url 'https://www.twitch.tv/ludwig'",
242 "Stream Ludwig from videogames on Twitch", false);
243 options_builder_add_example(b, OPTION_MODE_CLIENT_LIKE, "-f video.mp4", "Stream from local video file", false);
244 options_builder_add_example(b, OPTION_MODE_CLIENT_LIKE, "--palette-chars '@%#*+=-:. '",
245 "Custom palette characters to use. UTF-8 is allowed.", false);
247 b, OPTION_MODE_CLIENT_LIKE, "--snapshot",
248 "Print ascii art for --snapshot-delay's value of seconds then print the last frame and exit. "
249 "In snapshot mode, --width, --height, and --color are NOT autodetected when piping stdin in or redirecting "
250 "output.",
251 false);
252 options_builder_add_example(b, OPTION_MODE_CLIENT_LIKE, "--color-filter cyan --palette cool",
253 "Apply cyan color filter and cool palette", false);
254
255 // Client-specific examples
256 options_builder_add_example(b, OPTION_MODE_CLIENT, "example.com", "Connect to remote server", false);
257 options_builder_add_example(b, OPTION_MODE_CLIENT, "example.com:8080", "Connect to remote server on custom port",
258 false);
259 options_builder_add_example(b, OPTION_MODE_CLIENT, "--color-mode mono --render-mode half-block --width 120",
260 "Connect with custom display options", false);
261
262 // Mirror-specific examples (unique to mirror mode)
264 b, OPTION_MODE_MIRROR, NULL,
265 "View the webcam or files or URLs as ASCII art. Like client mode but without network connectivity or a server.",
266 false);
267 options_builder_add_example(b, OPTION_MODE_MIRROR, "--color-mode mono", "View webcam in black and white", false);
268 options_builder_add_example(b, OPTION_MODE_MIRROR, "--color-filter green",
269 "View webcam with green monochromatic color filter", false);
270 options_builder_add_example(b, OPTION_MODE_MIRROR, "--matrix --color-filter rainbow",
271 "Matrix rain effect with rainbow colors cycling over 3.5s", false);
272 options_builder_add_example(b, OPTION_MODE_MIRROR, "--file '-'",
273 "Stream media from stdin (cat file.gif | ascii-chat mirror -f '-')", false);
274 options_builder_add_example_utility(b, OPTION_MODE_MIRROR, "cat video.avi | ascii-chat mirror -f '-' -l -s 00:30",
275 "Stream .avi from stdin, looped, seeking to 00:30", true);
276 options_builder_add_example(b, OPTION_MODE_MIRROR, "--file video.mov --seek 22:10",
277 "Start playback at exactly 22:10 (also works with --url)", false);
278 options_builder_add_example(b, OPTION_MODE_MIRROR, "-f 'https://youtu.be/LS9W8SO-Two' -S -D 0 -s 5:12",
279 "Print a single frame from a YouTube video at exactly 5:12 and exit", false);
280 options_builder_add_example(b, OPTION_MODE_MIRROR, "-S -D 0 | tee frame.txt | pbcopy",
281 "Capture single ASCII frame to clipboard (macOS) and file", false);
282 options_builder_add_example_utility(b, OPTION_MODE_MIRROR, "pbpaste | cat -",
283 "View ASCII frame from clipboard (macOS)", true);
284
285 // Discovery-service specific examples
286 options_builder_add_example(b, OPTION_MODE_DISCOVERY_SVC, "--require-server-identity --require-client-identity",
287 "Enforce identity verification for all parties", false);
288
289 // Add mode descriptions
290 options_builder_add_mode(b, "server", "Run as multi-client video chat server");
291 options_builder_add_mode(b, "client", "Run as video chat client (connect to server)");
292 options_builder_add_mode(b, "mirror", "View local webcam as ASCII art (no server)");
293 options_builder_add_mode(b, "discovery-service", "Secure P2P session signalling");
294
295 // Add custom help sections for interactive modes (client, mirror, and discovery)
296 options_builder_add_custom_section(b, "KEYBINDINGS",
297 "Available in ascii-chat client, mirror, and discovery modes. "
298 "While rendering, press '?' to display a keyboard shortcuts help menu showing:\n"
299 " - Available keybindings (?, Space, arrows, m, c, f, r)\n"
300 " - Current settings (volume, color mode, audio status, etc.)",
301 OPTION_MODE_CLIENT_LIKE);
302
303 // Add environment variables section (all modes)
305 b, "ENVIRONMENT",
306 "All command-line flags that accept values have corresponding environment variables.\n"
307 " Format: ASCII_CHAT_<FLAG_NAME> where FLAG_NAME is uppercase with hyphens replaced by underscores\n"
308 " Example: --color-filter maps to ASCII_CHAT_COLOR_FILTER\n"
309 "\n"
310 " Configuration precedence (lowest to highest):\n"
311 " 1. Config file values (~/.ascii-chat/config.toml)\n"
312 " 2. Environment variables (ASCII_CHAT_*)\n"
313 " 3. Command-line flags (--flag-name)\n"
314 "\n"
315 " Additional environment variables are documented in the ascii-chat(1) man page.",
316 OPTION_MODE_ALL);
317
318 // Add common dependencies (these will be validated after parsing)
319 // Note: Dependencies are validated at runtime, so we add them here for documentation
320 // URL conflicts: --url cannot be used with --file or --loop
322 "Option --url cannot be used with --file (--url takes priority)");
324 b, "url", "loop", "Option --url cannot be used with --loop (network streams cannot be looped)");
325 // Encryption conflicts
326 options_builder_add_dependency_conflicts(b, "no-encrypt", "encrypt", "Cannot use --no-encrypt with --encrypt");
327 // Compression conflicts
328 options_builder_add_dependency_conflicts(b, "no-compress", "compression-level",
329 "Cannot use --no-compress with --compression-level");
330 // Audio encoding conflicts
331 options_builder_add_dependency_conflicts(b, "encode-audio", "no-encode-audio",
332 "Cannot use both --encode-audio and --no-encode-audio");
333 // Requirements
334 options_builder_add_dependency_requires(b, "snapshot-delay", "snapshot",
335 "Option --snapshot-delay requires --snapshot");
336 options_builder_add_dependency_requires(b, "loop", "file", "Option --loop requires --file");
337
338 const options_config_t *config = options_builder_build(b);
340 return config;
341}
void options_builder_add_usage(options_builder_t *builder, const char *mode, const char *positional, bool show_options, const char *description)
Definition builder.c:1218
void options_builder_add_example(options_builder_t *builder, uint32_t mode_bitmask, const char *args, const char *description, bool owns_args)
Definition builder.c:1231
void options_builder_add_dependency_requires(options_builder_t *builder, const char *option_name, const char *depends_on, const char *error_message)
Definition builder.c:1106
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, option_mode_bitmask_t mode_bitmask, int(*parse_fn)(const char *arg, void *config, char **remaining, int num_remaining, char **error_msg))
Definition builder.c:1168
void options_builder_add_dependency_conflicts(options_builder_t *builder, const char *option_name, const char *conflicts_with, const char *error_message)
Definition builder.c:1118
void options_builder_add_mode(options_builder_t *builder, const char *name, const char *description)
Definition builder.c:1284
void options_builder_add_custom_section(options_builder_t *builder, const char *heading, const char *content, option_mode_bitmask_t mode_bitmask)
Definition builder.c:1295
void options_builder_destroy(options_builder_t *builder)
Definition builder.c:437
options_config_t * options_builder_build(options_builder_t *builder)
Definition builder.c:452
void options_builder_add_example_utility(options_builder_t *builder, uint32_t mode_bitmask, const char *args, const char *description, bool is_utility_command)
Add an example with utility command support.
Definition builder.c:1265
options_builder_t * options_builder_create(size_t struct_size)
Definition builder.c:351
asciichat_error_t acds_string_generate(char *output, size_t output_size)
int parse_server_bind_address(const char *arg, void *config, char **remaining, int num_remaining, char **error_msg)
Parse server bind address positional argument.
Definition parsers.c:512
int parse_client_address(const char *arg, void *config, char **remaining, int num_remaining, char **error_msg)
Parse client address positional argument.
Definition parsers.c:634
asciichat_error_t options_registry_add_all_to_builder(options_builder_t *builder)
Definition public_api.c:20
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Safe formatted string printing to buffer.
Definition system.c:456

References acds_string_generate(), options_builder_add_custom_section(), options_builder_add_dependency_conflicts(), options_builder_add_dependency_requires(), options_builder_add_example(), options_builder_add_example_utility(), options_builder_add_mode(), options_builder_add_positional(), options_builder_add_usage(), options_builder_build(), options_builder_create(), options_builder_destroy(), options_registry_add_all_to_builder(), parse_client_address(), parse_server_bind_address(), and safe_snprintf().

Referenced by action_create_config(), action_create_manpage(), options_init(), and usage().