Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doxygen2man: print structure descriptions #443

Merged
merged 2 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions doxygen2man/cstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ cstring_t cstring_alloc(void)

char *cstring_to_chars(cstring_t cstring)
{
struct cstring_header *h = (struct cstring_header *)(char *)cstring;
struct cstring_header *h = (struct cstring_header *)cstring;

if (!h) {
return NULL;
Expand All @@ -51,9 +51,22 @@ char *cstring_to_chars(cstring_t cstring)
return strdup(h->the_string);
}

size_t cstring_len(cstring_t cstring)
{
struct cstring_header *h = (struct cstring_header *)cstring;

if (!h) {
return 0;
}

assert(h->checker == CHECKER_WORD);
return h->used;
}


cstring_t cstring_append_chars(cstring_t cstring, const char *newstring)
{
struct cstring_header *h = (struct cstring_header *)(char *)cstring;
struct cstring_header *h = (struct cstring_header *)cstring;
size_t newlen;

if (!h) {
Expand All @@ -74,7 +87,7 @@ cstring_t cstring_append_chars(cstring_t cstring, const char *newstring)
}

cstring = tmp;
h = (struct cstring_header *)(char *)cstring;
h = (struct cstring_header *)cstring;
h->allocated = new_allocsize;
}
strncat(h->the_string, newstring, h->allocated - h->used -1);
Expand All @@ -85,7 +98,7 @@ cstring_t cstring_append_chars(cstring_t cstring, const char *newstring)
cstring_t cstring_append_cstring(cstring_t cstring, cstring_t newstring)
{
/* Just check the newstring - cstring_append_chars() will check the target */
struct cstring_header *h = (struct cstring_header *)(char *)newstring;
struct cstring_header *h = (struct cstring_header *)newstring;

if (!h) {
return NULL;
Expand All @@ -106,7 +119,7 @@ cstring_t cstring_from_chars(const char* chars)

void cstring_free(cstring_t cstring)
{
struct cstring_header *h = (struct cstring_header *)(char *)cstring;
struct cstring_header *h = (struct cstring_header *)cstring;

if (!h) {
return;
Expand Down
1 change: 1 addition & 0 deletions doxygen2man/cstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ char *cstring_to_chars(cstring_t cstring);
cstring_t cstring_append_chars(cstring_t cstring, const char *newstring);
cstring_t cstring_append_cstring(cstring_t cstring, cstring_t newstring);
void cstring_free(cstring_t cstring);
size_t cstring_len(cstring_t cstring);

#endif
113 changes: 92 additions & 21 deletions doxygen2man/doxygen2man.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
*
* Author: Christine Caulfield <ccaulfie@redhat.com>
*
Expand Down Expand Up @@ -43,6 +43,9 @@
*/
#define LINE_LENGTH 80

/* Similar - but for structure member comments */
#define STRUCT_COMMENT_LENGTH 50

static int print_ascii = 1;
static int print_man = 0;
static int print_params = 0;
Expand Down Expand Up @@ -87,9 +90,10 @@ struct struct_info {
struct qb_list_head list;
};

static cstring_t get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext);
static cstring_t get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext, int add_nl);
static void traverse_node(xmlNode *parentnode, const char *leafname, void (do_members(xmlNode*, void*)), void *arg);
static cstring_t get_text(xmlNode *cur_node, char **returntext, char **notetext);
static void man_print_long_string(FILE *manfile, char *text);

static void free_paraminfo(struct param_info *pi)
{
Expand Down Expand Up @@ -189,7 +193,8 @@ static void get_param_info(xmlNode *cur_node, struct qb_list_head *list)
sub_tag->children->next->children) {
paramname = (char*)sub_tag->children->next->children->content;
}
if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameterdescription") == 0 &&
if (sub_tag->type == XML_ELEMENT_NODE &&
strcmp((char *)sub_tag->name, "parameterdescription") == 0 &&
paramname && sub_tag->children->next->children) {
paramdesc = (char*)sub_tag->children->next->children->content;

Expand Down Expand Up @@ -353,7 +358,7 @@ static cstring_t get_text(xmlNode *cur_node, char **returntext, char **notetext)
buffer = cstring_append_chars(buffer, "\n");
cstring_free(tmp);

tmp = get_texttree(&type,this_tag, NULL, NULL);
tmp = get_texttree(&type,this_tag, NULL, NULL, 1);
buffer = cstring_append_cstring(buffer, tmp);
buffer = cstring_append_chars(buffer, "\n");
}
Expand Down Expand Up @@ -392,12 +397,12 @@ static void read_structdesc(xmlNode *cur_node, void *arg)

for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
if (strcmp((char*)this_tag->name, "detaileddescription") == 0) {
cstring_t desc = get_texttree(NULL, this_tag, NULL, NULL);
cstring_t desc = get_texttree(NULL, this_tag, NULL, NULL, 1);
si->description = cstring_to_chars(desc);
cstring_free(desc);
}
if (strcmp((char*)this_tag->name, "briefdescription") == 0) {
cstring_t brief = get_texttree(NULL, this_tag, NULL, NULL);
cstring_t brief = get_texttree(NULL, this_tag, NULL, NULL, 1);
si->brief_description = cstring_to_chars(brief);
}
}
Expand All @@ -422,10 +427,11 @@ static void read_struct(xmlNode *cur_node, void *arg)
{
xmlNode *this_tag;
struct struct_info *si=arg;
struct param_info *pi;
struct param_info *pi = NULL;
char fullname[1024];
char *type = NULL;
char *name = NULL;
char *desc = NULL;
const char *args="";

for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
Expand All @@ -444,6 +450,13 @@ static void read_struct(xmlNode *cur_node, void *arg)
if (this_tag->children && strcmp((char*)this_tag->name, "argsstring") == 0) {
args = (char*)this_tag->children->content;
}
if (this_tag->children && strcmp((char*)this_tag->name, "detaileddescription") == 0) {
cstring_t *desc_cs = get_texttree(NULL, this_tag, NULL, NULL, 0);
if (cstring_len(desc_cs) > 1) {
desc = cstring_to_chars(desc_cs);
}
cstring_free(desc_cs);
}
}

if (name) {
Expand All @@ -452,10 +465,14 @@ static void read_struct(xmlNode *cur_node, void *arg)
snprintf(fullname, sizeof(fullname), "%s%s", name, args);
pi->paramtype = type?strdup(type):strdup("");
pi->paramname = strdup(fullname);
pi->paramdesc = NULL;
pi->paramdesc = desc;
qb_list_add_tail(&pi->list, &si->params_list);
}
}
/* Tidy */
if (!name || !pi) {
free(desc);
}
}

