]> git.ozlabs.org Git - ccan/blobdiff - tools/doc_extract-core.c
strsplit: remove nump argument
[ccan] / tools / doc_extract-core.c
index 829d34778f4dee7afce10c36d4f8c541d4b60a04..781ce2bdbcc8d5a08baac318f5e419d14fe46781 100644 (file)
 #include <ctype.h>
 #include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
+#include <ccan/str_talloc/str_talloc.h>
 #include "doc_extract.h"
 #include "tools.h"
 
-static char **grab_doc(char **lines, unsigned int num)
+static char **grab_doc(char **lines, unsigned int **linemap)
 {
        char **ret;
-       unsigned int i;
+       unsigned int i, num;
        bool printing = false;
 
-       ret = talloc_array(NULL, char *, num+1);
+       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++) {
                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) {
@@ -37,6 +41,7 @@ static char **grab_doc(char **lines, unsigned int num)
                                ret[num++] = talloc_strdup(ret, lines[i]+2);
                        else
                                errx(1, "Malformed line %u", i);
+                       (*linemap)[num-1] = i;
                }
        }
        ret[num] = NULL;
@@ -48,35 +53,32 @@ static bool is_blank(const char *line)
        return line && line[strspn(line, " \t\n")] == '\0';
 }
 
-static bool is_section(const char *line, bool one_liner)
+static char *is_section(const void *ctx, const char *line, char **value)
 {
-       unsigned int len;
-
-       if (!isupper(line[0]))
-               return false;
-       len = strspn(line, IDENT_CHARS" ");
-       if (line[len] != ':')
-               return false;
+       char *secname;
 
-       /* If it can be a one-liner, a space is sufficient.*/
-       if (one_liner)
-               return (line[len+1] == ' ' || line[len+1] == '\t');
+       /* Any number of upper case words separated by spaces, ending in : */
+       if (!strreg(ctx, line,
+                   "^([A-Z][a-zA-Z0-9_]*( [A-Z][a-zA-Z0-9_]*)*):[ \t\n]*(.*)",
+                   &secname, NULL, value))
+               return NULL;
 
-       return line[len] == ':' && is_blank(line+len+1);
+       return secname;
 }
 
-/* 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 true;
+               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)
@@ -91,7 +93,8 @@ static bool empty_section(struct doc_section *d)
 
 static struct doc_section *new_section(struct list_head *list,
                                       const char *function,
-                                      const char *type)
+                                      const char *type,
+                                      unsigned int srcline)
 {
        struct doc_section *d;
        char *lowertype;
@@ -113,6 +116,7 @@ static struct doc_section *new_section(struct list_head *list,
        d->type = lowertype;
        d->lines = NULL;
        d->num_lines = 0;
+       d->srcline = srcline;
 
        list_add_tail(list, &d->list);
        return d;
@@ -125,9 +129,10 @@ 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)
+struct list_head *extract_doc_sections(char **rawlines)
 {
-       char **lines = grab_doc(rawlines, num);
+       unsigned int *linemap;
+       char **lines = grab_doc(rawlines, &linemap);
        const char *function = NULL;
        struct doc_section *curr = NULL;
        unsigned int i;
@@ -137,26 +142,26 @@ 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], " "));
-                       curr = new_section(list, function, "summary");
-                       add_line(curr, strstr(lines[i], " - ") + 3);
-                       curr = new_section(list, function, "description");
-               } else if (is_section(lines[i], false)) {
-                       char *type = talloc_strndup(curr, lines[i],
-                                                   strcspn(lines[i], ":"));
-                       curr = new_section(list, function, type);
-               } else if (is_section(lines[i], true)) {
-                       unsigned int sectlen = strcspn(lines[i], ":");
-                       char *type = talloc_strndup(curr, lines[i], sectlen);
-                       curr = new_section(list, function, type);
-                       add_line(curr, lines[i] + sectlen + 1
-                                + strspn(lines[i] + sectlen + 1, " \t"));
+               unsigned funclen;
+               char *type, *extra;
+
+               funclen = is_summary_line(lines[i]);
+               if (funclen) {
+                       function = talloc_strndup(list, lines[i], funclen);
+                       curr = new_section(list, function, "summary",
+                                          linemap[i]);
+                       add_line(curr, lines[i] + funclen + 3);
+                       curr = new_section(list, function, "description",
+                                          linemap[i]);
+               } else if ((type = is_section(list, lines[i], &extra)) != NULL){
+                       curr = new_section(list, function, type, linemap[i]);
+                       if (!streq(extra, "")) {
+                               add_line(curr, extra);
+                               curr = NULL;
+                       }
                } else {
-                       if (!curr)
-                               continue;
-                       add_line(curr, lines[i]);
+                       if (curr)
+                               add_line(curr, lines[i]);
                }
        }
        talloc_free(lines);