1 /* This merely extracts, doesn't do XML or anything. */
12 #include <ccan/talloc/talloc.h>
13 #include <ccan/str/str.h>
14 #include "doc_extract.h"
17 static char **grab_doc(char **lines, unsigned int num)
21 bool printing = false;
23 ret = talloc_array(NULL, char *, num+1);
26 for (i = 0; lines[i]; i++) {
27 if (streq(lines[i], "/**")) {
30 ret[num-1] = talloc_append_string(ret[num-1],
33 } else if (streq(lines[i], " */"))
36 if (strstarts(lines[i], " * "))
37 ret[num++] = talloc_strdup(ret, lines[i]+3);
38 else if (strstarts(lines[i], " *"))
39 ret[num++] = talloc_strdup(ret, lines[i]+2);
41 errx(1, "Malformed line %u", i);
48 static bool is_blank(const char *line)
50 return line && line[strspn(line, " \t\n")] == '\0';
53 static bool is_section(const char *line, bool one_liner)
57 /* Any number of upper case words separated by spaces, ending in : */
59 if (!isupper(line[len]))
61 len += strspn(line+len, IDENT_CHARS);
70 /* If it can be a one-liner, a space is sufficient.*/
72 return (line[len+1] == ' ' || line[len+1] == '\t');
74 return line[len] == ':' && is_blank(line+len+1);
77 /* Summary line is form '<identifier> - ' (spaces for 'struct foo -') */
78 static unsigned int is_summary_line(const char *line)
82 id_len = strspn(line, IDENT_CHARS" ");
85 if (strspn(line, " ") == id_len)
87 if (!strstarts(line + id_len-1, " - "))
92 static bool empty_section(struct doc_section *d)
96 for (i = 0; i < d->num_lines; i++)
97 if (!is_blank(d->lines[i]))
102 static struct doc_section *new_section(struct list_head *list,
103 const char *function,
106 struct doc_section *d;
110 /* If previous section was empty, delete it. */
111 d = list_tail(list, struct doc_section, list);
112 if (d && empty_section(d)) {
117 d = talloc(list, struct doc_section);
118 d->function = function;
119 lowertype = talloc_size(d, strlen(type) + 1);
120 /* Canonicalize type to lower case. */
121 for (i = 0; i < strlen(type)+1; i++)
122 lowertype[i] = tolower(type[i]);
127 list_add_tail(list, &d->list);
131 static void add_line(struct doc_section *curr, const char *line)
133 curr->lines = talloc_realloc(curr, curr->lines, char *,
135 curr->lines[curr->num_lines++] = talloc_strdup(curr->lines, line);
138 struct list_head *extract_doc_sections(char **rawlines, unsigned int num)
140 char **lines = grab_doc(rawlines, num);
141 const char *function = NULL;
142 struct doc_section *curr = NULL;
144 struct list_head *list;
146 list = talloc(NULL, struct list_head);
147 list_head_init(list);
149 for (i = 0; lines[i]; i++) {
152 funclen = is_summary_line(lines[i]);
154 function = talloc_strndup(list, lines[i], funclen);
155 curr = new_section(list, function, "summary");
156 add_line(curr, lines[i] + funclen + 3);
157 curr = new_section(list, function, "description");
158 } else if (is_section(lines[i], false)) {
159 char *type = talloc_strndup(curr, lines[i],
160 strcspn(lines[i], ":"));
161 curr = new_section(list, function, type);
162 } else if (is_section(lines[i], true)) {
163 unsigned int sectlen = strcspn(lines[i], ":");
164 char *type = talloc_strndup(curr, lines[i], sectlen);
165 curr = new_section(list, function, type);
166 add_line(curr, lines[i] + sectlen + 1
167 + strspn(lines[i] + sectlen + 1, " \t"));
171 add_line(curr, lines[i]);