History

kbuild: move scripts/basic/docproc.c to scripts/docproc.c

Move docproc from scripts/basic to scripts so it is only built for *doc targets instead of every time the kernel is built.

Peter Foley committed 15 years ago

Commit bffd2021 parent 7a04fc97 files · +9 −7Browse files

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

Unified · Split

3 files
  1. scripts/basic/.gitignore +0 −2
  2. scripts/basic/Makefile +1 −2
  3. scripts/basic/docproc.c +0 −583
scripts/basic/.gitignore+0−2
@@ -1,3 +1 @@
1−hash
21 fixdep
3−docproc
scripts/basic/Makefile+1−2
@@ -7,9 +7,8 @@ · 6 unmodified lines
77 # .config is included by main Makefile.
88 # ---------------------------------------------------------------------------
99 # fixdep: Used to generate dependency information during build process
10−# docproc: Used in Documentation/DocBook
1110
12−hostprogs-y := fixdep docproc
11+hostprogs-y := fixdep
1312 always := $(hostprogs-y)
1413
1514 # fixdep is needed to compile other host programs
scripts/basic/docproc.c+0−583
@@ -1,583 +0,0 @@
1−/*
2− * docproc is a simple preprocessor for the template files
3− * used as placeholders for the kernel internal documentation.
4− * docproc is used for documentation-frontend and
5− * dependency-generator.
6− * The two usages have in common that they require
7− * some knowledge of the .tmpl syntax, therefore they
8− * are kept together.
9− *
10− * documentation-frontend
11− * Scans the template file and call kernel-doc for
12− * all occurrences of ![EIF]file
13− * Beforehand each referenced file is scanned for
14− * any symbols that are exported via these macros:
15− * EXPORT_SYMBOL(), EXPORT_SYMBOL_GPL(), &
16− * EXPORT_SYMBOL_GPL_FUTURE()
17− * This is used to create proper -function and
18− * -nofunction arguments in calls to kernel-doc.
19− * Usage: docproc doc file.tmpl
20− *
21− * dependency-generator:
22− * Scans the template file and list all files
23− * referenced in a format recognized by make.
24− * Usage: docproc depend file.tmpl
25− * Writes dependency information to stdout
26− * in the following format:
27− * file.tmpl src.c src2.c
28− * The filenames are obtained from the following constructs:
29− * !Efilename
30− * !Ifilename
31− * !Dfilename
32− * !Ffilename
33− * !Pfilename
34− *
35− */
36−
37−#define _GNU_SOURCE
38−#include <stdio.h>
39−#include <stdlib.h>
40−#include <string.h>
41−#include <ctype.h>
42−#include <unistd.h>
43−#include <limits.h>
44−#include <errno.h>
45−#include <sys/types.h>
46−#include <sys/wait.h>
47−
48−/* exitstatus is used to keep track of any failing calls to kernel-doc,
49− * but execution continues. */
50−int exitstatus = 0;
51−
52−typedef void DFL(char *);
53−DFL *defaultline;
54−
55−typedef void FILEONLY(char * file);
56−FILEONLY *internalfunctions;
57−FILEONLY *externalfunctions;
58−FILEONLY *symbolsonly;
59−FILEONLY *findall;
60−
61−typedef void FILELINE(char * file, char * line);
62−FILELINE * singlefunctions;
63−FILELINE * entity_system;
64−FILELINE * docsection;
65−
66−#define MAXLINESZ 2048
67−#define MAXFILES 250
68−#define KERNELDOCPATH "scripts/"
69−#define KERNELDOC "kernel-doc"
70−#define DOCBOOK "-docbook"
71−#define LIST "-list"
72−#define FUNCTION "-function"
73−#define NOFUNCTION "-nofunction"
74−#define NODOCSECTIONS "-no-doc-sections"
75−
76−static char *srctree, *kernsrctree;
77−
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−
95−static void usage (void)
96−{
97− fprintf(stderr, "Usage: docproc {doc|depend} file\n");
98− fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
99− fprintf(stderr, "doc: frontend when generating kernel documentation\n");
100− fprintf(stderr, "depend: generate list of files referenced within file\n");
101− fprintf(stderr, "Environment variable SRCTREE: absolute path to sources.\n");
102− fprintf(stderr, " KBUILD_SRC: absolute path to kernel source tree.\n");
103−}
104−
105−/*
106− * Execute kernel-doc with parameters given in svec
107− */
108−static void exec_kernel_doc(char **svec)
109−{
110− pid_t pid;
111− int ret;
112− char real_filename[PATH_MAX + 1];
113− /* Make sure output generated so far are flushed */
114− fflush(stdout);
115− switch (pid=fork()) {
116− case -1:
117− perror("fork");
118− exit(1);
119− case 0:
120− memset(real_filename, 0, sizeof(real_filename));
121− strncat(real_filename, kernsrctree, PATH_MAX);
122− strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
123− PATH_MAX - strlen(real_filename));
124− execvp(real_filename, svec);
125− fprintf(stderr, "exec ");
126− perror(real_filename);
127− exit(1);
128− default:
129− waitpid(pid, &ret ,0);
130− }
131− if (WIFEXITED(ret))
132− exitstatus |= WEXITSTATUS(ret);
133− else
134− exitstatus = 0xff;
135−}
136−
137−/* Types used to create list of all exported symbols in a number of files */
138−struct symbols
139−{
140− char *name;
141−};
142−
143−struct symfile
144−{
145− char *filename;
146− struct symbols *symbollist;
147− int symbolcnt;
148−};
149−
150−struct symfile symfilelist[MAXFILES];
151−int symfilecnt = 0;
152−
153−static void add_new_symbol(struct symfile *sym, char * symname)
154−{
155− sym->symbollist =
156− realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
157− sym->symbollist[sym->symbolcnt++].name = strdup(symname);
158−}
159−
160−/* Add a filename to the list */
161−static struct symfile * add_new_file(char * filename)
162−{
163− symfilelist[symfilecnt++].filename = strdup(filename);
164− return &symfilelist[symfilecnt - 1];
165−}
166−
167−/* Check if file already are present in the list */
168−static struct symfile * filename_exist(char * filename)
169−{
170− int i;
171− for (i=0; i < symfilecnt; i++)
172− if (strcmp(symfilelist[i].filename, filename) == 0)
173− return &symfilelist[i];
174− return NULL;
175−}
176−
177−/*
178− * List all files referenced within the template file.
179− * Files are separated by tabs.
180− */
181−static void adddep(char * file) { printf("\t%s", file); }
182−static void adddep2(char * file, char * line) { line = line; adddep(file); }
183−static void noaction(char * line) { line = line; }
184−static void noaction2(char * file, char * line) { file = file; line = line; }
185−
186−/* Echo the line without further action */
187−static void printline(char * line) { printf("%s", line); }
188−
189−/*
190− * Find all symbols in filename that are exported with EXPORT_SYMBOL &
191− * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly).
192− * All symbols located are stored in symfilelist.
193− */
194−static void find_export_symbols(char * filename)
195−{
196− FILE * fp;
197− struct symfile *sym;
198− char line[MAXLINESZ];
199− if (filename_exist(filename) == NULL) {
200− char real_filename[PATH_MAX + 1];
201− memset(real_filename, 0, sizeof(real_filename));
202− strncat(real_filename, srctree, PATH_MAX);
203− strncat(real_filename, "/", PATH_MAX - strlen(real_filename));
204− strncat(real_filename, filename,
205− PATH_MAX - strlen(real_filename));
206− sym = add_new_file(filename);
207− fp = fopen(real_filename, "r");
208− if (fp == NULL)
209− {
210− fprintf(stderr, "docproc: ");
211− perror(real_filename);
212− exit(1);
213− }
214− while (fgets(line, MAXLINESZ, fp)) {
215− char *p;
216− char *e;
217− if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != NULL) ||
218− ((p = strstr(line, "EXPORT_SYMBOL")) != NULL)) {
219− /* Skip EXPORT_SYMBOL{_GPL} */
220− while (isalnum(*p) || *p == '_')
221− p++;
222− /* Remove parentheses & additional whitespace */
223− while (isspace(*p))
224− p++;
225− if (*p != '(')
226− continue; /* Syntax error? */
227− else
228− p++;
229− while (isspace(*p))
230− p++;
231− e = p;
232− while (isalnum(*e) || *e == '_')
233− e++;
234− *e = '\0';
235− add_new_symbol(sym, p);
236− }
237− }
238− fclose(fp);
239− }
240−}
241−
242−/*
243− * Document all external or internal functions in a file.
244− * Call kernel-doc with following parameters:
245− * kernel-doc -docbook -nofunction function_name1 filename
246− * Function names are obtained from all the src files
247− * by find_export_symbols.
248− * intfunc uses -nofunction
249− * extfunc uses -function
250− */
251−static void docfunctions(char * filename, char * type)
252−{
253− int i,j;
254− int symcnt = 0;
255− int idx = 0;
256− char **vec;
257−
258− for (i=0; i <= symfilecnt; i++)
259− symcnt += symfilelist[i].symbolcnt;
260− vec = malloc((2 + 2 * symcnt + 3) * sizeof(char *));
261− if (vec == NULL) {
262− perror("docproc: ");
263− exit(1);
264− }
265− vec[idx++] = KERNELDOC;
266− vec[idx++] = DOCBOOK;
267− vec[idx++] = NODOCSECTIONS;
268− for (i=0; i < symfilecnt; i++) {
269− struct symfile * sym = &symfilelist[i];
270− for (j=0; j < sym->symbolcnt; j++) {
271− vec[idx++] = type;
272− consume_symbol(sym->symbollist[j].name);
273− vec[idx++] = sym->symbollist[j].name;
274− }
275− }
276− vec[idx++] = filename;
277− vec[idx] = NULL;
278− printf("<!-- %s -->\n", filename);
279− exec_kernel_doc(vec);
280− fflush(stdout);
281− free(vec);
282−}
283−static void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); }
284−static void extfunc(char * filename) { docfunctions(filename, FUNCTION); }
285−
286−/*
287− * Document specific function(s) in a file.
288− * Call kernel-doc with the following parameters:
289− * kernel-doc -docbook -function function1 [-function function2]
290− */
291−static void singfunc(char * filename, char * line)
292−{
293− char *vec[200]; /* Enough for specific functions */
294− int i, idx = 0;
295− int startofsym = 1;
296− vec[idx++] = KERNELDOC;
297− vec[idx++] = DOCBOOK;
298−
299− /* Split line up in individual parameters preceded by FUNCTION */
300− for (i=0; line[i]; i++) {
301− if (isspace(line[i])) {
302− line[i] = '\0';
303− startofsym = 1;
304− continue;
305− }
306− if (startofsym) {
307− startofsym = 0;
308− vec[idx++] = FUNCTION;
309− vec[idx++] = &line[i];
310− }
311− }
312− for (i = 0; i < idx; i++) {
313− if (strcmp(vec[i], FUNCTION))
314− continue;
315− consume_symbol(vec[i + 1]);
316− }
317− vec[idx++] = filename;
318− vec[idx] = NULL;
319− exec_kernel_doc(vec);
320−}
321−
322−/*
323− * Insert specific documentation section from a file.
324− * Call kernel-doc with the following parameters:
325− * kernel-doc -docbook -function "doc section" filename
326− */
327−static void docsect(char *filename, char *line)
328−{
329− char *vec[6]; /* kerneldoc -docbook -function "section" file NULL */
330− char *s;
331−
332− for (s = line; *s; s++)
333− if (*s == '\n')
334− *s = '\0';
335−
336− if (asprintf(&s, "DOC: %s", line) < 0) {
337− perror("asprintf");
338− exit(1);
339− }
340− consume_symbol(s);
341− free(s);
342−
343− vec[0] = KERNELDOC;
344− vec[1] = DOCBOOK;
345− vec[2] = FUNCTION;
346− vec[3] = line;
347− vec[4] = filename;
348− vec[5] = NULL;
349− exec_kernel_doc(vec);
350−}
351−
352−static void find_all_symbols(char *filename)
353−{
354− char *vec[4]; /* kerneldoc -list file NULL */
355− pid_t pid;
356− int ret, i, count, start;
357− char real_filename[PATH_MAX + 1];
358− int pipefd[2];
359− char *data, *str;
360− size_t data_len = 0;
361−
362− vec[0] = KERNELDOC;
363− vec[1] = LIST;
364− vec[2] = filename;
365− vec[3] = NULL;
366−
367− if (pipe(pipefd)) {
368− perror("pipe");
369− exit(1);
370− }
371−
372− switch (pid=fork()) {
373− case -1:
374− perror("fork");
375− exit(1);
376− case 0:
377− close(pipefd[0]);
378− dup2(pipefd[1], 1);
379− memset(real_filename, 0, sizeof(real_filename));
380− strncat(real_filename, kernsrctree, PATH_MAX);
381− strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
382− PATH_MAX - strlen(real_filename));
383− execvp(real_filename, vec);
384− fprintf(stderr, "exec ");
385− perror(real_filename);
386− exit(1);
387− default:
388− close(pipefd[1]);
389− data = malloc(4096);
390− do {
391− while ((ret = read(pipefd[0],
392− data + data_len,
393− 4096)) > 0) {
394− data_len += ret;
395− data = realloc(data, data_len + 4096);
396− }
397− } while (ret == -EAGAIN);
398− if (ret != 0) {
399− perror("read");
400− exit(1);
401− }
402− waitpid(pid, &ret ,0);
403− }
404− if (WIFEXITED(ret))
405− exitstatus |= WEXITSTATUS(ret);
406− else
407− exitstatus = 0xff;
408−
409− count = 0;
410− /* poor man's strtok, but with counting */
411− for (i = 0; i < data_len; i++) {
412− if (data[i] == '\n') {
413− count++;
414− data[i] = '\0';
415− }
416− }
417− start = all_list_len;
418− all_list_len += count;
419− all_list = realloc(all_list, sizeof(char *) * all_list_len);
420− str = data;
421− for (i = 0; i < data_len && start != all_list_len; i++) {
422− if (data[i] == '\0') {
423− all_list[start] = str;
424− str = data + i + 1;
425− start++;
426− }
427− }
428−}
429−
430−/*
431− * Parse file, calling action specific functions for:
432− * 1) Lines containing !E
433− * 2) Lines containing !I
434− * 3) Lines containing !D
435− * 4) Lines containing !F
436− * 5) Lines containing !P
437− * 6) Lines containing !C
438− * 7) Default lines - lines not matching the above
439− */
440−static void parse_file(FILE *infile)
441−{
442− char line[MAXLINESZ];
443− char * s;
444− while (fgets(line, MAXLINESZ, infile)) {
445− if (line[0] == '!') {
446− s = line + 2;
447− switch (line[1]) {
448− case 'E':
449− while (*s && !isspace(*s)) s++;
450− *s = '\0';
451− externalfunctions(line+2);
452− break;
453− case 'I':
454− while (*s && !isspace(*s)) s++;
455− *s = '\0';
456− internalfunctions(line+2);
457− break;
458− case 'D':
459− while (*s && !isspace(*s)) s++;
460− *s = '\0';
461− symbolsonly(line+2);
462− break;
463− case 'F':
464− /* filename */
465− while (*s && !isspace(*s)) s++;
466− *s++ = '\0';
467− /* function names */
468− while (isspace(*s))
469− s++;
470− singlefunctions(line +2, s);
471− break;
472− case 'P':
473− /* filename */
474− while (*s && !isspace(*s)) s++;
475− *s++ = '\0';
476− /* DOC: section name */
477− while (isspace(*s))
478− s++;
479− docsection(line + 2, s);
480− break;
481− case 'C':
482− while (*s && !isspace(*s)) s++;
483− *s = '\0';
484− if (findall)
485− findall(line+2);
486− break;
487− default:
488− defaultline(line);
489− }
490− }
491− else {
492− defaultline(line);
493− }
494− }
495− fflush(stdout);
496−}
497−
498−
499−int main(int argc, char *argv[])
500−{
501− FILE * infile;
502− int i;
503−
504− srctree = getenv("SRCTREE");
505− if (!srctree)
506− srctree = getcwd(NULL, 0);
507− kernsrctree = getenv("KBUILD_SRC");
508− if (!kernsrctree || !*kernsrctree)
509− kernsrctree = srctree;
510− if (argc != 3) {
511− usage();
512− exit(1);
513− }
514− /* Open file, exit on error */
515− infile = fopen(argv[2], "r");
516− if (infile == NULL) {
517− fprintf(stderr, "docproc: ");
518− perror(argv[2]);
519− exit(2);
520− }
521−
522− if (strcmp("doc", argv[1]) == 0)
523− {
524− /* Need to do this in two passes.
525− * First pass is used to collect all symbols exported
526− * in the various files;
527− * Second pass generate the documentation.
528− * This is required because some functions are declared
529− * and exported in different files :-((
530− */
531− /* Collect symbols */
532− defaultline = noaction;
533− internalfunctions = find_export_symbols;
534− externalfunctions = find_export_symbols;
535− symbolsonly = find_export_symbols;
536− singlefunctions = noaction2;
537− docsection = noaction2;
538− findall = find_all_symbols;
539− parse_file(infile);
540−
541− /* Rewind to start from beginning of file again */
542− fseek(infile, 0, SEEK_SET);
543− defaultline = printline;
544− internalfunctions = intfunc;
545− externalfunctions = extfunc;
546− symbolsonly = printline;
547− singlefunctions = singfunc;
548− docsection = docsect;
549− findall = NULL;
550−
551− parse_file(infile);
552−
553− for (i = 0; i < all_list_len; i++) {
554− if (!all_list[i])
555− continue;
556− fprintf(stderr, "Warning: didn't use docs for %s\n",
557− all_list[i]);
558− }
559− }
560− else if (strcmp("depend", argv[1]) == 0)
561− {
562− /* Create first part of dependency chain
563− * file.tmpl */
564− printf("%s\t", argv[2]);
565− defaultline = noaction;
566− internalfunctions = adddep;
567− externalfunctions = adddep;
568− symbolsonly = adddep;
569− singlefunctions = adddep2;
570− docsection = adddep2;
571− findall = adddep;
572− parse_file(infile);
573− printf("\n");
574− }
575− else
576− {
577− fprintf(stderr, "Unknown option: %s\n", argv[1]);
578− exit(1);
579− }
580− fclose(infile);
581− fflush(stdout);
582− return exitstatus;
583−}