mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sam Ravnborg <sam@ravnborg.org>
To: torvalds@transmeta.com, davej@suse.de
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] docbook: scripts/docproc improved [5/9]
Date: Wed, 24 Jul 2002 23:34:47 +0200	[thread overview]
Message-ID: <20020724233447.D12782@mars.ravnborg.org> (raw)
In-Reply-To: <20020724232021.A12622@mars.ravnborg.org>; from sam@ravnborg.org on Wed, Jul 24, 2002 at 11:20:21PM +0200

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.435   -> 1.436  
#	scripts/gen-all-syms	1.2     ->         (deleted)      
#	   scripts/docproc.c	1.2     -> 1.3    
#	      scripts/docgen	1.3     ->         (deleted)      
#	    scripts/Makefile	1.9     -> 1.10   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/07/24	sam@mars.ravnborg.org	1.436
# [PATCH] docbook: scripts/docproc improved [5/9]
# This is the first patch in a serie to clean-up the DocBook
# Makefile.
# docproc is extented to include the functionality previously provided by
# gen-all-syms and docgen. Furthermore the necessity to specify which
# files to search for EXPORT_SYMBOL are removed, the information is now
# read in the .tmpl files.
# docproc is furthermore extended to generate dependency information.
# gen-all-syms and docgen are deleted.
# --------------------------------------------
#
diff -Nru a/scripts/Makefile b/scripts/Makefile
--- a/scripts/Makefile	Wed Jul 24 22:52:07 2002
+++ b/scripts/Makefile	Wed Jul 24 22:52:07 2002
@@ -7,7 +7,7 @@
 # can't do it
 CHMOD_FILES := docgen gen-all-syms kernel-doc mkcompile_h makelst
 
-all: fixdep split-include $(CHMOD_FILES)
+all: fixdep split-include docproc $(CHMOD_FILES)
 
 $(CHMOD_FILES): FORCE
 	@chmod a+x $@
@@ -36,11 +36,6 @@
 	  cat $(TAIL)                                           \
 	) > $@
 	chmod 755 $@
-
-# DocBook stuff
-# ---------------------------------------------------------------------------
-
-doc-progs: docproc
 
 # ---------------------------------------------------------------------------
 
diff -Nru a/scripts/docgen b/scripts/docgen
--- a/scripts/docgen	Wed Jul 24 22:52:07 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,10 +0,0 @@
-#!/bin/sh
-set -e
-if [ -z "$scripts_objtree" ]
-then
-	X=`$TOPDIR/scripts/gen-all-syms "$*"`
-	$TOPDIR/scripts/docproc $X
-else
-	X=`${scripts_objtree}gen-all-syms "$*"`
-	TOPDIR=. ${scripts_objtree}docproc $X
-fi
diff -Nru a/scripts/docproc.c b/scripts/docproc.c
--- a/scripts/docproc.c	Wed Jul 24 22:52:07 2002
+++ b/scripts/docproc.c	Wed Jul 24 22:52:07 2002
@@ -1,104 +1,387 @@
+/*
+ *	docproc is a simple preprocessor for the template files
+ *      used as placeholders for the kernel internal documentation.
+ *	docproc is used for documentation-frontend and
+ *      dependency-generator.
+ *	The two usages have in common that they require
+ *	some knowledge of the .tmpl syntax, therefore they
+ *	are kept together.
+ *
+ *	documentation-frontend
+ *		Scans the template file and call kernel-doc for
+ *		all occurrences of ![EIF]file
+ *		Beforehand each referenced file are scanned for
+ *		any exported sympols "EXPORT_SYMBOL()" statements.
+ *		This is used to create proper -function and
+ *		-nofunction arguments in calls to kernel-doc.
+ *		Usage: docproc doc file.tmpl
+ *
+ *	dependency-generator:
+ *		Scans the template file and list all files
+ *		referenced in a format recognized by make.
+ *		Usage:	docproc depend file.tmpl
+ *		Writes dependency information to stdout
+ *		in the following format:
+ *		file.tmpl src.c	src2.c
+ *		The filenames are obtained from the following constructs:
+ *		!Efilename
+ *		!Ifilename
+ *		!Dfilename
+ *		!Ffilename
+ *		
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <unistd.h>
+#include <limits.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 
+/* exitstatus is used to keep track of any failing calls to kernel-doc,
+ * but execution continues. */
+int exitstatus = 0;
+
+typedef void DFL(char *);
+DFL *defaultline;
+
+typedef void FILEONLY(char * file);
+FILEONLY *internalfunctions;
+FILEONLY *externalfunctions;
+FILEONLY *symbolsonly;
+
+typedef void FILELINE(char * file, char * line);
+FILELINE * singlefunctions;
+FILELINE * entity_system;
+
+#define MAXLINESZ     2048
+#define MAXFILES      250
+#define KERNELDOCPATH "scripts/"
+#define KERNELDOC     "kernel-doc"
+#define DOCBOOK       "-docbook"
+#define FUNCTION      "-function"
+#define NOFUNCTION    "-nofunction"
+
+void usage (void)
+{
+	fprintf(stderr, "Usage: docproc {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");
+}
+
 /*
- *	A simple filter for the templates
+ * Execute kernel-doc with parameters givin in svec
  */
