]> git.ozlabs.org Git - ccan/blobdiff - tools/doc_extract-core.c
ccanlint: fix parsing bug which believes lines starting with - are a section header.
[ccan] / tools / doc_extract-core.c
index a8d9335b0c7a9a46ce94340801d09da1835cab28..07d31c77c01f15e85cbc3cebda601b050b916c5f 100644 (file)
@@ -26,8 +26,10 @@ static char **grab_doc(char **lines, unsigned int num)
        for (i = 0; lines[i]; i++) {
                if (streq(lines[i], "/**")) {
                        printing = true;
-                       if (num != 0)
-                               talloc_append_string(ret[num-1], "\n");
+                       if (num != 0) {
+                               ret[num-1] = talloc_append_string(ret[num-1],
+                                                                 "\n");
+                       }
                } else if (streq(lines[i], " */")) 
                        printing = false;
                else if (printing) {
@@ -50,13 +52,20 @@ static bool is_blank(const char *line)
 
 static bool is_section(const char *line, bool one_liner)
 {
-       unsigned int len;
-
-       if (!isupper(line[0]))
-               return false;
-       len = strspn(line, IDENT_CHARS);
-       if (line[len] != ':')
-               return false;
+       unsigned int len = 0;
+
+       /* Any number of upper case words separated by spaces, ending in : */
+       for (;;) {
+               if (!isupper(line[len]))
+                       return false;
+               len += strspn(line+len, IDENT_CHARS);
+               if (line[len] == ':')
+                       break;
+
+               if (line[len] != ' ')
+                       return false;
+               len++;
+       }
 
        /* If it can be a one-liner, a space is sufficient.*/
        if (one_liner)
@@ -65,17 +74,28 @@ static bool is_section(const char *line, bool one_liner)
        return line[len] == ':' && is_blank(line+len+1);
 }
 
-/* Summary line is form '<identifier> - ' */
-static bool is_summary_line(const char *line)
+/* Summary line is form '<identifier> - ' (spaces for 'struct foo -') */
+static unsigned int is_summary_line(const char *line)
 {
        unsigned int id_len;
 
-       id_len = strspn(line, IDENT_CHARS);
+       id_len = strspn(line, IDENT_CHARS" ");
        if (id_len == 0)
-               return false;
-       if (!strstarts(line + id_len, " - "))
-               return false;
+               return 0;
+       if (strspn(line, " ") == id_len)
+               return 0;
+       if (!strstarts(line + id_len-1, " - "))
+               return 0;
+       return id_len - 1;
+}
+
+static bool empty_section(struct doc_section *d)
+{
+       unsigned int i;
 
+       for (i = 0; i < d->num_lines; i++)
+               if (!is_blank(d->lines[i]))
+                       return false;
        return true;
 }
 
@@ -83,11 +103,27 @@ static struct doc_section *new_section(struct list_head *list,
                                       const char *function,
                                       const char *type)
 {
-       struct doc_section *d = talloc(list, struct doc_section);
+       struct doc_section *d;
+       char *lowertype;
+       unsigned int i;
+
+       /* If previous section was empty, delete it. */
+       d = list_tail(list, struct doc_section, list);
+       if (d && empty_section(d)) {
+               list_del(&d->list);
+               talloc_free(d);
+       }
+
+       d = talloc(list, struct doc_section);
        d->function = function;
-       d->type = type;
+       lowertype = talloc_size(d, strlen(type) + 1);
+       /* Canonicalize type to lower case. */
+       for (i = 0; i < strlen(type)+1; i++)
+               lowertype[i] = tolower(type[i]);
+       d->type = lowertype;
        d->lines = NULL;
        d->num_lines = 0;
+
        list_add_tail(list, &d->list);
        return d;
 }
@@ -111,11 +147,13 @@ struct list_head *extract_doc_sections(char **rawlines, unsigned int num)
        list_head_init(list);
 
        for (i = 0; lines[i]; i++) {
-               if (is_summary_line(lines[i])) {
-                       function = talloc_strndup(list, lines[i],
-                                                 strcspn(lines[i], " "));
+               unsigned funclen;
+
+               funclen = is_summary_line(lines[i]);
+               if (funclen) {
+                       function = talloc_strndup(list, lines[i], funclen);
                        curr = new_section(list, function, "summary");
-                       add_line(curr, strstr(lines[i], " - ") + 3);
+                       add_line(curr, lines[i] + funclen + 3);
                        curr = new_section(list, function, "description");
                } else if (is_section(lines[i], false)) {
                        char *type = talloc_strndup(curr, lines[i],