#include #include #include #include #include #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 = ""; else str = "<"; if (!append(&tmp, &ds, str)) exit(-3); break; case '>': if (format) str = ""; 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, "")) 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, "\n"); (void)fprintf(fp, "\tOptions\n"); (void)fprintf(fp, "\t\t\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\n"); do { (void)fprintf(fp, "\t\t\t\t", 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, "\n"); if (alias == name) break; free(name); name = alias; } while (alias); if (text) { (void)fprintf(fp, "\t\t\t\t\n"); (void)fprintf(fp, "\t\t\t\t\t"); 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, "\n"); (void)fprintf(fp, "\t\t\t\t\n"); } (void)fprintf(fp, "\t\t\t\n"); free(name); free(format); free(text); } (void)fprintf(fp, "\t\t\n"); (void)fprintf(fp, "\t\n"); (void)fclose(fp); (void)fprintf(stdout, "successfully generated '%s'\n", fname); return 0; }