From 40b0fa608877472b864bbc720dbd25ca4457509e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 19 Aug 2008 17:49:24 +1000 Subject: [PATCH 1/1] Extraction of parts of documentation. --- tools/doc_extract.c | 170 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 141 insertions(+), 29 deletions(-) diff --git a/tools/doc_extract.c b/tools/doc_extract.c index b70325ea..a40e3b1a 100644 --- a/tools/doc_extract.c +++ b/tools/doc_extract.c @@ -11,39 +11,151 @@ #include "talloc/talloc.h" #include "string/string.h" +static char **grab_doc(const char *fname) +{ + char *file; + char **lines, **ret; + unsigned int i, num; + bool printing = false, printed = false; + + file = grab_file(NULL, fname, NULL); + if (!file) + err(1, "Reading file %s", fname); + lines = strsplit(file, file, "\n", &num); + ret = talloc_array(NULL, char *, num+1); + + num = 0; + for (i = 0; lines[i]; i++) { + if (streq(lines[i], "/**")) { + printing = true; + if (printed++) + talloc_append_string(ret[num], "\n"); + } else if (streq(lines[i], " */")) + printing = false; + else if (printing) { + if (strstarts(lines[i], " * ")) + ret[num++] = talloc_strdup(ret, lines[i]+3); + else if (strstarts(lines[i], " *")) + ret[num++] = talloc_strdup(ret, lines[i]+2); + else + errx(1, "Malformed line %s:%u", fname, i); + } + } + ret[num] = NULL; + talloc_free(file); + return ret; +} + +static bool is_blank(const char *line) +{ + return line && line[strspn(line, " \t\n")] == '\0'; +} + +static bool is_section(const char *line) +{ + unsigned int len; + + len = strcspn(line, " \t\n:"); + if (len == 0) + return false; + + return line[len] == ':' && is_blank(line+len+1); +} + + +static bool end_section(const char *line) +{ + return !line || is_section(line); +} + +static unsigned int find_section(char **lines, const char *name) +{ + unsigned int i; + + for (i = 0; lines[i]; i++) { + if (!is_section(lines[i])) + continue; + if (strncasecmp(lines[i], name, strlen(name)) != 0) + continue; + if (lines[i][strlen(name)] == ':') + break; + } + return i; +} int main(int argc, char *argv[]) { - unsigned int i, j; - - for (i = 1; i < argc; i++) { - char *file; - char **lines; - bool printing = false, printed = false; - - file = grab_file(NULL, argv[i]); - if (!file) - err(1, "Reading file %s", argv[i]); - lines = strsplit(file, file, "\n", NULL); - - for (j = 0; lines[j]; j++) { - if (streq(lines[j], "/**")) { - printing = true; - if (printed++) - puts("\n"); - } else if (streq(lines[j], " */")) - printing = false; - else if (printing) { - if (strstarts(lines[j], " * ")) - puts(lines[j] + 3); - else if (strstarts(lines[j], " *")) - puts(lines[j] + 2); - else - errx(1, "Malformed line %s:%u", - argv[i], j); + unsigned int i; + const char *type; + + if (argc < 3) + errx(1, "Usage: doc_extract TYPE ...\n" + "Where TYPE is author|licence|maintainer|summary|description|example|all"); + + type = argv[1]; + for (i = 2; i < argc; i++) { + unsigned int line; + char **lines = grab_doc(argv[i]); + + if (!lines[0]) + errx(1, "No documentation in file"); + + /* Simple one-line fields. */ + if (streq(type, "author") + || streq(type, "maintainer") + || streq(type, "licence")) { + line = find_section(lines, type); + if (lines[line]) { + if (!lines[line+1]) + errx(1, "Malformed %s, end of file", + type); + puts(lines[line+1]); } - } - talloc_free(file); + } else if (streq(type, "summary")) { + /* Summary comes after - on first line. */ + char *dash; + + dash = strchr(lines[0], '-'); + if (!dash) + errx(1, "Malformed first line: no -"); + dash += strspn(dash, "- "); + puts(dash); + } else if (streq(type, "description")) { + line = 1; + while (is_blank(lines[line])) + line++; + + while (!end_section(lines[line])) + puts(lines[line++]); + } else if (streq(type, "example")) { + line = find_section(lines, type); + if (lines[line]) { + unsigned int strip; + line++; + + while (is_blank(lines[line])) + line++; + + /* Examples can be indented. Take cue + * from first non-blank line. */ + if (lines[line]) + strip = strspn(lines[line], " \t"); + + while (!end_section(lines[line])) { + if (strspn(lines[line], " \t") >= strip) + puts(lines[line] + strip); + else + puts(lines[line]); + line++; + } + } + } else if (streq(type, "all")) { + for (line = 0; lines[line]; line++) + puts(lines[line]); + } else + errx(1, "Unknown type '%s'", type); + + talloc_free(lines); } return 0; } -- 2.39.2