diff options
Diffstat (limited to 'scripts/basic')
| -rw-r--r-- | scripts/basic/docproc.c | 129 | 
1 files changed, 128 insertions, 1 deletions
| diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 79ab973fb43..fc3b18d844a 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c @@ -34,12 +34,14 @@   *   */ +#define _GNU_SOURCE  #include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include <ctype.h>  #include <unistd.h>  #include <limits.h> +#include <errno.h>  #include <sys/types.h>  #include <sys/wait.h> @@ -54,6 +56,7 @@ typedef void FILEONLY(char * file);  FILEONLY *internalfunctions;  FILEONLY *externalfunctions;  FILEONLY *symbolsonly; +FILEONLY *findall;  typedef void FILELINE(char * file, char * line);  FILELINE * singlefunctions; @@ -65,12 +68,30 @@ FILELINE * docsection;  #define KERNELDOCPATH "scripts/"  #define KERNELDOC     "kernel-doc"  #define DOCBOOK       "-docbook" +#define LIST          "-list"  #define FUNCTION      "-function"  #define NOFUNCTION    "-nofunction"  #define NODOCSECTIONS "-no-doc-sections"  static char *srctree, *kernsrctree; +static char **all_list = NULL; +static int all_list_len = 0; + +static void consume_symbol(const char *sym) +{ +	int i; + +	for (i = 0; i < all_list_len; i++) { +		if (!all_list[i]) +			continue; +		if (strcmp(sym, all_list[i])) +			continue; +		all_list[i] = NULL; +		break; +	} +} +  static void usage (void)  {  	fprintf(stderr, "Usage: docproc {doc|depend} file\n"); @@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type)  		struct symfile * sym = &symfilelist[i];  		for (j=0; j < sym->symbolcnt; j++) {  			vec[idx++]     = type; +			consume_symbol(sym->symbollist[j].name);  			vec[idx++] = sym->symbollist[j].name;  		}  	} @@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line)                          vec[idx++] = &line[i];                  }          } +	for (i = 0; i < idx; i++) { +        	if (strcmp(vec[i], FUNCTION)) +        		continue; +		consume_symbol(vec[i + 1]); +	}  	vec[idx++] = filename;  	vec[idx] = NULL;  	exec_kernel_doc(vec); @@ -306,6 +333,10 @@ static void docsect(char *filename, char *line)  		if (*s == '\n')  			*s = '\0'; +	asprintf(&s, "DOC: %s", line); +	consume_symbol(s); +	free(s); +  	vec[0] = KERNELDOC;  	vec[1] = DOCBOOK;  	vec[2] = FUNCTION; @@ -315,6 +346,84 @@ static void docsect(char *filename, char *line)  	exec_kernel_doc(vec);  } +static void find_all_symbols(char *filename) +{ +	char *vec[4]; /* kerneldoc -list file NULL */ +	pid_t pid; +	int ret, i, count, start; +	char real_filename[PATH_MAX + 1]; +	int pipefd[2]; +	char *data, *str; +	size_t data_len = 0; + +	vec[0] = KERNELDOC; +	vec[1] = LIST; +	vec[2] = filename; +	vec[3] = NULL; + +	if (pipe(pipefd)) { +		perror("pipe"); +		exit(1); +	} + +	switch (pid=fork()) { +		case -1: +			perror("fork"); +			exit(1); +		case  0: +			close(pipefd[0]); +			dup2(pipefd[1], 1); +			memset(real_filename, 0, sizeof(real_filename)); +			strncat(real_filename, kernsrctree, PATH_MAX); +			strncat(real_filename, "/" KERNELDOCPATH KERNELDOC, +					PATH_MAX - strlen(real_filename)); +			execvp(real_filename, vec); +			fprintf(stderr, "exec "); +			perror(real_filename); +			exit(1); +		default: +			close(pipefd[1]); +			data = malloc(4096); +			do { +				while ((ret = read(pipefd[0], +						   data + data_len, +						   4096)) > 0) { +					data_len += ret; +					data = realloc(data, data_len + 4096); +				} +			} while (ret == -EAGAIN); +			if (ret != 0) { +				perror("read"); +				exit(1); +			} +			waitpid(pid, &ret ,0); +	} +	if (WIFEXITED(ret)) +		exitstatus |= WEXITSTATUS(ret); +	else +		exitstatus = 0xff; + +	count = 0; +	/* poor man's strtok, but with counting */ +	for (i = 0; i < data_len; i++) { +		if (data[i] == '\n') { +			count++; +			data[i] = '\0'; +		} +	} +	start = all_list_len; +	all_list_len += count; +	all_list = realloc(all_list, sizeof(char *) * all_list_len); +	str = data; +	for (i = 0; i < data_len && start != all_list_len; i++) { +		if (data[i] == '\0') { +			all_list[start] = str; +			str = data + i + 1; +			start++; +		} +	} +} +  /*   * Parse file, calling action specific functions for:   * 1) Lines containing !E @@ -322,7 +431,8 @@ static void docsect(char *filename, char *line)   * 3) Lines containing !D   * 4) Lines containing !F   * 5) Lines containing !P - * 6) Default lines - lines not matching the above + * 6) Lines containing !C + * 7) Default lines - lines not matching the above   */  static void parse_file(FILE *infile)  { @@ -365,6 +475,12 @@ static void parse_file(FILE *infile)  						s++;  					docsection(line + 2, s);  					break; +				case 'C': +					while (*s && !isspace(*s)) s++; +					*s = '\0'; +					if (findall) +						findall(line+2); +					break;  				default:  					defaultline(line);  			} @@ -380,6 +496,7 @@ static void parse_file(FILE *infile)  int main(int argc, char *argv[])  {  	FILE * infile; +	int i;  	srctree = getenv("SRCTREE");  	if (!srctree) @@ -415,6 +532,7 @@ int main(int argc, char *argv[])  		symbolsonly       = find_export_symbols;  		singlefunctions   = noaction2;  		docsection        = noaction2; +		findall           = find_all_symbols;  		parse_file(infile);  		/* Rewind to start from beginning of file again */ @@ -425,8 +543,16 @@ int main(int argc, char *argv[])  		symbolsonly       = printline;  		singlefunctions   = singfunc;  		docsection        = docsect; +		findall           = NULL;  		parse_file(infile); + +		for (i = 0; i < all_list_len; i++) { +			if (!all_list[i]) +				continue; +			fprintf(stderr, "Warning: didn't use docs for %s\n", +				all_list[i]); +		}  	}  	else if (strcmp("depend", argv[1]) == 0)  	{ @@ -439,6 +565,7 @@ int main(int argc, char *argv[])  		symbolsonly       = adddep;  		singlefunctions   = adddep2;  		docsection        = adddep2; +		findall           = adddep;  		parse_file(infile);  		printf("\n");  	} | 
