1 /* This merely extracts, doesn't do XML or anything. */
11 #include "talloc/talloc.h"
12 #include "string/string.h"
14 static char **grab_doc(const char *fname)
19 bool printing = false, printed = false;
21 file = grab_file(NULL, fname, NULL);
23 err(1, "Reading file %s", fname);
24 lines = strsplit(file, file, "\n", &num);
25 ret = talloc_array(NULL, char *, num+1);
28 for (i = 0; lines[i]; i++) {
29 if (streq(lines[i], "/**")) {
32 talloc_append_string(ret[num], "\n");
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 %s:%u", fname, i);
49 static bool is_blank(const char *line)
51 return line && line[strspn(line, " \t\n")] == '\0';
54 static bool is_section(const char *line, bool maybe_one_liner)
58 len = strcspn(line, " \t\n:");
65 /* If it can be a one-liner, a space is sufficient.*/
66 if (maybe_one_liner && (line[len+1] == ' ' || line[len+1] == '\t'))
69 return line[len] == ':' && is_blank(line+len+1);
73 static bool end_section(const char *line)
75 return !line || is_section(line, true);
78 static unsigned int find_section(char **lines, const char *name,
83 for (i = 0; lines[i]; i++) {
84 if (!is_section(lines[i], maybe_one_liner))
86 if (strncasecmp(lines[i], name, strlen(name)) != 0)
88 if (lines[i][strlen(name)] == ':')
94 int main(int argc, char *argv[])
100 errx(1, "Usage: doc_extract TYPE <file>...\n"
101 "Where TYPE is author|licence|maintainer|summary|description|example|all");
104 for (i = 2; i < argc; i++) {
106 char **lines = grab_doc(argv[i]);
109 errx(1, "No documentation in file");
111 /* Simple one-line fields. */
112 if (streq(type, "author")
113 || streq(type, "maintainer")
114 || streq(type, "licence")) {
115 line = find_section(lines, type, true);
117 const char *p = strchr(lines[line], ':') + 1;
118 p += strspn(p, " \t\n");
120 /* Must be on next line. */
121 if (end_section(lines[line+1]))
122 errx(1, "Malformed %s", type);
127 } else if (streq(type, "summary")) {
128 /* Summary comes after - on first line. */
131 dash = strchr(lines[0], '-');
133 errx(1, "Malformed first line: no -");
134 dash += strspn(dash, "- ");
136 } else if (streq(type, "description")) {
138 while (is_blank(lines[line]))
141 while (!end_section(lines[line]))
143 } else if (streq(type, "example")) {
144 line = find_section(lines, type, false);
149 while (is_blank(lines[line]))
152 /* Examples can be indented. Take cue
153 * from first non-blank line. */
155 strip = strspn(lines[line], " \t");
157 while (!end_section(lines[line])) {
158 if (strspn(lines[line], " \t") >= strip)
159 puts(lines[line] + strip);
165 } else if (streq(type, "all")) {
166 for (line = 0; lines[line]; line++)
169 errx(1, "Unknown type '%s'", type);