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

Environment variable utilities with stack-based prompt responses. More...

Go to the source code of this file.

Functions

bool env_pop_prompt_response (char *response_out, size_t response_size)
 Pop the first response from ASCII_CHAT_QUESTION_PROMPT_RESPONSE stack.
 
bool env_has_prompt_response (void)
 Check if ASCII_CHAT_QUESTION_PROMPT_RESPONSE has any responses available.
 
bool env_validate_prompt_response_format (void)
 Validate ASCII_CHAT_QUESTION_PROMPT_RESPONSE format.
 

Detailed Description

Environment variable utilities with stack-based prompt responses.

Definition in file env.h.

Function Documentation

◆ env_has_prompt_response()

bool env_has_prompt_response ( void  )

Check if ASCII_CHAT_QUESTION_PROMPT_RESPONSE has any responses available.

Returns
true if at least one response is available, false otherwise

Definition at line 201 of file env.c.

201 {
202 const char *env_value = SAFE_GETENV("ASCII_CHAT_QUESTION_PROMPT_RESPONSE");
203 if (!env_value || env_value[0] == '\0' || env_value[0] == ';') {
204 return false;
205 }
206
207 // Check if it's all semicolons
208 for (const char *p = env_value; *p; p++) {
209 if (*p != ';') {
210 return true;
211 }
212 }
213
214 return false;
215}
#define SAFE_GETENV(name)
Definition common.h:434

References SAFE_GETENV.

◆ env_pop_prompt_response()

bool env_pop_prompt_response ( char *  response_out,
size_t  response_size 
)

Pop the first response from ASCII_CHAT_QUESTION_PROMPT_RESPONSE stack.

Format: "response1;response2;response3" or "response1;response2;response3;"

Examples:

  • "y;n;123" -> returns "y", sets env to "n;123"
  • "password" -> returns "password", sets env to ""
  • "y;" -> returns "y", sets env to ""
Parameters
response_outBuffer to store the popped response (must be at least 256 bytes)
response_sizeSize of response_out buffer
Returns
true if a response was successfully popped, false otherwise

Format: "response1;response2;response3" or "response1;response2;response3;" This function extracts the first response and updates the environment variable to contain the remaining responses.

Escaping: Use backslash to include literal semicolons or backslashes:

  • \; → ; (literal semicolon)
  • \ → \ (literal backslash)

Examples:

  • "y;n;123" -> returns "y", sets env to "n;123"
  • "password" -> returns "password", sets env to ""
  • "y;" -> returns "y", sets env to ""
  • "pass\;word;y" -> returns "pass;word", sets env to "y"
  • "path\\to\\file;n" -> returns "path\to\file", sets env to "n"
  • "" -> returns NULL
  • ";;y" -> returns NULL (invalid format)
  • ";y" -> returns NULL (invalid format)
Parameters
response_outBuffer to store the popped response (must be at least 256 bytes)
response_sizeSize of response_out buffer
Returns
true if a response was successfully popped, false otherwise

Definition at line 93 of file env.c.