+void exec_kernel_doc(char **svec)
+{
+	pid_t pid;
+	int ret;
+	/* Make sure output generated so far are flushed */
+	fflush(stdout);
+	switch(pid=fork()) {
+		case -1:
+			perror("fork");
+			exit(1);
+		case  0:
+			execvp(KERNELDOCPATH KERNELDOC, svec);
+			perror("exec " KERNELDOCPATH KERNELDOC);
+			exit(1);
+		default:
+			waitpid(pid, &ret ,0);
+	}
+	if (WIFEXITED(ret))
+		exitstatus = WEXITSTATUS(ret);
+	else
+		exitstatus = 0xff;
+}
 
-int main(int argc, char *argv[])
+/* Types used to create list of all exported symbols in a number of files */
+struct symbols
+{
+	char *name;
+};
+
+struct symfile
+{
+	char *filename;
+	struct symbols *symbollist;
+	int symbolcnt;
+};
+
+struct symfile symfilelist[MAXFILES];
+int symfilecnt = 0;
+
+void add_new_symbol(struct symfile *sym, char * symname)
+{
+	sym->symbollist =
+          realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+	sym->symbollist[sym->symbolcnt++].name = strdup(symname);
+}
+
+/* Add a filename to the list */
+struct symfile * add_new_file(char * filename)
+{
+	symfilelist[symfilecnt++].filename = strdup(filename);
+	return &symfilelist[symfilecnt - 1];					
+}
+/* Check if file already are present in the list */
+struct symfile * filename_exist(char * filename)
 {
-	char buf[1024];
-	char *vec[8192];
-	char *fvec[200];
-	char **svec;
-	char type[64];
 	int i;
-	int vp=2;
-	int ret=0;
-	pid_t pid;
+	for (i=0; i < symfilecnt; i++)
+		if (strcmp(symfilelist[i].filename, filename) == 0)
+			return &symfilelist[i];
+	return NULL;
+}
 
+/*
+ * List all files referenced within the template file.
+ * Files are separated by tabs.
+ */
+void adddep(char * file)		   { printf("\t%s", file); }
+void adddep2(char * file, char * line)     { line = line; adddep(file); }
+void noaction(char * line)		   { line = line; }
+void noaction2(char * file, char * line)   { file = file; line = line; }
 
