ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
environment.c
Go to the documentation of this file.
1
7#include <ascii-chat/options/manpage/content/environment.h>
8#include <ascii-chat/log/logging.h>
9#include <ascii-chat/common.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14char *manpage_content_generate_environment(const options_config_t *config) {
15 if (!config || config->num_descriptors == 0) {
16 char *buffer = SAFE_MALLOC(1, char *);
17 buffer[0] = '\0';
18 return buffer;
19 }
20
21 // Generate only ASCII_CHAT_* environment variables from config
22 // Manual variables are preserved from the template
23 size_t buffer_capacity = 32768;
24 char *buffer = SAFE_MALLOC(buffer_capacity, char *);
25 size_t offset = 0;
26
27 // Iterate through all option descriptors
28 for (size_t i = 0; i < config->num_descriptors; i++) {
29 const option_descriptor_t *desc = &config->descriptors[i];
30
31 // Only include descriptors that have environment variable names
32 if (!desc->env_var_name) {
33 continue;
34 }
35
36 // Ensure buffer is large enough
37 if (offset + 512 >= buffer_capacity) {
38 buffer_capacity *= 2;
39 buffer = SAFE_REALLOC(buffer, buffer_capacity, char *);
40 }
41
42 log_debug("[ENVIRONMENT] env=%s, desc=%s", desc->env_var_name ? desc->env_var_name : "NULL",
43 desc->help_text ? desc->help_text : "NULL");
44
45 // Generate .TP tagged paragraph for this environment variable
46 offset += safe_snprintf(buffer + offset, buffer_capacity - offset, ".TP\n");
47 offset += safe_snprintf(buffer + offset, buffer_capacity - offset, ".B %s\n", desc->env_var_name);
48
49 if (desc->help_text) {
50 offset += safe_snprintf(buffer + offset, buffer_capacity - offset, "%s\n", desc->help_text);
51 }
52 }
53
54 log_debug("Generated ENVIRONMENT ASCII_CHAT_* section (%zu bytes)", offset);
55 return buffer;
56}
57
61typedef struct {
62 const char *name;
63 const char *description;
64 const char *option_long_name;
66
67// Comparison function for qsort
68static int env_var_compare(const void *a, const void *b) {
69 const env_var_entry_t *var_a = (const env_var_entry_t *)a;
70 const env_var_entry_t *var_b = (const env_var_entry_t *)b;
71 return strcmp(var_a->name, var_b->name);
72}
73
74char *manpage_content_generate_environment_with_manual(const options_config_t *config, const char **manual_vars,
75 size_t manual_count, const char **manual_descs) {
76
77 if (!config) {
78 char *buffer = SAFE_MALLOC(1, char *);
79 buffer[0] = '\0';
80 return buffer;
81 }
82
83 // Count how many ASCII_CHAT_* variables we have
84 size_t num_auto_vars = 0;
85 for (size_t i = 0; i < config->num_descriptors; i++) {
86 if (config->descriptors[i].env_var_name) {
87 num_auto_vars++;
88 }
89 }
90
91 // Allocate array for all variables
92 size_t total_vars = num_auto_vars + manual_count;
93 env_var_entry_t *all_vars = SAFE_MALLOC(total_vars * sizeof(env_var_entry_t), env_var_entry_t *);
94 size_t var_idx = 0;
95
96 // Copy auto-generated variables from config
97 for (size_t i = 0; i < config->num_descriptors; i++) {
98 const option_descriptor_t *desc = &config->descriptors[i];
99 if (desc->env_var_name) {
100 all_vars[var_idx].name = desc->env_var_name;
101 all_vars[var_idx].description = desc->help_text ? desc->help_text : "";
102 all_vars[var_idx].option_long_name = desc->long_name; // Store for reference
103 var_idx++;
104 }
105 }
106
107 // Add manual variables
108 for (size_t i = 0; i < manual_count && var_idx < total_vars; i++) {
109 all_vars[var_idx].name = manual_vars[i];
110 all_vars[var_idx].description = (manual_descs && manual_descs[i]) ? manual_descs[i] : "";
111 all_vars[var_idx].option_long_name = NULL; // Manual variables have no option reference
112 var_idx++;
113 }
114
115 // Sort all variables alphabetically
116 qsort(all_vars, total_vars, sizeof(env_var_entry_t), env_var_compare);
117
118 // Generate output buffer with all environment variables
119 size_t buffer_capacity = 32768;
120 char *buffer = SAFE_MALLOC(buffer_capacity, char *);
121 size_t offset = 0;
122
123 // Write all environment variables in sorted order
124 for (size_t i = 0; i < total_vars; i++) {
125 if (offset + 512 >= buffer_capacity) {
126 buffer_capacity *= 2;
127 buffer = SAFE_REALLOC(buffer, buffer_capacity, char *);
128 }
129
130 offset += safe_snprintf(buffer + offset, buffer_capacity - offset, ".TP\n");
131 offset += safe_snprintf(buffer + offset, buffer_capacity - offset, ".B %s\n", all_vars[i].name);
132 if (*all_vars[i].description) {
133 if (all_vars[i].option_long_name) {
134 // For auto-generated variables, just reference the flag
135 offset += safe_snprintf(buffer + offset, buffer_capacity - offset, "See: \\fB\\-\\-%s\\fR\n",
136 all_vars[i].option_long_name);
137 } else {
138 // For manual variables, show full description
139 offset += safe_snprintf(buffer + offset, buffer_capacity - offset, "%s\n", all_vars[i].description);
140 }
141 }
142 }
143
144 SAFE_FREE(all_vars);
145
146 log_debug("Generated ENVIRONMENT section (%zu manual + %zu auto = %zu total, %zu bytes)", manual_count, num_auto_vars,
147 total_vars, offset);
148 return buffer;
149}
150
152 if (content) {
153 SAFE_FREE(content);
154 }
155}
char * manpage_content_generate_environment_with_manual(const options_config_t *config, const char **manual_vars, size_t manual_count, const char **manual_descs)
Definition environment.c:74
void manpage_content_free_environment(char *content)
char * manpage_content_generate_environment(const options_config_t *config)
Definition environment.c:14
Environment variable entry for manpage generation.
Definition environment.c:61
const char * name
Environment variable name.
Definition environment.c:62
const char * option_long_name
Long option name (for "(see --option)" suffix), or NULL for manual.
Definition environment.c:64
const char * description
Description text.
Definition environment.c:63
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Safe formatted string printing to buffer.
Definition system.c:456