#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) {
ret[num++] = talloc_strdup(ret, lines[i]+2);
else
errx(1, "Malformed line %u", i);
+ (*linemap)[num-1] = i;
}
}
ret[num] = NULL;
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)
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;
d->type = lowertype;
d->lines = NULL;
d->num_lines = 0;
+ d->srcline = srcline;
list_add_tail(list, &d->list);
return d;
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;
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);