static int read_structure_from_xml(const char *refid, const char *name)
Expand Down Expand Up @@ -517,7 +534,31 @@ static char *allcaps(const char *name)
return buffer;
}

static void print_param(FILE *manfile, struct param_info *pi, int field_width, int bold, const char *delimiter)
/*
* Print a structure comment that would be too long
* to fit after the structure member, in a style ...
* well, in a style like this!
*/
static void print_long_structure_comment(FILE *manfile, char *comment)
{
char *ptr = strtok(comment, " ");
int column = 7;

fprintf(manfile, "\\fP /*");
fprintf(manfile, "\n *");
while (ptr) {
column += strlen(ptr)+1;
if (column > 80) {
fprintf(manfile, "\n *");
column = 7;
}
fprintf(manfile, " %s", ptr);
ptr = strtok(NULL, " ");
}
fprintf(manfile, "\n */\n");
}

static void print_param(FILE *manfile, struct param_info *pi, int type_field_width, int name_field_width, int bold, const char *delimiter)
{
const char *asterisks = " ";
char *type = pi->paramtype;
Expand All @@ -542,10 +583,32 @@ static void print_param(FILE *manfile, struct param_info *pi, int field_width, i
}
}

fprintf(manfile, " %s%-*s%s%s\\fI%s\\fP%s\n",
bold?"\\fB":"", field_width, type,
asterisks, bold?"\\fP":"",
pi->paramname?pi->paramname:"", delimiter);
/* Print structure description if available */
if (pi->paramdesc) {
/* Too long to go on the same line? */
if (strlen(pi->paramdesc) > STRUCT_COMMENT_LENGTH) {
print_long_structure_comment(manfile, pi->paramdesc);
fprintf(manfile, " %s%-*s%s%s\\fI%s\\fP%s\n",
bold?"\\fB":"", type_field_width, type,
asterisks, bold?"\\fP":"",
pi->paramname?pi->paramname:"", delimiter);
} else {
/* Pad out so they all line up */
int pad_length = name_field_width -
(pi->paramname?strlen(pi->paramname):0) + 1;
fprintf(manfile, " %s%-*s%s%s\\fI%s\\fP%s\\fR%*s/* %s*/\n",
bold?"\\fB":"", type_field_width, type,
asterisks, bold?"\\fP":"",
pi->paramname?pi->paramname:"", delimiter,
pad_length, " ",
pi->paramdesc);
}
} else {
fprintf(manfile, " %s%-*s%s%s\\fI%s\\fP%s\n",
bold?"\\fB":"", type_field_width, type,
asterisks, bold?"\\fP":"",
pi->paramname?pi->paramname:"", delimiter);
}