-	if(chdir(getenv("TOPDIR")))
-	{
-		perror("chdir");
-		exit(1);
+/* Echo the line without further action */
+void printline(char * line)               { printf("%s", line); }
+
+/* 
+ * Find all symbols exported with EXPORT_SYMBOL and EXPORT_SYMBOL_GPL 
+ * in filename.
+ * All symbols located are stored in symfilelist.
+ */
+void find_export_symbols(char * filename)
+{
+	FILE * fp;
+	struct symfile *sym;
+	char line[MAXLINESZ];
+	if (filename_exist(filename) == NULL) {
+		sym = add_new_file(filename);
+		fp = fopen(filename, "r");
+		if (fp == NULL)
+		{
+			fprintf(stderr, "docproc: ");
+			perror(filename);
+		}
+		while(fgets(line, MAXLINESZ, fp)) {
+			char *p;
+			char *e;
+			if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
+                            ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) {
+				/* Skip EXPORT_SYMBOL{_GPL} */
+				while (isalnum(*p) || *p == '_')
+					p++;
+				/* Remove paranteses and additional ws */
+				while (isspace(*p))
+					p++;
+				if (*p != '(')
+					continue; /* Syntax error? */
+				else
+					p++;
+				while (isspace(*p))
+					p++;
+				e = p;
+				while (isalnum(*e) || *e == '_')
+					e++;
+				*e = '\0';
+				add_new_symbol(sym, p);
+			}
+		}
+		fclose(fp);
 	}
+}
+
+/*
+ * Document all external or internal functions in a file.
+ * Call kernel-doc with following parameters:
+ * kernel-doc -docbook -nofunction function_name1 filename
+ * function names are obtained from all the the src files
+ * by find_export_symbols.
+ * intfunc uses -nofunction
+ * extfunc uses -function
+ */
+void docfunctions(char * filename, char * type)
+{
+	int i,j;
+	int symcnt = 0;
+	int idx = 0;
+	char **vec;
 	
-	/*
-	 *	Build the exec array ahead of time.
-	 */
-	vec[0]="kernel-doc";
-	vec[1]="-docbook";
-	for(i=1;vp<8189;i++)
-	{
-		if(argv[i]==NULL)
-			break;
-		vec[vp++]=type;
-		vec[vp++]=argv[i];
+	for (i=0; i <= symfilecnt; i++)
+		symcnt += symfilelist[i].symbolcnt;
+	vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*));
+	if (vec == NULL) {
+		perror("docproc: ");
+		exit(1);
 	}
-	vec[vp++]=buf+2;
-	vec[vp++]=NULL;
-	
-	/*
-	 *	Now process the template
-	 */
-	 
-	while(fgets(buf, 1024, stdin))
-	{
-		if(*buf!='!') {
-			printf("%s", buf);
-			continue;
+	vec[idx++] = KERNELDOC;
+	vec[idx++] = DOCBOOK;
+	for (i=0; i < symfilecnt; i++) {
+		struct symfile * sym = &symfilelist[i];
+		for (j=0; j < sym->symbolcnt; j++) {
+			vec[idx++]     = type;
+			vec[idx++] = sym->symbollist[j].name;
 		}
+	}
+	vec[idx++]     = filename;
+	vec[idx] = NULL;
+	printf("<!-- %s -->\n", filename);
+	exec_kernel_doc(vec);
+	fflush(stdout);
+	free(vec);
+}
+void intfunc(char * filename) {	docfunctions(filename, NOFUNCTION); }
+void extfunc(char * filename) { docfunctions(filename, FUNCTION);   }
 
-		fflush(stdout);
-		svec = vec;
-		if(buf[1]=='E')
-			strcpy(type, "-function");
-		else if(buf[1]=='I')
-			strcpy(type, "-nofunction");	
-		else if(buf[1]=='F') {
-			int snarf = 0;
-			fvec[0] = "kernel-doc";
-			fvec[1] = "-docbook";
-			strcpy (type, "-function");
-			vp = 2;
-			for (i = 2; buf[i]; i++) {
-				if (buf[i] == ' ' || buf[i] == '\n') {
-					buf[i] = '\0';
-					snarf = 1;
-					continue;
-				}
-
-				if (snarf) {
-					snarf = 0;
-					fvec[vp++] = type;
-					fvec[vp++] = &buf[i];
-				}
+/*
+ * Document spåecific function(s) in a file.
+ * Call kernel-doc with the following parameters:
+ * kernel-doc -docbook -function function1 [-function function2]
+ */
+void singfunc(char * filename, char * line)
+{
+	char *vec[200]; /* Enough for specific functions */
+        int i, idx = 0;
+        int startofsym = 1;
+	vec[idx++] = KERNELDOC;
+	vec[idx++] = DOCBOOK;
+
+        /* Split line up in individual parameters preceeded by FUNCTION */        
+        for (i=0; line[i]; i++) {
+                if (isspace(line[i])) {
+                        line[i] = '\0';
+                        startofsym = 1;
+                        continue;
+                }
+                if (startofsym) {
+                        startofsym = 0;
+                        vec[idx++] = FUNCTION;
+                        vec[idx++] = &line[i];
+                }
+        }
+	vec[idx++] = filename;
+	vec[idx] = NULL;
+	exec_kernel_doc(vec);
+}
+
+/*
+ * Parse file, calling action specific functions for:
+ * 1) Lines containing !E
+ * 2) Lines containing !I
+ * 3) Lines containing !D
+ * 4) Lines containing !F
+ * 5) Default lines - lines not matching the above
+ */
+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;
+				default:
+					defaultline(line);
 			}
-			fvec[vp++] = &buf[2];
-			fvec[vp] = NULL;
-			svec = fvec;
-		} else
-		{
-			fprintf(stderr, "Unknown ! escape.\n");
-			exit(1);
 		}
-		switch(pid=fork())
-		{
-		case -1:
-			perror("fork");
-			exit(1);
-		case  0:
-			execvp("scripts/kernel-doc", svec);
-			perror("exec scripts/kernel-doc");
-			exit(1);
-		default:
-			waitpid(pid, &ret ,0);
+		else {
+			defaultline(line);
 		}
 	}
-	exit(ret);
+	fflush(stdout);
 }
