From 568fb2dec9c68bb38c2a1ad01fb3d4dd41488115 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 May 2016 16:15:39 +0300 Subject: docproc: add variables for subcommand and filename Improves clarity. No functional changes. Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/docproc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'scripts/docproc.c') diff --git a/scripts/docproc.c b/scripts/docproc.c index e267e621431a..48abc01a920e 100644 --- a/scripts/docproc.c +++ b/scripts/docproc.c @@ -500,6 +500,7 @@ static void parse_file(FILE *infile) int main(int argc, char *argv[]) { + const char *subcommand, *filename; FILE * infile; int i; @@ -513,15 +514,19 @@ int main(int argc, char *argv[]) usage(); exit(1); } + + subcommand = argv[1]; + filename = argv[2]; + /* Open file, exit on error */ - infile = fopen(argv[2], "r"); + infile = fopen(filename, "r"); if (infile == NULL) { fprintf(stderr, "docproc: "); - perror(argv[2]); + perror(filename); exit(2); } - if (strcmp("doc", argv[1]) == 0) { + if (strcmp("doc", subcommand) == 0) { /* Need to do this in two passes. * First pass is used to collect all symbols exported * in the various files; @@ -557,10 +562,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "Warning: didn't use docs for %s\n", all_list[i]); } - } else if (strcmp("depend", argv[1]) == 0) { + } else if (strcmp("depend", subcommand) == 0) { /* Create first part of dependency chain * file.tmpl */ - printf("%s\t", argv[2]); + printf("%s\t", filename); defaultline = noaction; internalfunctions = adddep; externalfunctions = adddep; @@ -571,7 +576,7 @@ int main(int argc, char *argv[]) parse_file(infile); printf("\n"); } else { - fprintf(stderr, "Unknown option: %s\n", argv[1]); + fprintf(stderr, "Unknown option: %s\n", subcommand); exit(1); } fclose(infile); -- cgit v1.2.3 From 868fb19212ca5bdbfa765a97a4bf6d2439b89056 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 May 2016 16:15:40 +0300 Subject: docproc: reduce unnecessary indentation Improves clarity. No functional changes. Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/docproc.c | 93 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) (limited to 'scripts/docproc.c') diff --git a/scripts/docproc.c b/scripts/docproc.c index 48abc01a920e..fb195f0ed0ef 100644 --- a/scripts/docproc.c +++ b/scripts/docproc.c @@ -445,52 +445,53 @@ static void parse_file(FILE *infile) char line[MAXLINESZ]; char * s; while (fgets(line, MAXLINESZ, infile)) { - if (line[0] == '!') { - s = line + 2; - switch (line[1]) { - case 'E': - while (*s && !isspace(*s)) s++; - *s = '\0'; - externalfunctions(line+2); - break; - case 'I': - while (*s && !isspace(*s)) s++; - *s = '\0'; - internalfunctions(line+2); - break; - case 'D': - while (*s && !isspace(*s)) s++; - *s = '\0'; - symbolsonly(line+2); - break; - case 'F': - /* filename */ - while (*s && !isspace(*s)) s++; - *s++ = '\0'; - /* function names */ - while (isspace(*s)) - s++; - singlefunctions(line +2, s); - break; - case 'P': - /* filename */ - while (*s && !isspace(*s)) s++; - *s++ = '\0'; - /* DOC: section name */ - while (isspace(*s)) - s++; - docsection(line + 2, s); - break; - case 'C': - while (*s && !isspace(*s)) s++; - *s = '\0'; - if (findall) - findall(line+2); - break; - default: - defaultline(line); - } - } else { + if (line[0] != '!') { + defaultline(line); + continue; + } + + s = line + 2; + switch (line[1]) { + case 'E': + while (*s && !isspace(*s)) s++; + *s = '\0'; + externalfunctions(line+2); + break; + case 'I': + while (*s && !isspace(*s)) s++; + *s = '\0'; + internalfunctions(line+2); + break; + case 'D': + while (*s && !isspace(*s)) s++; + *s = '\0'; + symbolsonly(line+2); + break; + case 'F': + /* filename */ + while (*s && !isspace(*s)) s++; + *s++ = '\0'; + /* function names */ + while (isspace(*s)) + s++; + singlefunctions(line +2, s); + break; + case 'P': + /* filename */ + while (*s && !isspace(*s)) s++; + *s++ = '\0'; + /* DOC: section name */ + while (isspace(*s)) + s++; + docsection(line + 2, s); + break; + case 'C': + while (*s && !isspace(*s)) s++; + *s = '\0'; + if (findall) + findall(line+2); + break; + default: defaultline(line); } } -- cgit v1.2.3 From a48dc45e9c02ebaebc79de5b3fec8e4f59a9fe9f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 May 2016 16:15:41 +0300 Subject: docproc: abstract docproc directive detection Helps follow-up work. No functional changes. Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/docproc.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'scripts/docproc.c') diff --git a/scripts/docproc.c b/scripts/docproc.c index fb195f0ed0ef..bc900310b431 100644 --- a/scripts/docproc.c +++ b/scripts/docproc.c @@ -430,6 +430,15 @@ static void find_all_symbols(char *filename) } } +/* Return pointer to directive content, or NULL if not a directive. */ +static char *is_directive(char *line) +{ + if (line[0] == '!') + return line + 1; + + return NULL; +} + /* * Parse file, calling action specific functions for: * 1) Lines containing !E @@ -443,29 +452,30 @@ static void find_all_symbols(char *filename) static void parse_file(FILE *infile) { char line[MAXLINESZ]; - char * s; + char *p, *s; while (fgets(line, MAXLINESZ, infile)) { - if (line[0] != '!') { + p = is_directive(line); + if (!p) { defaultline(line); continue; } - s = line + 2; - switch (line[1]) { + s = p + 1; + switch (*p++) { case 'E': while (*s && !isspace(*s)) s++; *s = '\0'; - externalfunctions(line+2); + externalfunctions(p); break; case 'I': while (*s && !isspace(*s)) s++; *s = '\0'; - internalfunctions(line+2); + internalfunctions(p); break; case 'D': while (*s && !isspace(*s)) s++; *s = '\0'; - symbolsonly(line+2); + symbolsonly(p); break; case 'F': /* filename */ @@ -474,7 +484,7 @@ static void parse_file(FILE *infile) /* function names */ while (isspace(*s)) s++; - singlefunctions(line +2, s); + singlefunctions(p, s); break; case 'P': /* filename */ @@ -483,13 +493,13 @@ static void parse_file(FILE *infile) /* DOC: section name */ while (isspace(*s)) s++; - docsection(line + 2, s); + docsection(p, s); break; case 'C': while (*s && !isspace(*s)) s++; *s = '\0'; if (findall) - findall(line+2); + findall(p); break; default: defaultline(line); -- cgit v1.2.3 From 1dcdad0aacb6d762b77f3e17167d131a14c0dbce Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 May 2016 16:15:42 +0300 Subject: docproc: abstract terminating lines at first space Cleaner code. Also fixes a bug when F or P directives didn't in fact have space. Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/docproc.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'scripts/docproc.c') diff --git a/scripts/docproc.c b/scripts/docproc.c index bc900310b431..a933e054402d 100644 --- a/scripts/docproc.c +++ b/scripts/docproc.c @@ -430,6 +430,21 @@ static void find_all_symbols(char *filename) } } +/* + * Terminate s at first space, if any. If there was a space, return pointer to + * the character after that. Otherwise, return pointer to the terminating NUL. + */ +static char *chomp(char *s) +{ + while (*s && !isspace(*s)) + s++; + + if (*s) + *s++ = '\0'; + + return s; +} + /* Return pointer to directive content, or NULL if not a directive. */ static char *is_directive(char *line) { @@ -460,27 +475,22 @@ static void parse_file(FILE *infile) continue; } - s = p + 1; switch (*p++) { case 'E': - while (*s && !isspace(*s)) s++; - *s = '\0'; + chomp(p); externalfunctions(p); break; case 'I': - while (*s && !isspace(*s)) s++; - *s = '\0'; + chomp(p); internalfunctions(p); break; case 'D': - while (*s && !isspace(*s)) s++; - *s = '\0'; + chomp(p); symbolsonly(p); break; case 'F': /* filename */ - while (*s && !isspace(*s)) s++; - *s++ = '\0'; + s = chomp(p); /* function names */ while (isspace(*s)) s++; @@ -488,16 +498,14 @@ static void parse_file(FILE *infile) break; case 'P': /* filename */ - while (*s && !isspace(*s)) s++; - *s++ = '\0'; + s = chomp(p); /* DOC: section name */ while (isspace(*s)) s++; docsection(p, s); break; case 'C': - while (*s && !isspace(*s)) s++; - *s = '\0'; + chomp(p); if (findall) findall(p); break; -- cgit v1.2.3 From 064669b43baa4b74b262c49db3ce69118e2f0f2d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 May 2016 16:15:43 +0300 Subject: docproc: add support for reStructuredText format via --rst option Expect reStructuredText input and have kernel-doc produce reStructuredText output with the new --rst option. Also add --docbook option for completeness. If no option is given, default to reStructuredText if the input file has ".rst" extension, DocBook otherwise. Directives for reStructuredText use .. ! instead of just !, to make them reStructuredText comments. Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/docproc.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 10 deletions(-) (limited to 'scripts/docproc.c') diff --git a/scripts/docproc.c b/scripts/docproc.c index a933e054402d..9babfd108d2e 100644 --- a/scripts/docproc.c +++ b/scripts/docproc.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -68,12 +69,23 @@ FILELINE * docsection; #define KERNELDOCPATH "scripts/" #define KERNELDOC "kernel-doc" #define DOCBOOK "-docbook" +#define RST "-rst" #define LIST "-list" #define FUNCTION "-function" #define NOFUNCTION "-nofunction" #define NODOCSECTIONS "-no-doc-sections" #define SHOWNOTFOUND "-show-not-found" +enum file_format { + FORMAT_AUTO, + FORMAT_DOCBOOK, + FORMAT_RST, +}; + +static enum file_format file_format = FORMAT_AUTO; + +#define KERNELDOC_FORMAT (file_format == FORMAT_RST ? RST : DOCBOOK) + static char *srctree, *kernsrctree; static char **all_list = NULL; @@ -95,7 +107,7 @@ static void consume_symbol(const char *sym) static void usage (void) { - fprintf(stderr, "Usage: docproc {doc|depend} file\n"); + fprintf(stderr, "Usage: docproc [{--docbook|--rst}] {doc|depend} file\n"); fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n"); fprintf(stderr, "doc: frontend when generating kernel documentation\n"); fprintf(stderr, "depend: generate list of files referenced within file\n"); @@ -242,7 +254,7 @@ static void find_export_symbols(char * filename) /* * Document all external or internal functions in a file. * Call kernel-doc with following parameters: - * kernel-doc -docbook -nofunction function_name1 filename + * kernel-doc [-docbook|-rst] -nofunction function_name1 filename * Function names are obtained from all the src files * by find_export_symbols. * intfunc uses -nofunction @@ -263,7 +275,7 @@ static void docfunctions(char * filename, char * type) exit(1); } vec[idx++] = KERNELDOC; - vec[idx++] = DOCBOOK; + vec[idx++] = KERNELDOC_FORMAT; vec[idx++] = NODOCSECTIONS; for (i=0; i < symfilecnt; i++) { struct symfile * sym = &symfilelist[i]; @@ -275,7 +287,10 @@ static void docfunctions(char * filename, char * type) } vec[idx++] = filename; vec[idx] = NULL; - printf("\n", filename); + if (file_format == FORMAT_RST) + printf(".. %s\n", filename); + else + printf("\n", filename); exec_kernel_doc(vec); fflush(stdout); free(vec); @@ -294,7 +309,7 @@ static void singfunc(char * filename, char * line) int i, idx = 0; int startofsym = 1; vec[idx++] = KERNELDOC; - vec[idx++] = DOCBOOK; + vec[idx++] = KERNELDOC_FORMAT; vec[idx++] = SHOWNOTFOUND; /* Split line up in individual parameters preceded by FUNCTION */ @@ -343,7 +358,7 @@ static void docsect(char *filename, char *line) free(s); vec[0] = KERNELDOC; - vec[1] = DOCBOOK; + vec[1] = KERNELDOC_FORMAT; vec[2] = SHOWNOTFOUND; vec[3] = FUNCTION; vec[4] = line; @@ -448,8 +463,10 @@ static char *chomp(char *s) /* Return pointer to directive content, or NULL if not a directive. */ static char *is_directive(char *line) { - if (line[0] == '!') + if (file_format == FORMAT_DOCBOOK && line[0] == '!') return line + 1; + else if (file_format == FORMAT_RST && !strncmp(line, ".. !", 4)) + return line + 4; return NULL; } @@ -516,6 +533,22 @@ static void parse_file(FILE *infile) fflush(stdout); } +/* + * Is this a RestructuredText template? Answer the question by seeing if its + * name ends in ".rst". + */ +static int is_rst(const char *file) +{ + char *dot = strrchr(file, '.'); + + return dot && !strcmp(dot + 1, "rst"); +} + +enum opts { + OPT_DOCBOOK, + OPT_RST, + OPT_HELP, +}; int main(int argc, char *argv[]) { @@ -529,13 +562,50 @@ int main(int argc, char *argv[]) kernsrctree = getenv("KBUILD_SRC"); if (!kernsrctree || !*kernsrctree) kernsrctree = srctree; - if (argc != 3) { + + for (;;) { + int c; + struct option opts[] = { + { "docbook", no_argument, NULL, OPT_DOCBOOK }, + { "rst", no_argument, NULL, OPT_RST }, + { "help", no_argument, NULL, OPT_HELP }, + {} + }; + + c = getopt_long_only(argc, argv, "", opts, NULL); + if (c == -1) + break; + + switch (c) { + case OPT_DOCBOOK: + file_format = FORMAT_DOCBOOK; + break; + case OPT_RST: + file_format = FORMAT_RST; + break; + case OPT_HELP: + usage(); + return 0; + default: + case '?': + usage(); + return 1; + } + } + + argc -= optind; + argv += optind; + + if (argc != 2) { usage(); exit(1); } - subcommand = argv[1]; - filename = argv[2]; + subcommand = argv[0]; + filename = argv[1]; + + if (file_format == FORMAT_AUTO) + file_format = is_rst(filename) ? FORMAT_RST : FORMAT_DOCBOOK; /* Open file, exit on error */ infile = fopen(filename, "r"); -- cgit v1.2.3 From 0e95abf9be3108498128458ffb087209e0a1b5fa Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 May 2016 16:15:44 +0300 Subject: docproc: print a comment about autogeneration for rst output Leave a hint to folks which file to edit instead. Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/docproc.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts/docproc.c') diff --git a/scripts/docproc.c b/scripts/docproc.c index 9babfd108d2e..0a12593b9041 100644 --- a/scripts/docproc.c +++ b/scripts/docproc.c @@ -45,6 +45,7 @@ #include #include #include +#include /* exitstatus is used to keep track of any failing calls to kernel-doc, * but execution continues. */ @@ -616,6 +617,12 @@ int main(int argc, char *argv[]) } if (strcmp("doc", subcommand) == 0) { + if (file_format == FORMAT_RST) { + time_t t = time(NULL); + printf(".. generated from %s by docproc %s\n", + filename, ctime(&t)); + } + /* Need to do this in two passes. * First pass is used to collect all symbols exported * in the various files; -- cgit v1.2.3