X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fdoc_extract-core.c;h=7b9bb84ab3f93e50c06be26a1663e18be8054074;hp=d7490598719f113ed0aa72738efb6c87c9734c91;hb=6a4d45337811b56d947e52f031b9ca0c955fcb6c;hpb=b2826f4cee703abe3d18296a5a7476e9322f37cc diff --git a/tools/doc_extract-core.c b/tools/doc_extract-core.c index d7490598..7b9bb84a 100644 --- a/tools/doc_extract-core.c +++ b/tools/doc_extract-core.c @@ -1,4 +1,7 @@ /* This merely extracts, doesn't do XML or anything. */ +#include +#include +#include #include #include #include @@ -9,20 +12,18 @@ #include #include #include -#include -#include -#include #include "doc_extract.h" #include "tools.h" -static char **grab_doc(char **lines, unsigned int num, unsigned int **linemap) +static char **grab_doc(char **lines, unsigned int **linemap, + const char *file) { char **ret; - unsigned int i; + unsigned int i, num; bool printing = false; - ret = talloc_array(NULL, char *, num+1); - *linemap = talloc_array(ret, unsigned int, num); + ret = talloc_array(NULL, char *, talloc_array_length(lines)); + *linemap = talloc_array(ret, unsigned int, talloc_array_length(lines)); num = 0; for (i = 0; lines[i]; i++) { @@ -39,8 +40,19 @@ static char **grab_doc(char **lines, unsigned int num, unsigned int **linemap) 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 %u", i); + else { + /* Weird, malformed? */ + static bool warned; + if (!warned) { + warnx("%s:%u:" + " Expected ' *' in comment.", + file, i+1); + warned++; + } + ret[num++] = talloc_strdup(ret, lines[i]); + if (strstr(lines[i], "*/")) + printing = false; + } (*linemap)[num-1] = i; } } @@ -71,7 +83,8 @@ static unsigned int is_summary_line(const char *line) { unsigned int id_len; - id_len = strspn(line, IDENT_CHARS" "); + /* We allow /, because it can be in (nested) module names. */ + id_len = strspn(line, IDENT_CHARS" /"); if (id_len == 0) return 0; if (strspn(line, " ") == id_len) @@ -129,10 +142,75 @@ static void add_line(struct doc_section *curr, const char *line) curr->lines[curr->num_lines++] = talloc_strdup(curr->lines, line); } -struct list_head *extract_doc_sections(char **rawlines, unsigned int num) +/* We convert tabs to spaces here. */ +static void add_detabbed_line(struct doc_section *curr, const char *rawline) +{ + unsigned int i, eff_i, len, off = 0; + char *line; + + /* Worst-case alloc: 8 spaces per tab. */ + line = talloc_array(curr, char, strlen(rawline) + + strcount(rawline, "\t") * 7 + 1); + len = 0; + + /* We keep track of the *effective* offset of i. */ + for (i = eff_i = 0; i < strlen(rawline); i++) { + if (rawline[i] == '\t') { + do { + line[len++] = ' '; + eff_i++; + } while (eff_i % 8 != 0); + } else { + line[len++] = rawline[i]; + if (off == 0 && rawline[i] == '*') + off = i + 1; + eff_i++; + } + } + line[len] = '\0'; + + add_line(curr, line + off); + talloc_free(line); +} + +/* Not very efficient: we could track prefix length while doing + * add_detabbed_line */ +static void trim_lines(struct doc_section *curr) +{ + unsigned int i, trim = -1; + int last_non_empty = -1; + + /* Get minimum whitespace prefix. */ + for (i = 0; i < curr->num_lines; i++) { + unsigned int prefix = strspn(curr->lines[i], " "); + /* Ignore blank lines */ + if (curr->lines[i][prefix] == '\0') + continue; + if (prefix < trim) + trim = prefix; + } + + /* Now trim it. */ + for (i = 0; i < curr->num_lines; i++) { + unsigned int prefix = strspn(curr->lines[i], " "); + if (prefix < trim) + curr->lines[i] += prefix; + else + curr->lines[i] += trim; + + /* All blank? Potential to trim. */ + if (curr->lines[i][strspn(curr->lines[i], " \t")] != '\0') + last_non_empty = i; + } + + /* Remove trailing blank lines. */ + curr->num_lines = last_non_empty + 1; +} + +struct list_head *extract_doc_sections(char **rawlines, const char *file) { unsigned int *linemap; - char **lines = grab_doc(rawlines, num, &linemap); + char **lines = grab_doc(rawlines, &linemap, file); const char *function = NULL; struct doc_section *curr = NULL; unsigned int i; @@ -161,9 +239,13 @@ struct list_head *extract_doc_sections(char **rawlines, unsigned int num) } } else { if (curr) - add_line(curr, lines[i]); + add_detabbed_line(curr, rawlines[linemap[i]]); } } + + list_for_each(list, curr, list) + trim_lines(curr); + talloc_free(lines); return list; }