1d33095500
Fix unused return values, cast to void if on purpose
213 lines
4.3 KiB
C
213 lines
4.3 KiB
C
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
|
|
#include "../cmdline.h"
|
|
|
|
static char* resize(char** buffer, size_t* size, size_t increment)
|
|
{
|
|
const size_t nsize = *size + increment;
|
|
char* tmp = realloc(*buffer, nsize);
|
|
if (!tmp)
|
|
{
|
|
(void)fprintf(stderr,
|
|
"Could not reallocate string buffer from %" PRIuz " to %" PRIuz " bytes.\n",
|
|
*size, nsize);
|
|
free(*buffer);
|
|
return NULL;
|
|
}
|
|
memset(&tmp[*size], '\0', increment);
|
|
*size = nsize;
|
|
*buffer = tmp;
|
|
return tmp;
|
|
}
|
|
|
|
static char* append(char** buffer, size_t* size, const char* str)
|
|
{
|
|
const size_t len = strnlen(*buffer, *size);
|
|
const size_t add = strlen(str);
|
|
const size_t required = len + add + 1;
|
|
|
|
if (required > *size)
|
|
{
|
|
if (!resize(buffer, size, required - *size))
|
|
return NULL;
|
|
}
|
|
strcat(*buffer, str);
|
|
return *buffer;
|
|
}
|
|
|
|
static LPSTR tr_esc_str(LPCSTR arg, bool format)
|
|
{
|
|
const char* str = NULL;
|
|
LPSTR tmp = NULL;
|
|
size_t ds = 0;
|
|
|
|
if (NULL == arg)
|
|
return NULL;
|
|
|
|
const size_t s = strlen(arg) + 1;
|
|
if (!resize(&tmp, &ds, s))
|
|
exit(-2);
|
|
|
|
for (size_t x = 0; x < s; x++)
|
|
{
|
|
char data[2] = { 0 };
|
|
switch (arg[x])
|
|
{
|
|
case '<':
|
|
if (format)
|
|
str = "<replaceable>";
|
|
else
|
|
str = "<";
|
|
|
|
if (!append(&tmp, &ds, str))
|
|
exit(-3);
|
|
break;
|
|
|
|
case '>':
|
|
if (format)
|
|
str = "</replaceable>";
|
|
else
|
|
str = ">";
|
|
|
|
if (!append(&tmp, &ds, str))
|
|
exit(-4);
|
|
break;
|
|
|
|
case '\'':
|
|
if (!append(&tmp, &ds, "'"))
|
|
exit(-5);
|
|
break;
|
|
|
|
case '"':
|
|
if (!append(&tmp, &ds, """))
|
|
exit(-6);
|
|
break;
|
|
|
|
case '&':
|
|
if (!append(&tmp, &ds, "&"))
|
|
exit(-6);
|
|
break;
|
|
|
|
case '\r':
|
|
case '\n':
|
|
if (!append(&tmp, &ds, "<sbr/>"))
|
|
exit(-7);
|
|
break;
|
|
|
|
default:
|
|
data[0] = arg[x];
|
|
if (!append(&tmp, &ds, data))
|
|
exit(-8);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
size_t elements = sizeof(global_cmd_args) / sizeof(global_cmd_args[0]);
|
|
const char* fname = "freerdp-argument.1.xml";
|
|
|
|
(void)fprintf(stdout, "Generating docbook file '%s'\n", fname);
|
|
FILE* fp = fopen(fname, "w");
|
|
if (NULL == fp)
|
|
{
|
|
(void)fprintf(stderr, "Could not open '%s' for writing.\n", fname);
|
|
return -1;
|
|
}
|
|
|
|
/* The tag used as header in the manpage */
|
|
(void)fprintf(fp, "<refsect1>\n");
|
|
(void)fprintf(fp, "\t<title>Options</title>\n");
|
|
(void)fprintf(fp, "\t\t<variablelist>\n");
|
|
|
|
/* Iterate over argument struct and write data to docbook 4.5
|
|
* compatible XML */
|
|
if (elements < 2)
|
|
{
|
|
(void)fprintf(stderr, "The argument array 'args' is empty, writing an empty file.\n");
|
|
elements = 1;
|
|
}
|
|
|
|
for (size_t x = 0; x < elements - 1; x++)
|
|
{
|
|
const COMMAND_LINE_ARGUMENT_A* arg = &global_cmd_args[x];
|
|
char* name = tr_esc_str(arg->Name, FALSE);
|
|
char* alias = tr_esc_str(arg->Alias, FALSE);
|
|
char* format = tr_esc_str(arg->Format, TRUE);
|
|
char* text = tr_esc_str(arg->Text, FALSE);
|
|
(void)fprintf(fp, "\t\t\t<varlistentry>\n");
|
|
|
|
do
|
|
{
|
|
(void)fprintf(fp, "\t\t\t\t<term><option>");
|
|
|
|
if (arg->Flags == COMMAND_LINE_VALUE_BOOL)
|
|
(void)fprintf(fp, "%s", arg->Default ? "-" : "+");
|
|
else
|
|
(void)fprintf(fp, "/");
|
|
|
|
(void)fprintf(fp, "%s</option>", name);
|
|
|
|
if (format)
|
|
{
|
|
if (arg->Flags == COMMAND_LINE_VALUE_OPTIONAL)
|
|
(void)fprintf(fp, "[");
|
|
|
|
(void)fprintf(fp, ":%s", format);
|
|
|
|
if (arg->Flags == COMMAND_LINE_VALUE_OPTIONAL)
|
|
(void)fprintf(fp, "]");
|
|
}
|
|
|
|
(void)fprintf(fp, "</term>\n");
|
|
|
|
if (alias == name)
|
|
break;
|
|
|
|
free(name);
|
|
name = alias;
|
|
} while (alias);
|
|
|
|
if (text)
|
|
{
|
|
(void)fprintf(fp, "\t\t\t\t<listitem>\n");
|
|
(void)fprintf(fp, "\t\t\t\t\t<para>");
|
|
|
|
if (text)
|
|
(void)fprintf(fp, "%s", text);
|
|
|
|
if (arg->Flags & COMMAND_LINE_VALUE_BOOL &&
|
|
(!arg->Default || arg->Default == BoolValueTrue))
|
|
(void)fprintf(fp, " (default:%s)", arg->Default ? "on" : "off");
|
|
else if (arg->Default)
|
|
{
|
|
char* value = tr_esc_str(arg->Default, FALSE);
|
|
(void)fprintf(fp, " (default:%s)", value);
|
|
free(value);
|
|
}
|
|
|
|
(void)fprintf(fp, "</para>\n");
|
|
(void)fprintf(fp, "\t\t\t\t</listitem>\n");
|
|
}
|
|
|
|
(void)fprintf(fp, "\t\t\t</varlistentry>\n");
|
|
free(name);
|
|
free(format);
|
|
free(text);
|
|
}
|
|
|
|
(void)fprintf(fp, "\t\t</variablelist>\n");
|
|
(void)fprintf(fp, "\t</refsect1>\n");
|
|
(void)fclose(fp);
|
|
|
|
(void)fprintf(stdout, "successfully generated '%s'\n", fname);
|
|
return 0;
|
|
}
|