ccanlint: add ilog dependency.
[ccan] / tools / doc_extract.c
1 /* This merely extracts, doesn't do XML or anything. */
2 #include <err.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <ccan/str/str.h>
6 #include <ccan/str_talloc/str_talloc.h>
7 #include <ccan/talloc/talloc.h>
8 #include <ccan/grab_file/grab_file.h>
9 #include "doc_extract.h"
10
11 /* We regard non-alphanumerics as equiv. */
12 static bool typematch(const char *a, const char *b)
13 {
14         size_t i;
15
16         for (i = 0; a[i]; i++) {
17                 if (cisalnum(a[i])) {
18                         if (a[i] != b[i])
19                                 return false;
20                 } else {
21                         if (cisalnum(b[i]))
22                                 return false;
23                 }
24         }
25         return b[i] == '\0';
26 }
27
28 int main(int argc, char *argv[])
29 {
30         unsigned int i;
31         const char *type;
32         const char *function = NULL;
33
34         if (argc < 3)
35                 errx(1, "Usage: doc_extract [--function=<funcname>] TYPE <file>...\n"
36                      "Where TYPE is functions|author|license|maintainer|summary|description|example|see_also|all");
37
38         if (strstarts(argv[1], "--function=")) {
39                 function = argv[1] + strlen("--function=");
40                 argv++;
41                 argc--;
42         }
43
44         type = argv[1];
45         for (i = 2; i < argc; i++) {
46                 char *file, **lines;
47                 struct list_head *list;
48                 struct doc_section *d;
49
50                 file = grab_file(NULL, argv[i], NULL);
51                 if (!file)
52                         err(1, "Reading file %s", argv[i]);
53                 lines = strsplit(file, file, "\n");
54
55                 list = extract_doc_sections(lines);
56                 if (list_empty(list))
57                         errx(1, "No documentation in file %s", argv[i]);
58                 talloc_free(file);
59
60                 if (streq(type, "functions")) {
61                         const char *last = NULL;
62                         list_for_each(list, d, list) {
63                                 if (d->function) {
64                                         if (!last || !streq(d->function, last))
65                                                 printf("%s\n", d->function);
66                                         last = d->function;
67                                 }
68                         }
69                 } else {
70                         unsigned int j;
71                         list_for_each(list, d, list) {
72                                 if (function) {
73                                         if (!d->function)
74                                                 continue;
75                                         if (!streq(d->function, function))
76                                                 continue;
77                                 }
78                                 if (streq(type, "all"))
79                                         printf("%s:\n", d->type);
80                                 else if (!typematch(d->type, type))
81                                         continue;
82
83                                 for (j = 0; j < d->num_lines; j++)
84                                         printf("%s\n", d->lines[j]);
85                         }
86                 }
87                 talloc_free(list);
88         }
89         return 0;
90 }