OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [scripts/] [basic/] [docproc.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
 *
34
 */
35
 
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <ctype.h>
40
#include <unistd.h>
41
#include <limits.h>
42
#include <sys/types.h>
43
#include <sys/wait.h>
44
 
45
/* exitstatus is used to keep track of any failing calls to kernel-doc,
46
 * but execution continues. */
47
int exitstatus = 0;
48
 
49
typedef void DFL(char *);
50
DFL *defaultline;
51
 
52
typedef void FILEONLY(char * file);
53
FILEONLY *internalfunctions;
54
FILEONLY *externalfunctions;
55
FILEONLY *symbolsonly;
56
 
57
typedef void FILELINE(char * file, char * line);
58
FILELINE * singlefunctions;
59
FILELINE * entity_system;
60
 
61
#define MAXLINESZ     2048
62
#define MAXFILES      250
63
#define KERNELDOCPATH "scripts/"
64
#define KERNELDOC     "kernel-doc"
65
#define DOCBOOK       "-docbook"
66
#define FUNCTION      "-function"
67
#define NOFUNCTION    "-nofunction"
68
 
69
char *srctree;
70
 
71
void usage (void)
72
{
73
        fprintf(stderr, "Usage: docproc {doc|depend} file\n");
74
        fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
75
        fprintf(stderr, "doc: frontend when generating kernel documentation\n");
76
        fprintf(stderr, "depend: generate list of files referenced within file\n");
77
        fprintf(stderr, "Environment variable SRCTREE: absolute path to kernel source tree.\n");
78
}
79
 
80
/*
81
 * Execute kernel-doc with parameters given in svec
82
 */
83
void exec_kernel_doc(char **svec)
84
{
85
        pid_t pid;
86
        int ret;
87
        char real_filename[PATH_MAX + 1];
88
        /* Make sure output generated so far are flushed */
89
        fflush(stdout);
90
        switch (pid=fork()) {
91
                case -1:
92
                        perror("fork");
93
                        exit(1);
94
                case  0:
95
                        memset(real_filename, 0, sizeof(real_filename));
96
                        strncat(real_filename, srctree, PATH_MAX);
97
                        strncat(real_filename, KERNELDOCPATH KERNELDOC,
98
                                        PATH_MAX - strlen(real_filename));
99
                        execvp(real_filename, svec);
100
                        fprintf(stderr, "exec ");
101
                        perror(real_filename);
102
                        exit(1);
103
                default:
104
                        waitpid(pid, &ret ,0);
105
        }
106
        if (WIFEXITED(ret))
107
                exitstatus |= WEXITSTATUS(ret);
108
        else
109
                exitstatus = 0xff;
110
}
111
 
112
/* Types used to create list of all exported symbols in a number of files */
113
struct symbols
114
{
115
        char *name;
116
};
117
 
118
struct symfile
119
{
120
        char *filename;
121
        struct symbols *symbollist;
122
        int symbolcnt;
123
};
124
 
125
struct symfile symfilelist[MAXFILES];
126
int symfilecnt = 0;
127
 
128
void add_new_symbol(struct symfile *sym, char * symname)
129
{
130
        sym->symbollist =
131
          realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
132
        sym->symbollist[sym->symbolcnt++].name = strdup(symname);
133
}
134
 
135
/* Add a filename to the list */
136
struct symfile * add_new_file(char * filename)
137
{
138
        symfilelist[symfilecnt++].filename = strdup(filename);
139
        return &symfilelist[symfilecnt - 1];
140
}
141
 
142
/* Check if file already are present in the list */
143
struct symfile * filename_exist(char * filename)
144
{
145
        int i;
146
        for (i=0; i < symfilecnt; i++)
147
                if (strcmp(symfilelist[i].filename, filename) == 0)
148
                        return &symfilelist[i];
149
        return NULL;
150
}
151
 
152
/*
153
 * List all files referenced within the template file.
154
 * Files are separated by tabs.
155
 */
156
void adddep(char * file)                   { printf("\t%s", file); }
157
void adddep2(char * file, char * line)     { line = line; adddep(file); }
158
void noaction(char * line)                 { line = line; }
159
void noaction2(char * file, char * line)   { file = file; line = line; }
160
 
161
/* Echo the line without further action */
162
void printline(char * line)               { printf("%s", line); }
163
 
164
/*
165
 * Find all symbols in filename that are exported with EXPORT_SYMBOL &
166
 * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly).
167
 * All symbols located are stored in symfilelist.
168
 */
169
void find_export_symbols(char * filename)
170
{
171
        FILE * fp;
172
        struct symfile *sym;
173
        char line[MAXLINESZ];
174
        if (filename_exist(filename) == NULL) {
175
                char real_filename[PATH_MAX + 1];
176
                memset(real_filename, 0, sizeof(real_filename));
177
                strncat(real_filename, srctree, PATH_MAX);
178
                strncat(real_filename, filename,
179
                                PATH_MAX - strlen(real_filename));
180
                sym = add_new_file(filename);
181
                fp = fopen(real_filename, "r");
182
                if (fp == NULL)
183
                {
184
                        fprintf(stderr, "docproc: ");
185
                        perror(real_filename);
186
                        exit(1);
187
                }
188
                while (fgets(line, MAXLINESZ, fp)) {
189
                        char *p;
190
                        char *e;
191
                        if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != NULL) ||
192
                            ((p = strstr(line, "EXPORT_SYMBOL")) != NULL)) {
193
                                /* Skip EXPORT_SYMBOL{_GPL} */
194
                                while (isalnum(*p) || *p == '_')
195
                                        p++;
196
                                /* Remove parentheses & additional whitespace */
197
                                while (isspace(*p))
198
                                        p++;
199
                                if (*p != '(')
200
                                        continue; /* Syntax error? */
201
                                else
202
                                        p++;
203
                                while (isspace(*p))
204
                                        p++;
205
                                e = p;
206
                                while (isalnum(*e) || *e == '_')
207
                                        e++;
208
                                *e = '\0';
209
                                add_new_symbol(sym, p);
210
                        }
211
                }
212
                fclose(fp);
213
        }