if (type != pi->paramtype) {
free(type);
Expand All @@ -557,9 +620,9 @@ static void print_structure(FILE *manfile, struct struct_info *si)
struct param_info *pi;
struct qb_list_head *iter;
unsigned int max_param_length=0;
unsigned int max_param_name_length=0;

fprintf(manfile, ".nf\n");
fprintf(manfile, "\\fB\n");

if (si->brief_description) {
fprintf(manfile, "%s\n", si->brief_description);
Expand All @@ -573,27 +636,33 @@ static void print_structure(FILE *manfile, struct struct_info *si)
if (strlen(pi->paramtype) > max_param_length) {
max_param_length = strlen(pi->paramtype);
}
if (strlen(pi->paramname) > max_param_name_length) {
max_param_name_length = strlen(pi->paramname);
}
}

fprintf(manfile, "\\fB\n");
if (si->kind == STRUCTINFO_STRUCT) {
fprintf(manfile, "struct %s {\n", si->structname);
} else if (si->kind == STRUCTINFO_ENUM) {
fprintf(manfile, "enum %s {\n", si->structname);
} else {
fprintf(manfile, "%s {\n", si->structname);
}
fprintf(manfile, "\\fR\n");

qb_list_for_each(iter, &si->params_list) {
fprintf(manfile, "\\fB\n");
pi = qb_list_entry(iter, struct param_info, list);
print_param(manfile, pi, max_param_length, 0,";");
print_param(manfile, pi, max_param_length, max_param_name_length, 1, ";");
}
fprintf(manfile, "};\n");

fprintf(manfile, "\\fP\n");
fprintf(manfile, ".fi\n");
}

cstring_t get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext)
cstring_t get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext, int add_nl)
{
xmlNode *this_tag;
cstring_t tmp;
Expand All @@ -604,7 +673,9 @@ cstring_t get_texttree(int *type, xmlNode *cur_node, char **returntext, char **n
if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "para") == 0) {
tmp = get_text(this_tag, returntext, notetext);
buffer = cstring_append_cstring(buffer, tmp);
buffer = cstring_append_chars(buffer, "\n");
if (add_nl) {
buffer = cstring_append_chars(buffer, "\n");
}

cstring_free(tmp);
}
Expand Down Expand Up @@ -779,8 +850,8 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
qb_list_for_each(iter, param_map) {
pi = qb_list_entry(iter, struct param_info, list);

if (pi->paramtype[0] != '\0') { //CC
print_param(manfile, pi, max_param_type_len, 1, ++param_num < param_count?",":"");
if (pi->paramtype[0] != '\0') {
print_param(manfile, pi, max_param_type_len, 0, 1, ++param_num < param_count?",":"");
}
}

Expand Down Expand Up @@ -1007,7 +1078,7 @@ static void traverse_members(xmlNode *cur_node, void *arg)
name = strdup((char *)this_tag->children->content);

if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "briefdescription") == 0) {
cstring_t tmp = get_texttree(&type, this_tag, &returntext, &notetext);
cstring_t tmp = get_texttree(&type, this_tag, &returntext, &notetext, 1);
if (!brief) {
brief = cstring_to_chars(tmp);
} else {
Expand All @@ -1016,7 +1087,7 @@ static void traverse_members(xmlNode *cur_node, void *arg)
cstring_free(tmp);
}
if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "detaileddescription") == 0) {
cstring_t tmp = get_texttree(&type, this_tag, &returntext, &notetext);
cstring_t tmp = get_texttree(&type, this_tag, &returntext, &notetext, 1);
if (!detailed) {
detailed = cstring_to_chars(tmp);
} else {
Expand Down