93 {
94 if (!response_out || response_size < 2) {
95 return false;
96 }
97
98 const char *env_value = SAFE_GETENV("ASCII_CHAT_QUESTION_PROMPT_RESPONSE");
99 if (!env_value || env_value[0] == '\0') {
100 return false;
101 }
102
103 // Validate: no leading semicolon (unless escaped)
104 if (env_value[0] == ';') {
105 log_warn("Invalid ASCII_CHAT_QUESTION_PROMPT_RESPONSE format: leading semicolon");
106 return false;
107 }
108
109 // Find the first unescaped semicolon
110 const char *semicolon = find_unescaped_semicolon(env_value);
111
112 if (semicolon == NULL) {
113 // No semicolon - this is the last (or only) response
114 size_t len = strlen(env_value);
115 if (len == 0) {
116 return false;
117 }
118
119 // Validate: ensure it's not empty
120 if (len >= response_size) {
121 log_warn("Response too long: %zu bytes (max: %zu)", len, response_size - 1);
122 return false;
123 }
124
125 // Copy the response
126 SAFE_STRNCPY(response_out, env_value, response_size);
127
128 // Unescape the response (\; → ; and \\ → \‍)
129 unescape_response(response_out);
130
131 // Clear the environment variable
132 platform_unsetenv("ASCII_CHAT_QUESTION_PROMPT_RESPONSE");
133
134 log_dev("Popped last response from stack: '%s' (cleared env)", response_out);
135 return true;
136 }
137
138 // Calculate response length
139 size_t response_len = (size_t)(semicolon - env_value);
140
141 // Validate: no empty segment
142 if (response_len == 0) {
143 log_warn("Invalid ASCII_CHAT_QUESTION_PROMPT_RESPONSE format: empty segment");
144 return false;
145 }
146
147 if (response_len >= response_size) {
148 log_warn("Response too long: %zu bytes (max: %zu)", response_len, response_size - 1);
149 return false;
150 }
151
152 // Copy the first response
153 memcpy(response_out, env_value, response_len);
154 response_out[response_len] = '\0';
155
156 // Unescape the response (\; → ; and \\ → \‍)
157 unescape_response(response_out);
158
159 // Calculate remaining stack (skip the semicolon)
160 const char *remaining = semicolon + 1;
161
162 // Validate: if remaining is empty or only semicolons, clear the env
163 bool remaining_valid = false;
164 for (const char *p = remaining; *p; p++) {
165 if (*p != ';') {
166 remaining_valid = true;
167 break;
168 }
169 }
170
171 // Update environment variable with remaining responses
172 if (remaining_valid && remaining[0] != '\0') {
173 char new_env[1024];
174 int written = snprintf(new_env, sizeof(new_env), "ASCII_CHAT_QUESTION_PROMPT_RESPONSE=%s", remaining);
175 if (written < 0 || (size_t)written >= sizeof(new_env)) {
176 log_warn("Failed to format new environment variable");
177 return false;
178 }
179
180 if (platform_setenv("ASCII_CHAT_QUESTION_PROMPT_RESPONSE", remaining) != 0) {
181 log_warn("Failed to update ASCII_CHAT_QUESTION_PROMPT_RESPONSE");
182 return false;
183 }
184
185 log_debug("Popped response from stack: '%s' (remaining: '%s')", response_out, remaining);
186 } else {
187 // No valid remaining responses - clear the env
188 platform_unsetenv("ASCII_CHAT_QUESTION_PROMPT_RESPONSE");
189
190 log_debug("Popped response from stack: '%s' (cleared env)", response_out);
191 }
192
193 return true;
194}
#define SAFE_STRNCPY(dst, src, size)
Definition common.h:414
#define log_warn(...)
Log a WARN message.
Definition log/log.h:574
#define log_dev(...)
Log a DEV message (most verbose, development only)
Definition log/log.h:534
#define log_debug(...)
Log a DEBUG message.
Definition log/log.h:548
int platform_setenv(const char *name, const char *value)
Set an environment variable.
Definition wasm/system.c:50
int platform_unsetenv(const char *name)
Remove an environment variable.
Definition wasm/system.c:56

References log_debug, log_dev, log_warn, platform_setenv(), platform_unsetenv(), SAFE_GETENV, and SAFE_STRNCPY.

◆ env_validate_prompt_response_format()

bool env_validate_prompt_response_format ( void  )

Validate ASCII_CHAT_QUESTION_PROMPT_RESPONSE format.

Valid formats: "y", "y;n", "y;n;123", "y;n;123;" Invalid formats: "", ";", ";y", "y;;n", ";;"

Returns
true if format is valid, false otherwise

Valid formats:

  • "y"
  • "y;n"
  • "y;n;123"
  • "y;n;123;"
  • "pass\;word;y" (escaped semicolon)
  • "path\\to\\file" (escaped backslash)

Invalid formats:

  • ""
  • ";"
  • ";y"
  • "y;;n" (empty segment)
  • ";;"
Returns
true if format is valid, false otherwise

Definition at line 237 of file env.c.

237 {
238 const char *env_value = SAFE_GETENV("ASCII_CHAT_QUESTION_PROMPT_RESPONSE");
239 if (!env_value) {
240 return true; // Not set is valid (no automated responses)
241 }
242
243 if (env_value[0] == '\0') {
244 return true; // Empty is valid (no automated responses)
245 }
246
247 // Invalid: leading semicolon (unless escaped)
248 if (env_value[0] == ';') {
249 return false;
250 }
251
252 // Check for consecutive unescaped semicolons or empty segments
253 const char *p = env_value;
254 bool last_was_semicolon = false;
255
256 while (*p) {
257 if (*p == '\\' && *(p + 1)) {
258 // Skip escaped character
259 last_was_semicolon = false;
260 p += 2;
261 continue;
262 }
263 if (*p == ';') {
264 if (last_was_semicolon) {
265 return false; // Consecutive unescaped semicolons (empty segment)
266 }
267 last_was_semicolon = true;
268 } else {
269 last_was_semicolon = false;
270 }
271 p++;
272 }
273
274 // Trailing semicolon is allowed
275 return true;
276}

References SAFE_GETENV.