214
}
215
 
216
/*
217
 * Document all external or internal functions in a file.
218
 * Call kernel-doc with following parameters:
219
 * kernel-doc -docbook -nofunction function_name1 filename
220
 * Function names are obtained from all the src files
221
 * by find_export_symbols.
222
 * intfunc uses -nofunction
223
 * extfunc uses -function
224
 */
225
void docfunctions(char * filename, char * type)
226
{
227
        int i,j;
228
        int symcnt = 0;
229
        int idx = 0;
230
        char **vec;
231
 
232
        for (i=0; i <= symfilecnt; i++)
233
                symcnt += symfilelist[i].symbolcnt;
234
        vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*));
235
        if (vec == NULL) {
236
                perror("docproc: ");
237
                exit(1);
238
        }
239
        vec[idx++] = KERNELDOC;
240
        vec[idx++] = DOCBOOK;
241
        for (i=0; i < symfilecnt; i++) {
242
                struct symfile * sym = &symfilelist[i];
243
                for (j=0; j < sym->symbolcnt; j++) {
244
                        vec[idx++]     = type;
245
                        vec[idx++] = sym->symbollist[j].name;
246
                }
247
        }
248
        vec[idx++]     = filename;
249
        vec[idx] = NULL;
250
        printf("<!-- %s -->\n", filename);
251
        exec_kernel_doc(vec);
252
        fflush(stdout);
253
        free(vec);
254
}
255
void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); }
256
void extfunc(char * filename) { docfunctions(filename, FUNCTION);   }
257
 
258
/*
259
 * Document specific function(s) in a file.
260
 * Call kernel-doc with the following parameters:
261
 * kernel-doc -docbook -function function1 [-function function2]
262
 */
263
void singfunc(char * filename, char * line)
264
{
265
        char *vec[200]; /* Enough for specific functions */
266
        int i, idx = 0;
267
        int startofsym = 1;
268
        vec[idx++] = KERNELDOC;
269
        vec[idx++] = DOCBOOK;
270
 
271
        /* Split line up in individual parameters preceded by FUNCTION */
272
        for (i=0; line[i]; i++) {
273
                if (isspace(line[i])) {
274
                        line[i] = '\0';
275
                        startofsym = 1;
276
                        continue;
277
                }
278
                if (startofsym) {
279
                        startofsym = 0;
280
                        vec[idx++] = FUNCTION;
281
                        vec[idx++] = &line[i];
282
                }
283
        }
284
        vec[idx++] = filename;
285
        vec[idx] = NULL;
286
        exec_kernel_doc(vec);
287
}
288
 