+		
+
+int main(int argc, char *argv[])
+{
+	FILE * infile;
+	if (argc != 3) {
+		usage();
+		exit(1);
+	}
+	/* Open file, exit on error */
+	infile = fopen(argv[2], "r");
+        if (infile == NULL) {
+                fprintf(stderr, "docproc: ");
+                perror(argv[2]);
+                exit(2);
+        }
+
+	if (strcmp("doc", argv[1]) == 0)
+	{
+		/* Need to do this in two passes.
+		 * First pass is used to collect all symbols exported
+		 * in the various files.
+		 * Second pass generate the documentation.
+		 * This is required because function are declared
+		 * and exported in different files :-((
+		 */
+		/* Collect symbols */
+		defaultline       = noaction;
+		internalfunctions = find_export_symbols;
+		externalfunctions = find_export_symbols;
+		symbolsonly       = find_export_symbols;
+		singlefunctions   = noaction2;
+		parse_file(infile);
+
+		/* Rewind to start from beginning of file again */
+		fseek(infile, 0, SEEK_SET);
+		defaultline       = printline;
+		internalfunctions = intfunc;
+		externalfunctions = extfunc;
+		symbolsonly       = printline;
+		singlefunctions   = singfunc;
+		
+		parse_file(infile);
+	}
+	else if (strcmp("depend", argv[1]) == 0)
+	{
+		/* Create first part of dependency chain
+		 * file.tmpl */
+		printf("%s\t", argv[2]);
+		defaultline       = noaction;
+		internalfunctions = adddep;
+		externalfunctions = adddep;
+		symbolsonly       = adddep;
+		singlefunctions   = adddep2;
+		parse_file(infile);
+		printf("\n");
+	}
+	else
+	{
+		fprintf(stderr, "Unknown option: %s\n", argv[1]);
+		exit(1);
+	}
+	fclose(infile);
+	fflush(stdout);
+	return exitstatus;
+}
+
diff -Nru a/scripts/gen-all-syms b/scripts/gen-all-syms
--- a/scripts/gen-all-syms	Wed Jul 24 22:52:07 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,7 +0,0 @@
-#!/bin/sh
-for i in $*
-do
-	grep "EXPORT_SYMBOL.*(.*)" "$i" \
-		| sed -e "s/EXPORT_SYMBOL.*(/  /" \
-		| sed -e "s/).*$//" | sed -e "s/^  //"
-done

  parent reply	other threads:[~2002-07-24 21:24 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-24 21:20 [PATCH] Made 'make sgmldocs' work again after serial merge [1/9] Sam Ravnborg
2002-07-24 21:31 ` [PATCH] kernel-doc: Improved support for man-page generation [2/9] Sam Ravnborg
2002-07-24 21:32 ` [PATCH] kernel-doc: Generate valid DocBook syntax [3/9] Sam Ravnborg
2002-07-24 21:33 ` [PATCH] kernel-doc: Fix warnings [4/9] Sam Ravnborg
2002-07-24 21:34 ` Sam Ravnborg [this message]
2002-07-24 21:36 ` [PATCH] docbook: Makefile cleanup [6/9] Sam Ravnborg
2002-07-24 21:37 ` [PATCH] docbook: Update documentation to reflect new docproc [7/9] Sam Ravnborg
2002-07-24 21:38 ` [PATCH] docbook: Move script target in top-level file [8/9] Sam Ravnborg
2002-07-24 21:39 ` [PATCH] docbook: Call docbook makefile with -f [9/9] Sam Ravnborg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020724233447.D12782@mars.ravnborg.org \
    --to=sam@ravnborg.org \
    --cc=davej@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®