History

docbook: warn on unused doc entries

When you don't use !E or !I but only !F, then it's very easy to miss including some functions, structs etc. in documentation. To help finding which ones were missed, allow printing out the unused ones as warnings. For example, using this on mac80211 yields a lot of warnings like this: Warning: didn't use docs for DOC: mac80211 workqueue Warning: didn't use docs for ieee80211_max_queues Warning: didn't use docs for ieee80211_bss_change Warning: didn't use docs for ieee80211_bss_conf when generating the documentation for it.

Johannes Berg committed 16 years ago

Commit eda603f1 parent 1f3a6683 files · +183 −3Browse files

Showing the changes to scripts/basic (1 of 3 files). Show all

Unified · Split

scripts/basic/docproc.c+128−1
@@ -34,12 +34,14 @@ · 33 unmodified lines
3434 *
3535 */
3636
37+#define _GNU_SOURCE
3738 #include <stdio.h>
3839 #include <stdlib.h>
3940 #include <string.h>
4041 #include <ctype.h>
4142 #include <unistd.h>
4243 #include <limits.h>
44+#include <errno.h>
4345 #include <sys/types.h>
4446 #include <sys/wait.h>
4547
@@ -54,6 +56,7 @@ typedef void FILEONLY(char * file); · 8 unmodified lines
5456 FILEONLY *internalfunctions;
5557 FILEONLY *externalfunctions;
5658 FILEONLY *symbolsonly;
59+FILEONLY *findall;
5760
5861 typedef void FILELINE(char * file, char * line);
5962 FILELINE * singlefunctions;
@@ -65,12 +68,30 @@ FILELINE * docsection; · 5 unmodified lines
6568 #define KERNELDOCPATH "scripts/"
6669 #define KERNELDOC "kernel-doc"
6770 #define DOCBOOK "-docbook"
71+#define LIST "-list"
6872 #define FUNCTION "-function"
6973 #define NOFUNCTION "-nofunction"
7074 #define NODOCSECTIONS "-no-doc-sections"
7175
7276 static char *srctree, *kernsrctree;
7377
78+static char **all_list = NULL;
79+static int all_list_len = 0;
80+
81+static void consume_symbol(const char *sym)
82+{
83+ int i;
84+
85+ for (i = 0; i < all_list_len; i++) {
86+ if (!all_list[i])
87+ continue;
88+ if (strcmp(sym, all_list[i]))
89+ continue;
90+ all_list[i] = NULL;
91+ break;
92+ }
93+}
94+
7495 static void usage (void)
7596 {
7697 fprintf(stderr, "Usage: docproc {doc|depend} file\n");
@@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type) · 171 unmodified lines
248269 struct symfile * sym = &symfilelist[i];
249270 for (j=0; j < sym->symbolcnt; j++) {
250271 vec[idx++] = type;
272+ consume_symbol(sym->symbollist[j].name);
251273 vec[idx++] = sym->symbollist[j].name;
252274 }
253275 }
@@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line) · 33 unmodified lines
287309 vec[idx++] = &line[i];
288310 }
289311 }
312+ for (i = 0; i < idx; i++) {
313+ if (strcmp(vec[i], FUNCTION))
314+ continue;
315+ consume_symbol(vec[i + 1]);
316+ }
290317 vec[idx++] = filename;
291318 vec[idx] = NULL;
292319 exec_kernel_doc(vec);
@@ -306,6 +333,10 @@ static void docsect(char *filename, char *line) · 13 unmodified lines
306333 if (*s == '\n')
307334 *s = '\0';
308335
336+ asprintf(&s, "DOC: %s", line);
337+ consume_symbol(s);
338+ free(s);
339+
309340 vec[0] = KERNELDOC;
310341 vec[1] = DOCBOOK;
311342 vec[2] = FUNCTION;
@@ -315,6 +346,84 @@ static void docsect(char *filename, char *line) · 3 unmodified lines
315346 exec_kernel_doc(vec);
316347 }
317348
349+static void find_all_symbols(char *filename)
350+{
351+ char *vec[4]; /* kerneldoc -list file NULL */
352+ pid_t pid;
353+ int ret, i, count, start;
354+ char real_filename[PATH_MAX + 1];
355+ int pipefd[2];
356+ char *data, *str;
357+ size_t data_len = 0;
358+
359+ vec[0] = KERNELDOC;
360+ vec[1] = LIST;
361+ vec[2] = filename;
362+ vec[3] = NULL;
363+
364+ if (pipe(pipefd)) {
365+ perror("pipe");
366+ exit(1);
367+ }
368+
369+ switch (pid=fork()) {
370+ case -1:
371+ perror("fork");
372+ exit(1);
373+ case 0:
374+ close(pipefd[0]);
375+ dup2(pipefd[1], 1);
376+ memset(real_filename, 0, sizeof(real_filename));
377+ strncat(real_filename, kernsrctree, PATH_MAX);
378+ strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
379+ PATH_MAX - strlen(real_filename));
380+ execvp(real_filename, vec);
381+ fprintf(stderr, "exec ");
382+ perror(real_filename);
383+ exit(1);
384+ default:
385+ close(pipefd[1]);
386+ data = malloc(4096);
387+ do {
388+ while ((ret = read(pipefd[0],
389+ data + data_len,
390+ 4096)) > 0) {
391+ data_len += ret;
392+ data = realloc(data, data_len + 4096);
393+ }
394+ } while (ret == -EAGAIN);
395+ if (ret != 0) {
396+ perror("read");
397+ exit(1);
398+ }
399+ waitpid(pid, &ret ,0);
400+ }
401+ if (WIFEXITED(ret))
402+ exitstatus |= WEXITSTATUS(ret);
403+ else
404+ exitstatus = 0xff;
405+
406+ count = 0;
407+ /* poor man's strtok, but with counting */
408+ for (i = 0; i < data_len; i++) {
409+ if (data[i] == '\n') {
410+ count++;
411+ data[i] = '\0';
412+ }
413+ }
414+ start = all_list_len;
415+ all_list_len += count;
416+ all_list = realloc(all_list, sizeof(char *) * all_list_len);
417+ str = data;
418+ for (i = 0; i < data_len && start != all_list_len; i++) {
419+ if (data[i] == '\0') {
420+ all_list[start] = str;
421+ str = data + i + 1;
422+ start++;
423+ }
424+ }
425+}
426+
318427 /*
319428 * Parse file, calling action specific functions for:
320429 * 1) Lines containing !E
@@ -322,7 +431,8 @@ static void docsect(char *filename, char *line) · 1 unmodified line
322431 * 3) Lines containing !D
323432 * 4) Lines containing !F
324433 * 5) Lines containing !P
325− * 6) Default lines - lines not matching the above
434+ * 6) Lines containing !C
435+ * 7) Default lines - lines not matching the above
326436 */
327437 static void parse_file(FILE *infile)
328438 {
@@ -365,6 +475,12 @@ static void parse_file(FILE *infile) · 36 unmodified lines
365475 s++;
366476 docsection(line + 2, s);
367477 break;
478+ case 'C':
479+ while (*s && !isspace(*s)) s++;
480+ *s = '\0';
481+ if (findall)
482+ findall(line+2);
483+ break;
368484 default:
369485 defaultline(line);
370486 }
@@ -380,6 +496,7 @@ static void parse_file(FILE *infile) · 9 unmodified lines
380496 int main(int argc, char *argv[])
381497 {
382498 FILE * infile;
499+ int i;
383500
384501 srctree = getenv("SRCTREE");
385502 if (!srctree)
@@ -415,6 +532,7 @@ int main(int argc, char *argv[]) · 29 unmodified lines
415532 symbolsonly = find_export_symbols;
416533 singlefunctions = noaction2;
417534 docsection = noaction2;
535+ findall = find_all_symbols;
418536 parse_file(infile);
419537
420538 /* Rewind to start from beginning of file again */
@@ -425,8 +543,16 @@ int main(int argc, char *argv[]) · 4 unmodified lines
425543 symbolsonly = printline;
426544 singlefunctions = singfunc;
427545 docsection = docsect;
546+ findall = NULL;
428547
429548 parse_file(infile);
549+
550+ for (i = 0; i < all_list_len; i++) {
551+ if (!all_list[i])
552+ continue;
553+ fprintf(stderr, "Warning: didn't use docs for %s\n",
554+ all_list[i]);
555+ }
430556 }
431557 else if (strcmp("depend", argv[1]) == 0)
432558 {
@@ -439,6 +565,7 @@ int main(int argc, char *argv[]) · 6 unmodified lines
439565 symbolsonly = adddep;
440566 singlefunctions = adddep2;
441567 docsection = adddep2;
568+ findall = adddep;
442569 parse_file(infile);
443570 printf("\n");
444571 }