7 #include "../cmdline.h"
9 static char* resize(
char** buffer,
size_t* size,
size_t increment)
11 const size_t nsize = *size + increment;
12 char* tmp = realloc(*buffer, nsize);
16 "Could not reallocate string buffer from %" PRIuz
" to %" PRIuz
" bytes.\n",
21 memset(&tmp[*size],
'\0', increment);
27 static char* append(
char** buffer,
size_t* size,
const char* str)
29 const size_t len = strnlen(*buffer, *size);
30 const size_t add = strlen(str);
31 const size_t required = len + add + 1;
35 if (!resize(buffer, size, required - *size))
38 strncpy(&(*buffer)[len], str, add);
42 static LPSTR tr_esc_str(LPCSTR arg,
bool format,
int* failed)
44 const char* str = NULL;
53 const size_t s = strlen(arg) + 1;
54 if (!resize(&tmp, &ds, s))
60 for (
size_t x = 0; x < s; x++)
67 if (!append(&tmp, &ds, str))
80 if (!append(&tmp, &ds, str))
93 if (!append(&tmp, &ds, str))
102 if (!append(&tmp, &ds, str))
110 if (!append(&tmp, &ds,
"\\&."))
119 if (!append(&tmp, &ds,
"\n.br\n"))
128 if (!append(&tmp, &ds, data))
140 int main(
int argc,
char* argv[])
143 size_t elements =
sizeof(global_cmd_args) /
sizeof(global_cmd_args[0]);
147 (void)fprintf(stderr,
"Usage: %s <output file name>\n", argv[0]);
151 const char* fname = argv[1];
153 (void)fprintf(stdout,
"Generating manpage file '%s'\n", fname);
154 FILE* fp = fopen(fname,
"w");
157 (void)fprintf(stderr,
"Could not open '%s' for writing.\n", fname);
162 (void)fprintf(fp,
".SH \"OPTIONS\"\n");
166 (void)fprintf(stderr,
"The argument array 'args' is empty, writing an empty file.\n");
170 for (
size_t x = 0; x < elements - 1; x++)
174 char* name = tr_esc_str(arg->Name, FALSE, &failed);
175 char* alias = tr_esc_str(arg->Alias, FALSE, &failed);
176 char* format = tr_esc_str(arg->Format, TRUE, &failed);
177 char* text = tr_esc_str(arg->Text, FALSE, &failed);
189 (void)fprintf(fp,
".PP\n");
193 (void)fprintf(fp,
"%s\\fB", first ?
"" :
", ");
195 if (arg->Flags == COMMAND_LINE_VALUE_BOOL)
196 (void)fprintf(fp,
"%s", arg->Default ?
"\\-" :
"+");
198 (
void)fprintf(fp,
"/");
200 (void)fprintf(fp,
"%s\\fR", name);
204 if (arg->Flags == COMMAND_LINE_VALUE_OPTIONAL)
205 (void)fprintf(fp,
"[");
207 (void)fprintf(fp,
":%s", format);
209 if (arg->Flags == COMMAND_LINE_VALUE_OPTIONAL)
210 (void)fprintf(fp,
"]");
219 (void)fprintf(fp,
"\n");
223 (void)fprintf(fp,
".RS 4\n");
224 const int hasText = text && (strnlen(text, 2) > 0);
226 (void)fprintf(fp,
"%s", text);
228 if (arg->Flags & COMMAND_LINE_VALUE_BOOL &&
229 (!arg->Default || arg->Default == BoolValueTrue))
230 (
void)fprintf(fp,
" (default:%s)\n", arg->Default ?
"on" :
"off");
231 else if (arg->Default)
233 char* value = tr_esc_str(arg->Default, FALSE, &failed);
239 (void)fprintf(fp,
" (default:%s)\n", value);
243 (void)fprintf(fp,
"\n");
246 (void)fprintf(fp,
".RE\n");
258 (void)fprintf(stdout,
"successfully generated '%s'\n", fname);
260 (
void)fprintf(stdout,
"failed to generate '%s'\n", fname);