289
/*
290
 * Parse file, calling action specific functions for:
291
 * 1) Lines containing !E
292
 * 2) Lines containing !I
293
 * 3) Lines containing !D
294
 * 4) Lines containing !F
295
 * 5) Default lines - lines not matching the above
296
 */
297
void parse_file(FILE *infile)
298
{
299
        char line[MAXLINESZ];
300
        char * s;
301
        while (fgets(line, MAXLINESZ, infile)) {
302
                if (line[0] == '!') {
303
                        s = line + 2;
304
                        switch (line[1]) {
305
                                case 'E':
306
                                        while (*s && !isspace(*s)) s++;
307
                                        *s = '\0';
308
                                        externalfunctions(line+2);
309
                                        break;
310
                                case 'I':
311
                                        while (*s && !isspace(*s)) s++;
312
                                        *s = '\0';
313
                                        internalfunctions(line+2);
314
                                        break;
315
                                case 'D':
316
                                        while (*s && !isspace(*s)) s++;
317
                                        *s = '\0';
318
                                        symbolsonly(line+2);
319
                                        break;
320
                                case 'F':
321
                                        /* filename */
322
                                        while (*s && !isspace(*s)) s++;
323
                                        *s++ = '\0';
324
                                        /* function names */
325
                                        while (isspace(*s))
326
                                                s++;
327
                                        singlefunctions(line +2, s);
328
                                        break;
329
                                default:
330
                                        defaultline(line);
331
                        }
332
                }
333
                else {
334
                        defaultline(line);
335
                }
336
        }
337
        fflush(stdout);
338
}
339
 
340
 
341
int main(int argc, char *argv[])
342
{
343
        FILE * infile;
344
 
345
        srctree = getenv("SRCTREE");
346
        if (!srctree)
347
                srctree = getcwd(NULL, 0);
348
        if (argc != 3) {
349
                usage();
350
                exit(1);
351
        }
352
        /* Open file, exit on error */
353
        infile = fopen(argv[2], "r");
354
        if (infile == NULL) {
355
                fprintf(stderr, "docproc: ");
356
                perror(argv[2]);
357
                exit(2);
358
        }
359
 
360
        if (strcmp("doc", argv[1]) == 0)
361
        {
362
                /* Need to do this in two passes.
363
                 * First pass is used to collect all symbols exported
364
                 * in the various files;
365
                 * Second pass generate the documentation.
366
                 * This is required because some functions are declared
367
                 * and exported in different files :-((
368
                 */
369
                /* Collect symbols */
370
                defaultline       = noaction;
371
                internalfunctions = find_export_symbols;
372
                externalfunctions = find_export_symbols;
373
                symbolsonly       = find_export_symbols;
374
                singlefunctions   = noaction2;
375
                parse_file(infile);
376
 
377
                /* Rewind to start from beginning of file again */
378
                fseek(infile, 0, SEEK_SET);
379
                defaultline       = printline;
380
                internalfunctions = intfunc;
381
                externalfunctions = extfunc;
382
                symbolsonly       = printline;
383
                singlefunctions   = singfunc;
384
 
385
                parse_file(infile);
386
        }
387
        else if (strcmp("depend", argv[1]) == 0)
388
        {
389
                /* Create first part of dependency chain
390
                 * file.tmpl */
391
                printf("%s\t", argv[2]);
392
                defaultline       = noaction;
393
                internalfunctions = adddep;
394
                externalfunctions = adddep;
395
                symbolsonly       = adddep;
396
                singlefunctions   = adddep2;
397
                parse_file(infile);
398
                printf("\n");
399
        }
400
        else
401
        {
402
                fprintf(stderr, "Unknown option: %s\n", argv[1]);
403
                exit(1);
404
        }
405
        fclose(infile);
406
        fflush(stdout);
407
        return exitstatus;
408
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.