| @@ -34,12 +34,14 @@ · 33 unmodified lines |
| 34 | * | 34 | * |
| 35 | */ | 35 | */ |
| 36 | | 36 | |
| | 37 | #define _GNU_SOURCE |
| 37 | #include <stdio.h> | 38 | #include <stdio.h> |
| 38 | #include <stdlib.h> | 39 | #include <stdlib.h> |
| 39 | #include <string.h> | 40 | #include <string.h> |
| 40 | #include <ctype.h> | 41 | #include <ctype.h> |
| 41 | #include <unistd.h> | 42 | #include <unistd.h> |
| 42 | #include <limits.h> | 43 | #include <limits.h> |
| | 44 | #include <errno.h> |
| 43 | #include <sys/types.h> | 45 | #include <sys/types.h> |
| 44 | #include <sys/wait.h> | 46 | #include <sys/wait.h> |
| 45 | | 47 | |
| @@ -54,6 +56,7 @@ typedef void FILEONLY(char * file); · 8 unmodified lines |
| 54 | FILEONLY *internalfunctions; | 56 | FILEONLY *internalfunctions; |
| 55 | FILEONLY *externalfunctions; | 57 | FILEONLY *externalfunctions; |
| 56 | FILEONLY *symbolsonly; | 58 | FILEONLY *symbolsonly; |
| | 59 | FILEONLY *findall; |
| 57 | | 60 | |
| 58 | typedef void FILELINE(char * file, char * line); | 61 | typedef void FILELINE(char * file, char * line); |
| 59 | FILELINE * singlefunctions; | 62 | FILELINE * singlefunctions; |
| @@ -65,12 +68,30 @@ FILELINE * docsection; · 5 unmodified lines |
| 65 | #define KERNELDOCPATH "scripts/" | 68 | #define KERNELDOCPATH "scripts/" |
| 66 | #define KERNELDOC "kernel-doc" | 69 | #define KERNELDOC "kernel-doc" |
| 67 | #define DOCBOOK "-docbook" | 70 | #define DOCBOOK "-docbook" |
| | 71 | #define LIST "-list" |
| 68 | #define FUNCTION "-function" | 72 | #define FUNCTION "-function" |
| 69 | #define NOFUNCTION "-nofunction" | 73 | #define NOFUNCTION "-nofunction" |
| 70 | #define NODOCSECTIONS "-no-doc-sections" | 74 | #define NODOCSECTIONS "-no-doc-sections" |
| 71 | | 75 | |
| 72 | static char *srctree, *kernsrctree; | 76 | static char *srctree, *kernsrctree; |
| 73 | | 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 | |
| 74 | static void usage (void) | 95 | static void usage (void) |
| 75 | { | 96 | { |
| 76 | fprintf(stderr, "Usage: docproc {doc|depend} file\n"); | 97 | fprintf(stderr, "Usage: docproc {doc|depend} file\n"); |
| @@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type) · 171 unmodified lines |
| 248 | struct symfile * sym = &symfilelist[i]; | 269 | struct symfile * sym = &symfilelist[i]; |
| 249 | for (j=0; j < sym->symbolcnt; j++) { | 270 | for (j=0; j < sym->symbolcnt; j++) { |
| 250 | vec[idx++] = type; | 271 | vec[idx++] = type; |
| | 272 | consume_symbol(sym->symbollist[j].name); |
| 251 | vec[idx++] = sym->symbollist[j].name; | 273 | vec[idx++] = sym->symbollist[j].name; |
| 252 | } | 274 | } |
| 253 | } | 275 | } |
| @@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line) · 33 unmodified lines |
| 287 | vec[idx++] = &line[i]; | 309 | vec[idx++] = &line[i]; |
| 288 | } | 310 | } |
| 289 | } | 311 | } |
| | 312 | for (i = 0; i < idx; i++) { |
| | 313 | if (strcmp(vec[i], FUNCTION)) |
| | 314 | continue; |
| | 315 | consume_symbol(vec[i + 1]); |
| | 316 | } |
| 290 | vec[idx++] = filename; | 317 | vec[idx++] = filename; |
| 291 | vec[idx] = NULL; | 318 | vec[idx] = NULL; |
| 292 | exec_kernel_doc(vec); | 319 | exec_kernel_doc(vec); |
| @@ -306,6 +333,13 @@ static void docsect(char *filename, char *line) · 13 unmodified lines |
| 306 | if (*s == '\n') | 333 | if (*s == '\n') |
| 307 | *s = '\0'; | 334 | *s = '\0'; |
| 308 | | 335 | |
| | 336 | if (asprintf(&s, "DOC: %s", line) < 0) { |
| | 337 | perror("asprintf"); |
| | 338 | exit(1); |
| | 339 | } |
| | 340 | consume_symbol(s); |
| | 341 | free(s); |
| | 342 | |
| 309 | vec[0] = KERNELDOC; | 343 | vec[0] = KERNELDOC; |
| 310 | vec[1] = DOCBOOK; | 344 | vec[1] = DOCBOOK; |
| 311 | vec[2] = FUNCTION; | 345 | vec[2] = FUNCTION; |
| @@ -315,6 +349,84 @@ static void docsect(char *filename, char *line) · 3 unmodified lines |
| 315 | exec_kernel_doc(vec); | 349 | exec_kernel_doc(vec); |
| 316 | } | 350 | } |
| 317 | | 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 | |
| 318 | /* | 430 | /* |
| 319 | * Parse file, calling action specific functions for: | 431 | * Parse file, calling action specific functions for: |
| 320 | * 1) Lines containing !E | 432 | * 1) Lines containing !E |
| @@ -322,7 +434,8 @@ static void docsect(char *filename, char *line) · 1 unmodified line |
| 322 | * 3) Lines containing !D | 434 | * 3) Lines containing !D |
| 323 | * 4) Lines containing !F | 435 | * 4) Lines containing !F |
| 324 | * 5) Lines containing !P | 436 | * 5) Lines containing !P |
| 325 | * 6) Default lines - lines not matching the above | 437 | * 6) Lines containing !C |
| | 438 | * 7) Default lines - lines not matching the above |
| 326 | */ | 439 | */ |
| 327 | static void parse_file(FILE *infile) | 440 | static void parse_file(FILE *infile) |
| 328 | { | 441 | { |
| @@ -365,6 +478,12 @@ static void parse_file(FILE *infile) · 36 unmodified lines |
| 365 | s++; | 478 | s++; |
| 366 | docsection(line + 2, s); | 479 | docsection(line + 2, s); |
| 367 | break; | 480 | break; |
| | 481 | case 'C': |
| | 482 | while (*s && !isspace(*s)) s++; |
| | 483 | *s = '\0'; |
| | 484 | if (findall) |
| | 485 | findall(line+2); |
| | 486 | break; |
| 368 | default: | 487 | default: |
| 369 | defaultline(line); | 488 | defaultline(line); |
| 370 | } | 489 | } |
| @@ -380,6 +499,7 @@ static void parse_file(FILE *infile) · 9 unmodified lines |
| 380 | int main(int argc, char *argv[]) | 499 | int main(int argc, char *argv[]) |
| 381 | { | 500 | { |
| 382 | FILE * infile; | 501 | FILE * infile; |
| | 502 | int i; |
| 383 | | 503 | |
| 384 | srctree = getenv("SRCTREE"); | 504 | srctree = getenv("SRCTREE"); |
| 385 | if (!srctree) | 505 | if (!srctree) |
| @@ -415,6 +535,7 @@ int main(int argc, char *argv[]) · 29 unmodified lines |
| 415 | symbolsonly = find_export_symbols; | 535 | symbolsonly = find_export_symbols; |
| 416 | singlefunctions = noaction2; | 536 | singlefunctions = noaction2; |
| 417 | docsection = noaction2; | 537 | docsection = noaction2; |
| | 538 | findall = find_all_symbols; |
| 418 | parse_file(infile); | 539 | parse_file(infile); |
| 419 | | 540 | |
| 420 | /* Rewind to start from beginning of file again */ | 541 | /* Rewind to start from beginning of file again */ |
| @@ -425,8 +546,16 @@ int main(int argc, char *argv[]) · 4 unmodified lines |
| 425 | symbolsonly = printline; | 546 | symbolsonly = printline; |
| 426 | singlefunctions = singfunc; | 547 | singlefunctions = singfunc; |
| 427 | docsection = docsect; | 548 | docsection = docsect; |
| | 549 | findall = NULL; |
| 428 | | 550 | |
| 429 | parse_file(infile); | 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 | } |
| 430 | } | 559 | } |
| 431 | else if (strcmp("depend", argv[1]) == 0) | 560 | else if (strcmp("depend", argv[1]) == 0) |
| 432 | { | 561 | { |
| @@ -439,6 +568,7 @@ int main(int argc, char *argv[]) · 6 unmodified lines |
| 439 | symbolsonly = adddep; | 568 | symbolsonly = adddep; |
| 440 | singlefunctions = adddep2; | 569 | singlefunctions = adddep2; |
| 441 | docsection = adddep2; | 570 | docsection = adddep2; |
| | 571 | findall = adddep; |
| 442 | parse_file(infile); | 572 | parse_file(infile); |
| 443 | printf("\n"); | 573 | printf("\n"); |
| 444 | } | 574 | } |