Index: doc/tools/src2html1.4a/Ctags/C.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/C.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/C.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)C.c	5.5 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "ctags.h"
+
+static int func_entry(), str_entry();
+static void hash_entry();
+
+/*
+ * c_entries --
+ *	read .c and .h files and call appropriate routines
+ */
+c_entries()
+{
+	extern int	tflag;		/* -t: create tags for typedefs */
+	register int	c,		/* current character */
+			level;		/* brace level */
+	register char	*sp;		/* buffer pointer */
+	int	token,			/* if reading a token */
+		t_def,			/* if reading a typedef */
+		t_level;		/* typedef's brace level */
+	char	tok[MAXTOKEN];		/* token buffer */
+	int	st;			/* Symbol type */
+	int	rparen;			/* State of last rparen */
+
+	lineftell = ftell(inf);
+	sp = tok; token = t_def = NO; t_level = -1; level = 0; lineno = 1;
+	rparen=0;
+	while (GETC(!=,EOF)) {
+	rparen--;
+	switch ((char)c) {
+		/*
+		 * Here's where it DOESN'T handle:
+		 *	foo(a)
+		 *	{
+		 *	#ifdef notdef
+		 *		}
+		 *	#endif
+		 *		if (a)
+		 *			puts("hello, world");
+		 *	}
+		 */
+		case '{':
+			++level;
+			goto endtok;
+		case '}':
+			/*
+			 * if level goes below zero, try and fix
+			 * it, even though we've already messed up
+			 */
+			if (--level < 0)
+				level = 0;
+			goto endtok;
+
+		case '\n':
+			SETLINE;
+			/*
+			 * the above 3 cases are similar in that they
+			 * are special characters that also end tokens.
+			 */
+endtok:			if (sp > tok) {
+				*sp = EOS;
+				token = YES;
+				sp = tok;
+			}
+			else
+				token = NO;
+			continue;
+
+		/* we ignore quoted strings and comments in their entirety */
+		case '"':
+		case '\'':
+			(void)skip_key(c);
+			break;
+		/* We ignore everything between [] */
+		case '[':
+			(void)skip_key(']');
+			goto storec;
+
+		/*
+		 * comments can be fun; note the state is unchanged after
+		 * return, in case we found:
+		 *	"foo() XX comment XX { int bar; }"
+		 */
+		case '/':
+			if (GETC(==,'*')) {
+				skip_comment();
+				continue;
+			}
+			(void)ungetc(c,inf);
+			c = '/';
+			goto storec;
+
+		/* hash marks flag #define's. */
+		case '#':
+			if (sp == tok) {
+				hash_entry();
+				break;
+			}
+			goto storec;
+
+		/*
+	 	 * if we have a current token, parenthesis on
+		 * level zero indicates a function.
+		 */
+		case '(':
+			if (!level && token) {
+				int	curline;
+
+				if (sp != tok)
+					*sp = EOS;
+				/*
+				 * grab the line immediately, we may
+				 * already be wrong, for example,
+				 *	foo\n
+				 *	(arg1,
+				 */
+				getline();
+				curline = lineno;
+				if (func_entry()) {
+					++level;
+					pfnote(tok,curline,SY_FUN);
+				} else rparen=2;
+				break;
+			}
+			goto storec;
+
+		/*
+		 * semi-colons indicate the end of a typedef; if we find a
+		 * typedef we search for the next semi-colon of the same
+		 * level as the typedef.  Ignoring "structs", they are
+		 * tricky, since you can find:
+		 *
+		 *	"typedef long time_t;"
+		 *	"typedef unsigned int u_int;"
+		 *	"typedef unsigned int u_int [10];"
+		 *
+		 * If looking at a typedef, we save a copy of the last token
+		 * found.  Then, when we find the ';' we take the current
+		 * token if it starts with a valid token name, else we take
+		 * the one we saved.  There's probably some reasonable
+		 * alternative to this...
+		 */
+		case ';':
+			if (t_def && level == t_level) {
+				t_def = NO;
+				getline();
+				if (sp != tok)
+					*sp = EOS;
+				pfnote(tok,lineno,SY_TYP);
+				break;
+			}
+		/*
+		 * Catch global variables by the fact that they end in ; or ,
+		 * and they are at level zero.
+		 */
+		case ',':
+			if (sp != tok) *sp = EOS;
+			if (level==0 && rparen!=1) {
+				pfnote(tok,lineno,SY_VAR);
+				break;
+			}
+			goto storec;
+
+		/*
+		 * store characters until one that can't be part of a token
+		 * comes along; check the current token against certain
+		 * reserved words.
+		 */
+		default:
+storec:			if (!intoken(c)) {
+				if (sp == tok)
+					break;
+				*sp = EOS;
+				if (tflag) {
+					/* no typedefs inside typedefs */
+					if (!t_def && !bcmp(tok,"typedef",8)) {
+						t_def = YES;
+						t_level = level;
+						break;
+					}
+					/* catch "typedef struct" */
+					if ((!t_def || t_level < level)
+					    && (!bcmp(tok,"struct",7)
+					    || !bcmp(tok,"union",6)
+					    || !bcmp(tok,"enum",5))) {
+						/* Get type of symbol */
+						st=0;
+						switch (*tok) {
+						 case 's' : st= SY_STR; break;
+						 case 'u' : st= SY_UNI; break;
+						 case 'e' : st= SY_ENU; break;
+						}
+						/*
+						 * get line immediately;
+						 * may change before '{'
+						 */
+						getline();
+						if (str_entry(c,st))
+							++level;
+						break;
+					}
+				}
+				sp = tok;
+			}
+			else if (sp != tok || begtoken(c)) {
+				*sp++ = c;
+				token = YES;
+			}
+			continue;
+		}
+		sp = tok;
+		token = NO;
+	}
+}
+
+/*
+ * func_entry --
+ *	handle a function reference
+ */
+static
+func_entry()
+{
+	register int	c;		/* current character */
+
+	/*
+	 * we assume that the character after a function's right paren
+	 * is a token character if it's a function and a non-token
+	 * character if it's a declaration.  Comments don't count...
+	 */
+	(void)skip_key((int)')');
+	for (;;) {
+		while (GETC(!=,EOF) && iswhite(c))
+			if (c == (int)'\n')
+				SETLINE;
+		if (intoken(c) || c == (int)'{')
+			break;
+		if (c == (int)'/' && GETC(==,'*'))
+			skip_comment();
+		else {				/* don't ever "read" '/' */
+			(void)ungetc(c,inf);
+			return(NO);
+		}
+	}
+	if (c != (int)'{')
+		(void)skip_key((int)'{');
+	return(YES);
+}
+
+/*
+ * hash_entry --
+ *	handle a line starting with a '#'
+ */
+static void
+hash_entry()
+{
+	extern int	dflag;		/* -d: non-macro defines */
+	register int	c,		/* character read */
+			curline;	/* line started on */
+	register char	*sp;		/* buffer pointer */
+	char	tok[MAXTOKEN];		/* storage buffer */
+
+	curline = lineno;
+	for (sp = tok;;) {		/* get next token */
+		if (GETC(==,EOF))
+			return;
+		if (iswhite(c))
+			break;
+		*sp++ = c;
+	}
+	*sp = EOS;
+	if (bcmp(tok,"define",6))	/* only interested in #define's */
+		goto skip;
+	for (;;) {			/* this doesn't handle "#define \n" */
+		if (GETC(==,EOF))
+			return;
+		if (!iswhite(c))
+			break;
+	}
+	for (sp = tok;;) {		/* get next token */
+		*sp++ = c;
+		if (GETC(==,EOF))
+			return;
+		/*
+		 * this is where it DOESN'T handle
+		 * "#define \n"
+		 */
+		if (!intoken(c))
+			break;
+	}
+	*sp = EOS;
+	if (dflag || c == (int)'(') {	/* only want macros */
+		getline();
+		if (c == (int)'(') pfnote(tok,curline,SY_MAC);
+		else pfnote(tok,curline,SY_DEF);
+	}
+skip:	if (c == (int)'\n') {		/* get rid of rest of define */
+		SETLINE
+		if (*(sp - 1) != '\\')
+			return;
+	}
+	(void)skip_key((int)'\n');
+}
+
+/*
+ * str_entry --
+ *	handle a struct, union or enum entry
+ */
+static
+str_entry(c,st)
+	register int	c;		/* current character */
+	int	st;			/* type of symbol */
+{
+	register char	*sp;		/* buffer pointer */
+	int	curline;		/* line started on */
+	char	tok[BUFSIZ];		/* storage buffer */
+
+	curline = lineno;
+	while (iswhite(c))
+		if (GETC(==,EOF))
+			return(NO);
+	if (c == (int)'{')		/* it was "struct {" */
+		return(YES);
+	for (sp = tok;;) {		/* get next token */
+		*sp++ = c;
+		if (GETC(==,EOF))
+			return(NO);
+		if (!intoken(c))
+			break;
+	}
+	switch ((char)c) {
+		case '{':		/* it was "struct foo{" */
+			--sp;
+			break;
+		case '\n':		/* it was "struct foo\n" */
+			SETLINE;
+			/*FALLTHROUGH*/
+		default:		/* probably "struct foo " */
+			while (GETC(!=,EOF))
+				if (!iswhite(c))
+					break;
+			if (c != (int)'{') {
+				(void)ungetc(c, inf);
+				return(NO);
+			}
+	}
+	*sp = EOS;
+	pfnote(tok,curline,st);
+	return(YES);
+}
+
+/*
+ * skip_comment --
+ *	skip over comment
+ */
+skip_comment()
+{
+	register int	c,		/* character read */
+			star;		/* '*' flag */
+
+	for (star = 0;GETC(!=,EOF);)
+		switch((char)c) {
+			/* comments don't nest, nor can they be escaped. */
+			case '*':
+				star = YES;
+				break;
+			case '/':
+				if (star)
+					return;
+				break;
+			case '\n':
+				SETLINE;
+				/*FALLTHROUGH*/
+			default:
+				star = NO;
+		}
+}
+
+/*
+ * skip_key --
+ *	skip to next char "key"
+ */
+skip_key(key)
+	register int	key;
+{
+	register int	c,
+			skip,
+			retval;
+
+	for (skip = retval = NO;GETC(!=,EOF);)
+		switch((char)c) {
+		case '\\':		/* a backslash escapes anything */
+			skip = !skip;	/* we toggle in case it's "\\" */
+			break;
+		case ';':		/* special case for yacc; if one */
+		case '|':		/* of these chars occurs, we may */
+			retval = YES;	/* have moved out of the rule */
+			break;		/* not used by C */
+		case '\n':
+			SETLINE;
+			/*FALLTHROUGH*/
+		default:
+			if (c == key && !skip)
+				return(retval);
+			skip = NO;
+		}
+	return(retval);
+}
Index: doc/tools/src2html1.4a/Ctags/Makefile
===================================================================
--- doc/tools/src2html1.4a/Ctags/Makefile	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/Makefile	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,12 @@
+#	@(#)Makefile	5.6 (Berkeley) 5/11/90
+
+PROG=	ctags-new
+CFLAGS+=-I.
+SRCS=	C.c ctags.c fortran.c lisp.c print.c tree.c yacc.c strerror.c
+
+ctags: C.o ctags.o fortran.o lisp.o print.o tree.o yacc.o strerror.o
+	cc -o ctags-new C.o ctags.o fortran.o lisp.o print.o tree.o yacc.o \
+	strerror.o
+
+clean:
+	rm -f *.o ctags-new
Index: doc/tools/src2html1.4a/Ctags/ctags.1
===================================================================
--- doc/tools/src2html1.4a/Ctags/ctags.1	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/ctags.1	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,225 @@
+.\" Ctags-new is a modified version of the ctags produced by UCB and
+.\" distributed in their BSD distributions.
+.\" You should be able to diff this version against theirs to see what I
+.\" have changed.
+.\" 	Warren Toomey
+.\"
+.\" Copyright (c) 1987, 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)ctags.1	6.8 (Berkeley) 4/24/91
+.\"
+.Dd April 24, 1991
+.Dt CTAGS 1
+.Os BSD 4
+.Sh NAME
+.Nm ctags-new
+.Nd create a tags file
+.Sh SYNOPSIS
+.Nm ctags-new
+.Op Fl BFadtuwvx
+.Op Fl f Ar tagsfile
+.Ar name ...
+.Sh DESCRIPTION
+.Nm Ctags-new
+makes a tags file for
+.Xr ex 1
+from the specified C,
+Pascal, Fortran,
+.Tn YACC ,
+lex, and lisp sources.  A tags file gives the
+locations of specified objects in a group of files.  Each line of the
+tags file contains the object name, the file in which it is defined,
+and a search pattern for the object definition, separated by white-space.
+Using the
+.Ar tags
+file,
+.Xr ex 1
+can quickly locate these object
+definitions.  Depending on the options provided to
+.Nm ctags-new ,
+objects will consist of subroutines, typedefs, defines, structs,
+enums and unions.
+.Bl -tag -width Ds
+.It Fl B
+use backward searching patterns
+.Pq Li ?...? .
+.It Fl F
+use forward searching patterns
+.Pq Li /.../
+(the default).
+.It Fl a
+append to
+.Ar tags
+file.
+.It Fl d
+create tags for
+.Li #defines
+that don't take arguments;
+.Li #defines
+that take arguments are tagged automatically.
+.It Fl f
+Places the tag descriptions in a file called
+.Ar tagsfile .
+The default behaviour is to place them in a file
+.Ar tags .
+.It Fl t
+create tags for typedefs, structs, unions, and enums.
+.It Fl u
+update the specified files in the
+.Ar tags
+file, that is, all
+references to them are deleted, and the new values are appended to the
+file.  (Beware: this option is implemented in a way which is rather
+slow; it is usually faster to simply rebuild the
+.Ar tags
+file.)
+.It Fl v
+An index of the form expected by
+.Xr vgrind 1
+is produced on the standard output.  This listing
+contains the object name, file name, and page number (assuming 64
+line pages).  Since the output will be sorted into lexicographic order,
+it may be desired to run the output through
+.Xr sort 1 .
+Sample use:
+.Bd -literal -offset indent
+ctags-new \-v files \&| sort \-f > index
+vgrind \-x index
+.Ed
+.It Fl y
+Yet another output format. This produces lines with the information:
+symbol, line number, file name, type of symbol, each separated by whitespace.
+This is used by the
+.Xr src2html 1L
+program.
+.It Fl w
+suppress warning diagnostics.
+.It Fl x
+.Nm ctags-new
+produces a list of object
+names, the line number and file name on which each is defined, as well
+as the text of that line and prints this on the standard output.  This
+is a simple index which can be printed out as an off-line readable
+function index.
+.El
+.Pp
+Files whose names end in
+.Nm \&.c
+or
+.Nm \&.h
+are assumed to be C
+source files and are searched for C style routine and macro definitions.
+Files whose names end in
+.Nm \&.y
+are assumed to be
+.Tn YACC
+source files.
+Files whose names end in
+.Nm \&.l
+are assumed to be lisp files if their
+first non-blank character is `;', `(', or `[',
+otherwise, they are
+treated as lex files.  Other files are first examined to see if they
+contain any Pascal or Fortran routine definitions, and, if not, are
+searched for C style definitions.
+.Pp
+The tag
+.Li main
+is treated specially in C programs.  The tag formed
+is created by prepending
+.Ar M
+to the name of the file, with the
+trailing
+.Nm \&.c
+and any leading pathname components removed.  This
+makes use of
+.Nm ctags-new
+practical in directories with more than one
+program.
+.Pp
+Yacc and lex files each have a special tag.
+.Ar Yyparse
+is the start
+of the second section of the yacc file, and
+.Ar yylex
+is the start of
+the second section of the lex file.
+.Sh FILES
+.Bl -tag -width tags -compact
+.It Pa tags
+default output tags file
+.El
+.Sh DIAGNOSTICS
+.Nm Ctags-new
+exits with a value of 1 if an error occurred, where
+duplicate objects are not considered errors, 0 otherwise.
+.Sh SEE ALSO
+.Xr ex 1 ,
+.Xr vi 1
+.Sh BUGS
+Recognition of
+.Nm functions  ,
+.Nm subroutines
+and
+.Nm procedures
+for
+.Tn FORTRAN
+and Pascal is done is a very simpleminded way.  No attempt
+is made to deal with block structure; if you have two Pascal procedures
+in different blocks with the same name you lose.
+.Nm Ctags-new
+doesn't
+understand about Pascal types.
+.Pp
+The method of deciding whether to look for C, Pascal or
+.Tn FORTRAN
+functions is a hack.
+.Pp
+.Nm Ctags-new
+relies on the input being well formed, and any syntactical
+errors will completely confuse it.  It also finds some legal syntax
+confusing; for example, as it doesn't understand
+.Li #ifdef Ns 's ,
+(incidentally, that's a feature, not a bug) any code with unbalanced
+braces inside
+.Li #ifdef Ns 's
+will cause it to become somewhat disoriented.
+In a similar fashion, multiple line changes within a definition will
+cause it to enter the last line of the object, rather than the first, as
+the searching pattern.  The last line of multiple line
+.Li typedef Ns 's
+will similarly be noted.
+.Sh HISTORY
+The
+.Nm
+command appeared in 
+.Bx 3.0 .
Index: doc/tools/src2html1.4a/Ctags/ctags.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/ctags.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/ctags.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1987 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)ctags.c	5.8 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "ctags.h"
+
+/*
+ * ctags: create a tags file
+ */
+
+NODE	*head;			/* head of the sorted binary tree */
+
+				/* boolean "func" (see init()) */
+bool	_wht[0177],_etk[0177],_itk[0177],_btk[0177],_gd[0177];
+
+FILE	*inf,			/* ioptr for current input file */
+	*outf;			/* ioptr for tags file */
+
+long	lineftell;		/* ftell after getc( inf ) == '\n' */
+
+int	lineno,			/* line number of current line */
+	dflag,			/* -d: non-macro defines */
+	tflag,			/* -t: create tags for typedefs */
+	wflag,			/* -w: suppress warnings */
+	vflag,			/* -v: vgrind style index output */
+	xflag,			/* -x: cxref style output */
+	yflag;			/* -y: yet another style output */
+
+char	*curfile,		/* current input file name */
+	searchar = '/',		/* use /.../ searches by default */
+	lbuf[BUFSIZ];
+
+main(argc,argv)
+	int	argc;
+	char	**argv;
+{
+	extern char	*optarg;		/* getopt arguments */
+	extern int	optind;
+	static char	*outfile = "tags";	/* output file */
+	int	aflag,				/* -a: append to tags */
+		uflag,				/* -u: update tags */
+		exit_val,			/* exit value */
+		step,				/* step through args */
+		ch;				/* getopts char */
+	char	cmd[100];			/* too ugly to explain */
+
+	aflag = uflag = NO;
+	while ((ch = getopt(argc,argv,"BFadf:tuwvxy")) != EOF)
+		switch((char)ch) {
+			case 'B':
+				searchar = '?';
+				break;
+			case 'F':
+				searchar = '/';
+				break;
+			case 'a':
+				aflag++;
+				break;
+			case 'd':
+				dflag++;
+				break;
+			case 'f':
+				outfile = optarg;
+				break;
+			case 't':
+				tflag++;
+				break;
+			case 'u':
+				uflag++;
+				break;
+			case 'w':
+				wflag++;
+				break;
+			case 'v':
+				vflag++;
+			case 'x':
+				xflag++;
+				break;
+			case 'y':
+				yflag++;
+				break;
+			case '?':
+			default:
+				goto usage;
+		}
+	argv += optind;
+	argc -= optind;
+	if (!argc) {
+usage:		puts("Usage: ctags [-BFadtuwvx] [-f tagsfile] file ...");
+		exit(1);
+	}
+
+	init();
+
+	for (exit_val = step = 0;step < argc;++step)
+		if (!(inf = fopen(argv[step],"r"))) {
+			perror(argv[step]);
+			exit_val = 1;
+		}
+		else {
+			curfile = argv[step];
+			find_entries(argv[step]);
+			(void)fclose(inf);
+		}
+
+	if (head)
+		if (xflag)
+			put_entries(head);
+		else {
+			if (uflag) {
+				for (step = 0;step < argc;step++) {
+					(void)sprintf(cmd,"mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",outfile,argv[step],outfile);
+					system(cmd);
+				}
+				++aflag;
+			}
+			if (!(outf = fopen(outfile, aflag ? "a" : "w"))) {
+				perror(outfile);
+				exit(exit_val);
+			}
+			put_entries(head);
+			(void)fclose(outf);
+			if (uflag) {
+				(void)sprintf(cmd,"sort %s -o %s",outfile,outfile);
+				system(cmd);
+			}
+		}
+	exit(exit_val);
+}
+
+/*
+ * init --
+ *	this routine sets up the boolean psuedo-functions which work by
+ *	setting boolean flags dependent upon the corresponding character.
+ *	Every char which is NOT in that string is false with respect to
+ *	the pseudo-function.  Therefore, all of the array "_wht" is NO
+ *	by default and then the elements subscripted by the chars in
+ *	CWHITE are set to YES.  Thus, "_wht" of a char is YES if it is in
+ *	the string CWHITE, else NO.
+ */
+init()
+{
+	register int	i;
+	register char	*sp;
+
+	for (i = 0; i < 0177; i++) {
+		_wht[i] = _etk[i] = _itk[i] = _btk[i] = NO;
+		_gd[i] = YES;
+	}
+#define	CWHITE	" \f\t\n"
+	for (sp = CWHITE; *sp; sp++)	/* white space chars */
+		_wht[*sp] = YES;
+#define	CTOKEN	" \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?"
+	for (sp = CTOKEN; *sp; sp++)	/* token ending chars */
+		_etk[*sp] = YES;
+#define	CINTOK	"ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789"
+	for (sp = CINTOK; *sp; sp++)	/* valid in-token chars */
+		_itk[*sp] = YES;
+#define	CBEGIN	"ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+	for (sp = CBEGIN; *sp; sp++)	/* token starting chars */
+		_btk[*sp] = YES;
+#define	CNOTGD	",;"
+	for (sp = CNOTGD; *sp; sp++)	/* invalid after-function chars */
+		_gd[*sp] = NO;
+}
+
+/*
+ * find_entries --
+ *	this routine opens the specified file and calls the function
+ *	which searches the file.
+ */
+find_entries(file)
+	char	*file;
+{
+	register char	*cp;
+
+	lineno = 0;				/* should be 1 ?? KB */
+	if (cp = rindex(file, '.')) {
+		if (cp[1] == 'l' && !cp[2]) {
+			register int	c;
+
+			for (;;) {
+				if (GETC(==,EOF))
+					return;
+				if (!iswhite(c)) {
+					rewind(inf);
+					break;
+				}
+			}
+#define	LISPCHR	";(["
+/* lisp */		if (index(LISPCHR,(char)c)) {
+				l_entries();
+				return;
+			}
+/* lex */		else {
+				/*
+				 * we search all 3 parts of a lex file
+				 * for C references.  This may be wrong.
+				 */
+				toss_yysec();
+				(void)strcpy(lbuf,"%%$");
+				pfnote("yylex",lineno);
+				rewind(inf);
+			}
+		}
+/* yacc */	else if (cp[1] == 'y' && !cp[2]) {
+			/*
+			 * we search only the 3rd part of a yacc file
+			 * for C references.  This may be wrong.
+			 */
+			toss_yysec();
+			(void)strcpy(lbuf,"%%$");
+			pfnote("yyparse",lineno);
+			y_entries();
+		}
+/* fortran */	else if ((cp[1] != 'c' && cp[1] != 'h') && !cp[2]) {
+			if (PF_funcs())
+				return;
+			rewind(inf);
+		}
+	}
+/* C */	c_entries();
+}
Index: doc/tools/src2html1.4a/Ctags/ctags.h
===================================================================
--- doc/tools/src2html1.4a/Ctags/ctags.h	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/ctags.h	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ctags.h	5.4 (Berkeley) 2/26/91
+ */
+
+#include <strings.h>
+#define	bool	char
+
+#define	YES		1
+#define	NO		0
+#define	EOS		'\0'
+
+#define	ENDLINE		50		/* max length of pattern */
+#define	MAXTOKEN	250		/* max size of single token */
+
+#define	SETLINE		{++lineno;lineftell = ftell(inf);}
+#define	GETC(op,exp)	((c = getc(inf)) op (int)exp)
+
+#define	iswhite(arg)	(_wht[arg])	/* T if char is white */
+#define	begtoken(arg)	(_btk[arg])	/* T if char can start token */
+#define	intoken(arg)	(_itk[arg])	/* T if char can be in token */
+#define	endtoken(arg)	(_etk[arg])	/* T if char ends tokens */
+#define	isgood(arg)	(_gd[arg])	/* T if char can be after ')' */
+
+					/* Symbol types */
+#define SY_MAC	1			/* Preprocessor Macros */
+#define SY_DEF	2			/* Preprocessor Defines */
+#define SY_FUN	3			/* C Functions */
+#define SY_VAR	4			/* C Variables */
+#define SY_STR	5			/* C Structs */
+#define SY_UNI	6			/* C Unions */
+#define SY_TYP	7			/* C Typedefs */
+#define SY_ENU	8			/* C Enums */
+
+typedef struct nd_st {			/* sorting structure */
+	struct nd_st	*left,
+			*right;		/* left and right sons */
+	char	*entry,			/* function or type name */
+		*file,			/* file name */
+		*pat;			/* search pattern */
+	int	symbtype;		/* Type of symbol */
+	int	lno;			/* for -x option */
+	bool	been_warned;		/* set if noticed dup */
+} NODE;
+
+extern FILE	*inf;			/* ioptr for current input file */
+extern long	lineftell;		/* ftell after getc( inf ) == '\n' */
+extern int	lineno,			/* line number of current line */
+		xflag;			/* -x: cxref style output */
+extern bool	_wht[0177],_etk[0177],_itk[0177],_btk[0177],_gd[0177];
+extern char	lbuf[BUFSIZ];
Index: doc/tools/src2html1.4a/Ctags/fortran.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/fortran.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/fortran.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)fortran.c	5.5 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "ctags.h"
+
+static void takeprec();
+
+char *lbp;				/* line buffer pointer */
+
+PF_funcs()
+{
+	register bool	pfcnt;		/* pascal/fortran functions found */
+	register char	*cp;
+	char	tok[MAXTOKEN],
+		*gettoken();
+
+	for (pfcnt = NO;;) {
+		lineftell = ftell(inf);
+		if (!fgets(lbuf,sizeof(lbuf),inf))
+			return(pfcnt);
+		++lineno;
+		lbp = lbuf;
+		if (*lbp == '%')	/* Ratfor escape to fortran */
+			++lbp;
+		for (;isspace(*lbp);++lbp);
+		if (!*lbp)
+			continue;
+		switch (*lbp | ' ') {	/* convert to lower-case */
+		case 'c':
+			if (cicmp("complex") || cicmp("character"))
+				takeprec();
+			break;
+		case 'd':
+			if (cicmp("double")) {
+				for (;isspace(*lbp);++lbp);
+				if (!*lbp)
+					continue;
+				if (cicmp("precision"))
+					break;
+				continue;
+			}
+			break;
+		case 'i':
+			if (cicmp("integer"))
+				takeprec();
+			break;
+		case 'l':
+			if (cicmp("logical"))
+				takeprec();
+			break;
+		case 'r':
+			if (cicmp("real"))
+				takeprec();
+			break;
+		}
+		for (;isspace(*lbp);++lbp);
+		if (!*lbp)
+			continue;
+		switch (*lbp | ' ') {
+		case 'f':
+			if (cicmp("function"))
+				break;
+			continue;
+		case 'p':
+			if (cicmp("program") || cicmp("procedure"))
+				break;
+			continue;
+		case 's':
+			if (cicmp("subroutine"))
+				break;
+		default:
+			continue;
+		}
+		for (;isspace(*lbp);++lbp);
+		if (!*lbp)
+			continue;
+		for (cp = lbp + 1;*cp && intoken(*cp);++cp);
+		if (cp = lbp + 1)
+			continue;
+		*cp = EOS;
+		(void)strcpy(tok,lbp);
+		getline();			/* process line for ex(1) */
+		pfnote(tok,lineno);
+		pfcnt = YES;
+	}
+	/*NOTREACHED*/
+}
+
+/*
+ * cicmp --
+ *	do case-independent strcmp
+ */
+cicmp(cp)
+	register char	*cp;
+{
+	register int	len;
+	register char	*bp;
+
+	for (len = 0,bp = lbp;*cp && (*cp &~ ' ') == (*bp++ &~ ' ');
+	    ++cp,++len);
+	if (!*cp) {
+		lbp += len;
+		return(YES);
+	}
+	return(NO);
+}
+
+static void
+takeprec()
+{
+	for (;isspace(*lbp);++lbp);
+	if (*lbp == '*') {
+		for (++lbp;isspace(*lbp);++lbp);
+		if (!isdigit(*lbp))
+			--lbp;			/* force failure */
+		else
+			while (isdigit(*++lbp));
+	}
+}
Index: doc/tools/src2html1.4a/Ctags/lisp.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/lisp.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/lisp.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lisp.c	5.5 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "ctags.h"
+
+extern char	*lbp;			/* pointer shared with fortran */
+
+/*
+ * lisp tag functions
+ * just look for (def or (DEF
+ */
+l_entries()
+{
+	register int	special;
+	register char	*cp,
+			savedc;
+	char	tok[MAXTOKEN];
+
+	for (;;) {
+		lineftell = ftell(inf);
+		if (!fgets(lbuf,sizeof(lbuf),inf))
+			return;
+		++lineno;
+		lbp = lbuf;
+		if (!cicmp("(def"))
+			continue;
+		special = NO;
+		switch(*lbp | ' ') {
+		case 'm':
+			if (cicmp("method"))
+				special = YES;
+			break;
+		case 'w':
+			if (cicmp("wrapper") || cicmp("whopper"))
+				special = YES;
+		}
+		for (;!isspace(*lbp);++lbp);
+		for (;isspace(*lbp);++lbp);
+		for (cp = lbp;*cp && *cp != '\n';++cp);
+		*cp = EOS;
+		if (special) {
+			if (!(cp = index(lbp,')')))
+				continue;
+			for (;cp >= lbp && *cp != ':';--cp);
+			if (cp < lbp)
+				continue;
+			lbp = cp;
+			for (;*cp && *cp != ')' && *cp != ' ';++cp);
+		}
+		else
+			for (cp = lbp + 1;
+			    *cp && *cp != '(' && *cp != ' ';++cp);
+		savedc = *cp;
+		*cp = EOS;
+		(void)strcpy(tok,lbp);
+		*cp = savedc;
+		getline();
+		pfnote(tok,lineno);
+	}
+	/*NOTREACHED*/
+}
Index: doc/tools/src2html1.4a/Ctags/print.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/print.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/print.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)print.c	5.4 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ctags.h"
+
+extern char	searchar;		/* ex search character */
+
+/*
+ * getline --
+ *	get the line the token of interest occurred on,
+ *	prepare it for printing.
+ */
+getline()
+{
+	register long	saveftell;
+	register int	c,
+			cnt;
+	register char	*cp;
+
+	saveftell = ftell(inf);
+	(void)fseek(inf,lineftell,SEEK_SET);
+	if (xflag)
+		for (cp = lbuf;GETC(!=,'\n');*cp++ = c);
+	/*
+	 * do all processing here, so we don't step through the
+	 * line more than once; means you don't call this routine
+	 * unless you're sure you've got a keeper.
+	 */
+	else for (cnt = 0,cp = lbuf;GETC(!=,EOF) && cnt < ENDLINE;++cnt) {
+		if (c == (int)'\\') {		/* backslashes */
+			if (cnt > ENDLINE - 2)
+				break;
+			*cp++ = '\\'; *cp++ = '\\';
+			++cnt;
+		}
+		else if (c == (int)searchar) {	/* search character */
+			if (cnt > ENDLINE - 2)
+				break;
+			*cp++ = '\\'; *cp++ = c;
+			++cnt;
+		}
+		else if (c == (int)'\n') {	/* end of keep */
+			*cp++ = '$';		/* can find whole line */
+			break;
+		}
+		else
+			*cp++ = c;
+	}
+	*cp = EOS;
+	(void)fseek(inf,saveftell,SEEK_SET);
+}
+
+char *symtype[]= {
+	"Unknown",
+	"Preprocessor macro",
+	"Preprocessor define",
+	"C function",
+	"C variable",
+	"C struct",
+	"C union",
+	"C typedef",
+	"C enum"
+};
+
+/*
+ * put_entries --
+ *	write out the tags
+ */
+put_entries(node)
+	register NODE	*node;
+{
+	extern FILE	*outf;		/* ioptr for tags file */
+	extern int	vflag;		/* -v: vgrind style output */
+	extern int	yflag;		/* -y: yet another style output */
+
+	if (node->left)
+		put_entries(node->left);
+	if (vflag)
+		printf("%s %s %d\n",
+		    node->entry,node->file,(node->lno + 63) / 64);
+	else if (xflag)
+		printf("%-16s %4d %-16s %s\n",
+		    node->entry,node->lno,node->file,node->pat);
+	else if (yflag)
+		printf("%-16s %4d %-16s %s\n",
+		    node->entry,node->lno,node->file,symtype[node->symbtype]);
+	else
+		fprintf(outf,"%s\t%s\t%c^%s%c\n",
+		    node->entry,node->file,searchar,node->pat,searchar);
+	if (node->right)
+		put_entries(node->right);
+}
Index: doc/tools/src2html1.4a/Ctags/strerror.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/strerror.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/strerror.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,6 @@
+char *strerror(i)
+ int i;
+ {
+  extern char *sys_errlist[];
+  return sys_errlist[i];
+ }
Index: doc/tools/src2html1.4a/Ctags/tree.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/tree.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/tree.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tree.c	5.5 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ctags.h"
+
+/*
+ * pfnote --
+ *	enter a new node in the tree
+ */
+pfnote(name,ln,type)
+	char	*name;
+	int	ln;
+	int 	type;
+{
+	extern NODE	*head;		/* head of the sorted binary tree */
+	extern char	*curfile;	/* current input file name */
+	register NODE	*np;
+	register char	*fp;
+	char	nbuf[MAXTOKEN];
+
+	/*NOSTRICT*/
+	if (!(np = (NODE *)malloc(sizeof(NODE)))) {
+		fputs("ctags: too many entries to sort\n",stderr);
+		put_entries(head);
+		free_tree(head);
+		/*NOSTRICT*/
+		if (!(head = np = (NODE *)malloc(sizeof(NODE)))) {
+			fputs("ctags: out of space.\n",stderr);
+			exit(1);
+		}
+	}
+	if (!xflag && !strcmp(name,"main")) {
+		if (!(fp = rindex(curfile,'/')))
+			fp = curfile;
+		else
+			++fp;
+		(void)sprintf(nbuf,"M%s",fp);
+		fp = rindex(nbuf,'.');
+		if (fp && !fp[2])
+			*fp = EOS;
+		name = nbuf;
+	}
+	if (!(np->entry = strdup(name))) {
+		(void)fprintf(stderr, "ctags: %s\n", strerror(errno));
+		exit(1);
+	}
+	np->file = curfile;
+	np->lno = ln; np->symbtype= type;
+	np->left = np->right = 0;
+	if (!(np->pat = strdup(lbuf))) {
+		(void)fprintf(stderr, "ctags: %s\n", strerror(errno));
+		exit(1);
+	}
+	if (!head)
+		head = np;
+	else
+		add_node(np,head);
+}
+
+add_node(node,cur_node)
+	register NODE	*node,
+			*cur_node;
+{
+	extern int	wflag;			/* -w: suppress warnings */
+	register int	dif;
+
+	dif = strcmp(node->entry,cur_node->entry);
+	if (!dif) {
+		if (node->file == cur_node->file) {
+			if (!wflag)
+				fprintf(stderr,"Duplicate entry in file %s, line %d: %s\nSecond entry ignored\n",node->file,lineno,node->entry);
+			return;
+		}
+		if (!cur_node->been_warned)
+			if (!wflag)
+				fprintf(stderr,"Duplicate entry in files %s and %s: %s (Warning only)\n",node->file,cur_node->file,node->entry);
+		cur_node->been_warned = YES;
+	}
+	else if (dif < 0)
+		if (cur_node->left)
+			add_node(node,cur_node->left);
+		else
+			cur_node->left = node;
+	else if (cur_node->right)
+		add_node(node,cur_node->right);
+	else
+		cur_node->right = node;
+}
+
+free_tree(node)
+	register NODE	*node;
+{
+	NODE	*nl;
+	while (node) {
+		if (node->right)
+			free_tree(node->right);
+		nl= node->left; free(node);
+		node = nl;
+	}
+}
Index: doc/tools/src2html1.4a/Ctags/yacc.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/yacc.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/yacc.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)yacc.c	5.6 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "ctags.h"
+
+/*
+ * y_entries:
+ *	find the yacc tags and put them in.
+ */
+y_entries()
+{
+	register int	c;
+	register char	*sp;
+	register bool	in_rule;
+	char	tok[MAXTOKEN];
+
+	while (GETC(!=,EOF))
+		switch ((char)c) {
+		case '\n':
+			SETLINE;
+			/* FALLTHROUGH */
+		case ' ':
+		case '\f':
+		case '\r':
+		case '\t':
+			break;
+		case '{':
+			if (skip_key((int)'}'))
+				in_rule = NO;
+			break;
+		case '\'':
+		case '"':
+			if (skip_key(c))
+				in_rule = NO;
+			break;
+		case '%':
+			if (GETC(==,'%'))
+				return;
+			(void)ungetc(c,inf);
+			break;
+		case '/':
+			if (GETC(==,'*'))
+				skip_comment();
+			else
+				(void)ungetc(c,inf);
+			break;
+		case '|':
+		case ';':
+			in_rule = NO;
+			break;
+		default:
+			if (in_rule || !isalpha(c) && c != (int)'.'
+			    && c != (int)'_')
+				break;
+			sp = tok;
+			*sp++ = c;
+			while (GETC(!=,EOF) && (intoken(c) || c == (int)'.'))
+				*sp++ = c;
+			*sp = EOS;
+			getline();		/* may change before ':' */
+			while (iswhite(c)) {
+				if (c == (int)'\n')
+					SETLINE;
+				if (GETC(==,EOF))
+					return;
+			}
+			if (c == (int)':') {
+				pfnote(tok,lineno);
+				in_rule = YES;
+			}
+			else
+				(void)ungetc(c,inf);
+		}
+}
+
+/*
+ * toss_yysec --
+ *	throw away lines up to the next "\n%%\n"
+ */
+toss_yysec()
+{
+	register int	c,			/* read character */
+			state;
+
+	/*
+	 * state == 0 : waiting
+	 * state == 1 : received a newline
+	 * state == 2 : received first %
+	 * state == 3 : recieved second %
+	 */
+	lineftell = ftell(inf);
+	for (state = 0;GETC(!=,EOF);)
+		switch ((char)c) {
+			case '\n':
+				++lineno;
+				lineftell = ftell(inf);
+				if (state == 3)		/* done! */
+					return;
+				state = 1;		/* start over */
+				break;
+			case '%':
+				if (state)		/* if 1 or 2 */
+					++state;	/* goto 3 */
+				break;
+			default:
+				state = 0;		/* reset */
+		}
+}
Index: doc/tools/src2html1.4a/Ctags/z.c
===================================================================
--- doc/tools/src2html1.4a/Ctags/z.c	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Ctags/z.c	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,20 @@
+#define fred 23
+#define jim(a) (a+2)
+
+int helo;
+
+struct thing {
+	int v;
+} doris;
+
+union what {
+	int v;
+	char q;
+} mary;
+
+enum thinddd { 1,2,3,4,5 } zoo;
+
+typedef unsigned int uinty;
+
+int rain()
+ { printf("Hello world\n"); }
Index: doc/tools/src2html1.4a/FreeBSD/FreeBSD.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/FreeBSD.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/FreeBSD.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,25 @@
+Welcome to the hyperlinked source code tree for FreeBSD-2.1.0. This is an
+attempt at a WWW document that allows you to find functions, structs
+etc. in the FreeBSD source code by name.<p>
+
+If you are interested in a particular type of symbols (e.g functions), use
+the type links below. If you are interested in a particular directory in
+FreeBSD, choose the directory link below.<p>
+
+Follow the links until you reach the source code you are interested in.<p>
+
+<h3>Bugs and Missing Features</h3>
+
+I am using ctags and perl to find the symbols and produce the html documents.
+My parsing of the ctags output (especially for variables) seems slightly
+wrong. I'd appreciate a better way of doing things.<p>
+
+The final code should have hyperlinks that allow you to follow references
+to other symbols in the tree (e.g calls to bread() etc). This is difficult
+given C's scoping rules, and I don't want to write a C grammar parser.
+Until I can think of a clean way, I'll omit the desired hyperlinks.<p>
+
+<author>
+<a href="http://minnie.cs.adfa.oz.au/warren.html">Warren Toomey</a>
+wkt@cs.adfa.oz.au, January 1996
+</author>
Index: doc/tools/src2html1.4a/FreeBSD/FreeBSD.s2h
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/FreeBSD.s2h	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/FreeBSD.s2h	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,68 @@
+#
+#
+# Input description for the FreeBSD 2.1.0 source tree
+# Place this file and all the .hdr files in a directory,
+# cd into that directory, and say `src2html FreeBSD.s2h'.
+#
+set Formdir /cgi-bin
+set Htmldir FreeBSD-srctree
+set Htmlroot .
+set Newsrctree newsrc
+set Srctree sys
+#
+dir conf		Kernel configuration parameters
+dir ddb			Kernel debugging routines
+dir dev/aic7xxx		Adaptec AIC7770/AIC7870 sequencer code
+dir dev/vn		Vnode disk driver
+dir gnu/i386/fpemul 	GNU's i387 floating point emulator
+dir gnu/i386/isa	Device drivers with GNU licensing
+dir gnu/isdn		An ISDN driver
+dir i386/apm		i386-specific power management
+dir i386/apm/apm_init	i386-specific power management
+dir i386/boot/biosboot	i386-specific boot code
+dir i386/boot/dosboot	i386-specific boot code
+dir i386/boot/kzipboot	i386-specific boot code
+dir i386/boot/netboot	i386-specific boot code
+dir i386/eisa		Device drivers for peripherals on the EISA bus
+dir i386/i386		i386-specific code
+dir i386/ibcs2		Intel Unix Binary Compatibility code
+dir i386/include 	i386-specific C-language include files
+dir i386/include/pc	i386-specific C-language include files
+dir i386/isa		Device drivers for peripherals on the ISA bus
+dir i386/isa/ic		Device drivers for peripherals on the ISA bus
+dir i386/isa/matcd	Matsushita device driver
+dir i386/isa/pcvt	VT-220 emulation code
+dir i386/isa/sound	Device drivers for sound peripherals on the ISA bus
+dir i386/linux		Linux binaries support
+dir i386/scsi		Device drivers for SCSI peripherals on the ISA bus
+dir isofs/cd9660	ISO CD9660 file-system code
+dir kern		The core OS routines: processes, scheduling, syscalls
+dir libkern		The kernel library
+dir miscfs/deadfs	Miscellaneous file systems
+dir miscfs/devfs	Miscellaneous file systems
+dir miscfs/fdesc	Miscellaneous file systems
+dir miscfs/fifofs	Miscellaneous file systems
+dir miscfs/kernfs	Miscellaneous file systems
+dir miscfs/nullfs	Miscellaneous file systems
+dir miscfs/portal	Miscellaneous file systems
+dir miscfs/procfs	Miscellaneous file systems
+dir miscfs/specfs	Miscellaneous file systems
+dir miscfs/umapfs	Miscellaneous file systems
+dir miscfs/union	Miscellaneous file systems
+dir msdosfs		The MS-DOS file system code
+dir net			Routing and general network interfaces
+dir netccitt		CCITT Networking code
+dir netinet		Internet protocols
+dir netiso		ISO Networking code
+dir netiso/xebec	ISO Networking code
+dir netns		Xerox NS Networking code
+dir nfs			The Network File System
+dir pccard		Interface code for PC-CARD controllers.
+dir pci			Device drivers for peripherals on the PCI bus
+dir scsi		Device drivers for peripherals on the SCSI bus
+dir sys			Widely used C-language include files
+dir ufs/ffs		The Berkeley Fast Filesystem
+dir ufs/lfs		The Log Filesystem
+dir ufs/mfs		The Memory Filesystem
+dir ufs/ufs		The Unix Filesystem
+dir vm			The Virtual Memory Management subsystem
Index: doc/tools/src2html1.4a/FreeBSD/conf.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/conf.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/conf.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,9 @@
+The <tt>conf</tt> directory holds miscellaneous files, such as the list of
+files which are needed/optional in the OS. The main file of concern is
+<tt>param.c</tt>, which describes the system-dependent configuration
+parameters of FreeBSD.
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+doesn't really cover this directory. It is vaguely covered in Chapter 8 of
+the "System Performance Tuning" Nutshell book by Mike Loukides.
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/ddb.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/ddb.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/ddb.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,6 @@
+The <tt>ddb</tt> directory holds routines used to debug the kernel.
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+doesn't really cover this directory. However, some information has been
+presented by Kirk KcKusick and Keith Bostic in their "UNIX Kernel Internals"
+notes, which they have presented in many places in the past few years.
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/i386.i386.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/i386.i386.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/i386.i386.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,5 @@
+The <tt>i386/i386</tt> directory holds the routines that deal with the Intel
+386/486 CPU in the PC architecture.
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+doesn't describe this anywhere at all, because this is machine-specific.
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/i386.include.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/i386.include.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/i386.include.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,5 @@
+The <tt>i386/include</tt> directory holds C-language include files that
+define things that are specific about the PC architecture.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+doesn't describe this anywhere at all. <p>
Index: doc/tools/src2html1.4a/FreeBSD/i386.isa.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/i386.isa.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/i386.isa.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,10 @@
+The <tt>i386/isa</tt> directory holds the routines that deal with the ISA
+I/O bus in the PC architecture.
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+doesn't describe this anywhere at all, because this is machine-specific.
+You can however glean some information from the following chapter:
+
+<dl>
+<dt> <b>Chapter 8</b>, pp 225-256 <i>Device Drivers</i>.
+</dl>
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/i386.stand.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/i386.stand.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/i386.stand.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,14 @@
+The <tt>i386/stand</tt> directory holds functions that are useful, but cannot
+be called from the kernel. For example printf() is great, but if the kernel
+called printf() it would generate a TRAP and wind up back in the kernel.<p>
+
+The functions here emulate these functions by dealing directly with the
+hardware on the system.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+covers machine-independent <tt>stand</tt> functionality in:
+
+<dl>
+<dt> <b>Chapter 13.2</b>, pg 394 <i>Bootstrapping</i>.
+</dl>
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/kern.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/kern.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/kern.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,18 @@
+The <tt>kern</tt> directory holds the core functionality of FreeBSD:
+system startup, core system calls and syscall dispatching, process
+management, scheduling, signals, file descriptors, top-level filesystem
+code, interprocess communication and terminal handling.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+covers <tt>kern</tt> in:
+
+<dl>
+<dt> <b>Chapter 2</b>, pp 19-42 <i>Overview of the Kernel</i>.
+<dt> <b>Chapter 3</b>, pp 43-66 <i>Kernel Services</i>.
+<dt> <b>Chapter 4</b>, pp 69-108 <i>Process Management</i>.
+<dt> <b>Chapter 6</b>, pp 169-186 <i>I/O System Overview</i>.
+<dt> <b>Chapter 9</b>, pp 259-278 <i>Terminal Handling</i>.
+<dt> <b>Chapter 10</b>, pp 281-309 <i>Interprocess Communication</i>.
+<dt> <b>Chapter 13</b>, pp 393-411 <i>System Startup</i>.
+</dl>
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/net.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/net.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/net.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,11 @@
+The <tt>net</tt> directory holds the network functionality of FreeBSD that
+deals with routing and generic interfaces: SLIP, PPP, Ethernet, packet
+filters.
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+covers <tt>kern</tt> in:
+
+<dl>
+<dt> <b>Chapter 11</b>, pp 311-341 <i>Network Communication</i>.
+</dl>
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/netinet.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/netinet.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/netinet.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,10 @@
+The <tt>netinet</tt> directory holds the code for the Internet network
+protocols used in FreeBSD: TCP, IP, ICMP, ARP.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+covers <tt>netinet</tt> in:
+
+<dl>
+<dt> <b>Chapter 12</b>, pp 343-389 <i>Network Protocols</i>.
+</dl>
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/nfs.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/nfs.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/nfs.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,7 @@
+The <tt>nfs</tt> directory holds the code for the Network File System.
+The code was developed from a specification of NFS from Sun Microsystems.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+doesn't cover <tt>nfs</tt>. You probably don't really want to delve into
+it too much, but there is an RFC around describing the protocol, but not
+the code here. <p>
Index: doc/tools/src2html1.4a/FreeBSD/stand.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/stand.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/stand.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,14 @@
+The <tt>stand</tt> directory holds functions that are useful, but cannot be
+called from the kernel. For example printf() is great, but if the kernel
+called printf() it would generate a TRAP and wind up back in the kernel.<p>
+
+The functions here emulate these functions by dealing directly with the
+hardware on the system.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+covers <tt>stand</tt> in:
+
+<dl>
+<dt> <b>Chapter 13.2</b>, pg 394 <i>Bootstrapping</i>.
+</dl>
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/sys.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/sys.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/sys.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,6 @@
+The <tt>sys</tt> directory holds C-language include files that are used
+by all parts of the FreeBSD source tree.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+doesn't cover these files specifically, but discussion of their contents
+crops up everywhere.<p>
Index: doc/tools/src2html1.4a/FreeBSD/ufs.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/ufs.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/ufs.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,10 @@
+The <tt>ufs</tt> directory holds the code for the Berkeley Fast Filesystem,
+which is the filesystem used on locally mounted hard and floppy disks.<p>
+
+The 4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman
+covers <tt>ufs</tt> in:
+
+<dl>
+<dt> <b>Chapter 7</b>, pp 187-223 <i>The Filesystem</i>.
+</dl>
+<p>
Index: doc/tools/src2html1.4a/FreeBSD/vm.hdr
===================================================================
--- doc/tools/src2html1.4a/FreeBSD/vm.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/FreeBSD/vm.hdr	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,9 @@
+The <tt>vm</tt> directory holds the virtual memory subsystem used by
+FreeBSD. This was derived from the VM system used in the Mach kernel,
+with the interface to the rest of the kernel rewritten. As such, it is
+not described in the
+4.3BSD Internals book by Leffler, McKusick, Karels and Quarterman,
+but it is described by Kirk KcKusick and Keith Bostic in their
+"UNIX Kernel Internals"
+notes, which they have presented in many places in the past few years.
+<p>
Index: doc/tools/src2html1.4a/Readme
===================================================================
--- doc/tools/src2html1.4a/Readme	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/Readme	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,65 @@
+   src2html - Hyperlink a C source code tree using HTML, Version 1.3-alpha
+
+	     Warren Toomey	wkt@cs.adfa.oz.au	June 1995
+
+
+Src2html is a program which takes a C source tree and creates a set of
+HTML hypertext documents that allows the most important symbols in the
+source tree to be found easily. As well, a HTML version of the source
+tree is created, with the symbols given in bold font where they are defined
+in the source.
+
+
+REQUIREMENTS
+
+You will need:
+
+	+ Perl 4.x
+	+ a standard Unix sort(1) command.
+	+ a mkdir(1) that supports recursive creation of directories.
+	  src2html is configured to use `mkdir -p' to do this.
+	+ an egrep(1) if you're going to use the search facility.
+	+ httpd(1) if you're going to use the search facility.
+	+ Ctags-new, which is bundled with src2html, and a C compiler
+	  to compile it.
+
+
+INSTALLATION
+
+Extract the src2html archive, including the Ctags-new and Example directories;
+you probably have already done that. Go into the Ctags-new directory and make
+ctags-new. This should be very straight-forward.
+
+Install ctags-new and src2html in a directory on your path, make them
+executable and install their man pages as well. If your mkdir(1) uses a
+different option to -p, edit src2html to fix this.
+
+If you want to use the search facility, you need to install src2html.cgi
+in your httpd script directory, and edit it to reflect the root of your
+HTML documents, as set in DirectryRoot in conf/srm.conf.
+
+Make sure that ctags-new, src2html and src2html.cgi are executable, and
+that the latter two can find the Perl interpreter. Installation is complete.
+
+
+USING SRC2HTML
+
+Using src2html is pretty straight-forward. Print out and read the man page
+before trying anything. In the FreeBSD directory I have included the config
+file and header files for my src2html conversion of the FreeBSD-2.0.5 source
+tree; read the man page and FreeBSD/FreeBSD.s2h in tandem. The root document of
+this HTML tree is at http://minnie.cs.adfa.oz.au/FreeBSD-srctree/FreeBSD.html.
+
+
+COMMENTS AND QUESTIONS
+
+Surprisingly, src2html is reasonably fast even on large source trees. This was
+my first Perl program, so it could probably be made faster and smaller. I've
+placed comments in the source to give you an idea of what each section does. If
+you have any questions or comments, please email them to me at
+wkt@cs.adfa.oz.au. Now that it's finished I'm not that keen on overhauling it
+etc. I consider it as a good prototype. Getting inter-source hyperlinks done
+would be great, but I really don't want to write a C parser myself.
+
+Cheers,
+	Warren Toomey
Index: doc/tools/src2html1.4a/src2html
===================================================================
--- doc/tools/src2html1.4a/src2html	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/src2html	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,589 @@
+#!/usr/local/bin/perl
+# Src2html: Take a source tree and generate Html documents that have hyperlinks
+# to the definition of structures, variables, functions, and preprocessor
+# definitions. Read the manual page for details on how to use the program.
+#
+# Version 1.4-alpha. Written by Warren Toomey wkt@cs.adfa.oz.au
+#
+# 19th January 1996
+#
+
+if ($#ARGV <= 0 || $#ARGV > 4) {		# Check arg count
+    print(STDERR "Usage: $0 [-na] [-nl] [-d num] input_description\n");
+    print(STDERR "           -na: Don't produce top-level category files\n");
+    print(STDERR "           -nl: Don't produce per-letter files\n");
+    print(STDERR "            -d: Set debugging to given number (0-3)\n");
+    exit(1);
+}
+
+# Set up default option values
+$NoLetters= 0;
+$NoAll= 0;
+$Debug=0;
+$Top= $ARGV[$#ARGV];
+$Top=~ s/\.s2h$//;
+
+# Parse the options
+for ($i=0; $i<= $#ARGV; $i++) {
+	if ($ARGV[$i] eq "-na") { $NoAll= 1; next; }
+	if ($ARGV[$i] eq "-nl") { $NoLetters= 1; next; }
+	if ($ARGV[$i] eq "-d") { $i++; $Debug= $ARGV[$i]; next; }
+}
+
+$Title{"m"}= "Macros";
+$Title{"d"}= "Defines";
+$Title{"f"}= "Functions";
+$Title{"v"}= "Variables";
+$Title{"s"}= "Structs";
+$Title{"u"}= "Unions";
+$Title{"t"}= "Typedefs";
+$Title{"e"}= "Enums";
+$Title{"g"}= "All symbols";
+
+&get_s2h;				# Read the description file
+&make_dirs;				# Make directories as needed
+&make_ctags;				# Generate ctags for all src
+&parse_ctags;				# Parse ctags, generate html ptr files
+foreach $i (keys(%Dirinfo))
+{ &rewrite_src($i); }			# Rewrite the src code
+exit(0);				# and exit
+ 
+
+## get_s2h: Opens the source description file, reads it, and sets up some
+## variables describing where some directories are, and the source directories
+## to process. Variables used are:
+## Srctree - The root of the source tree we are processing
+## Htmlroot - The directory where all WWW documents are kept
+## Htmldir -  The directory under Htmlroot for this source tree
+## Htmltree - The root of the destination tree for the Html code
+## Newsrctree - The directory in Htmltree to store the new Htmlised code
+## Headers - The directory where we keep information to prepend in some docs
+## Formdir - The place to put the index searching script
+## Dirinfo{} - The list of dirs and the info about the directory
+## Dotdir{} - The directory name with /'s -> .'s
+
+sub get_s2h {
+    $Newsrctree= 'newsrc';			# Set up as default
+    $Headers= '.';
+
+
+    #########################################################
+    # make sure we dump out the last bit of the last file....
+
+			# Print out the remainder of the
+			# current file, incl. the buffered line
+    if ($In_file == 1) {
+      if ("$line" ne "") { print OUT $line; }
+      while (<IN>) {
+	      s/\&/&amp;/g; s/\</&lt;/g; s/\>/&gt;/g; print OUT;
+	} 
+      print OUT "\n\n\n\n\n\n\n\n</pre></body>\n";
+      close(IN); close(OUT);
+    }
+    #########################################################
+
+    open(S2H,$ARGV[$#ARGV])				# Open descript
+	|| die "$0: can't open $ARGV[$#ARGV]: $!\n";
+
+    while(<S2H>) {				# Read in input lines
+	next if /^#/;				# Skip comments
+	if ( /^set\s+Srctree\s+(\S+)/ ) {
+	    $Srctree = $1; next;		# Set the variable
+	}
+	if ( /^set\s+Htmlroot\s+(\S+)/ ) {
+	    $Htmlroot = $1; next;		# Set the variable
+	}
+	if ( /^set\s+Htmldir\s+(\S+)/ ) {
+	    $Htmldir = $1; next;		# Set the variable
+	}
+	if ( /^set\s+Newsrctree\s+(\S+)/ ) {
+	    $Newsrctree = $1; next;		# Set the variable
+	}
+	if ( /^set\s+Headers\s+(\S+)/ ) {
+	    $Headers = $1; next;		# Set the variable
+	}
+	if ( /^set\s+Formdir\s+(\S+)/ ) {
+	    $Formdir = $1; next;		# Set the variable
+	}
+	if ( /^dir\s+(\S+)\s+(.*)/ ) {
+	    $Dirinfo{$1}= $2; $Dotdir{$1}=$1;
+	    $Dotdir{$1}=~ s/\//./g;
+	    next;				# Get dir commands
+	}
+	if ( /^\n/ ) { next; }			# Ignore blank lines
+						# Bad input line, give warning
+	chop; print "$_: Bad line, ignoring\n"; next;
+    }
+    close(S2H);
+    if (!defined($Srctree)) { die "$0: Srctree undefined in $ARGV[$#ARGV]\n"; }
+    if (!defined($Htmlroot)) { die "$0: Htmlroot undefined in $ARGV[$#ARGV]\n"; }
+    if (!defined($Htmldir)) { die "$0: Htmldir undefined in $ARGV[$#ARGV]\n"; }
+    $Htmltree= "$Htmlroot/$Htmldir";
+}
+
+## make_dirs: Make the directories need to store the Html documents, and also
+## check to make sure that the input directories exist. We depend upon mkdir(1)
+## having the -p option to make intermediate directories as needed.
+
+sub make_dirs {
+    local($i);
+
+    foreach $i (keys(%Dirinfo)) {	     # Check that the directories exist
+	if (! -e "$Srctree/$i") {
+	    die "$0: Input dir $Srctree/$i doesn't exist\n";
+	}
+	if (! -d "$Srctree/$i") {
+	    die "$0: Input dir $Srctree/$i is not a directory\n";
+	}
+    }
+    if (! -e "$Htmltree") {
+	system("mkdir -p $Htmltree") && die "$0: Can't mkdir $Htmltree\n";
+    }
+    if (! -e "$Htmltree/$Newsrctree") {
+	system("mkdir -p $Htmltree/$Newsrctree")
+		&& die "$0: Can't mkdir $Htmltree/$Newsrctree\n";
+    }
+    if (! -e "$Htmltree/ctags") {
+	system("mkdir -p $Htmltree/ctags") && die "$0: Can't mkdir ctags\n";
+    }
+    foreach $i (keys(%Dirinfo)) {
+	if (! -e "$Htmltree/$Newsrctree/$i") {
+	    system("mkdir -p $Htmltree/$Newsrctree/$i")
+		&& die "$0: Can't mkdir $Htmltree/$Newsrctree/$i\n";
+	}
+    }
+}
+
+## make_ctags: Process all the source code, creating the ctags files.
+## The Ctagsfile{} array is set up to hold the name of the ctags files
+## created.
+
+sub make_ctags {
+    local($i);
+
+    foreach $i (keys(%Dirinfo)) {
+	$Ctagsfile{$i}= "$Htmltree/ctags/$Dotdir{$i}.ctags";
+	if ($Debug > 0 ) { print "Generating ctags for $Ctagsfile{$i}\n"; }
+	system("(cd $Srctree; ctags-new -d -t -w -y $i/*) > $Ctagsfile{$i}")
+	&& print "$0: ctags failed on $Srctree/$i\n";
+    }
+}
+
+
+## parse_ctags: Parse the ctags file produced by make_ctags, creating several
+## arrays of information. The arrays created are:
+## Macro{} - The name of every macro and its name lowercased
+## Def{} - The name of every define and its name lowercased
+## Func{} - The name of every function and its name lowercased
+## Var{} - The name of every variable and its name lowercased
+## Struct{} - The name of every struct and its name lowercased
+## Union{} - The name of every union and its name lowercased
+## Type{} - The name of every typedef and its name lowercased
+## Enum{} - The name of every enum and its name lowercased
+## Nfile{} - The directory in which the symbol was found
+## Nline{} - The line number where the symbol was found
+
+sub parse_ctags {
+    local($i);
+    local($low);
+
+    foreach $i (keys(%Dirinfo)) {
+	open(CTAGS,$Ctagsfile{$i}) || die "$0: Can't open $Ctagsfile{$i}, $!\n";
+	if ($Debug > 0) { print "Parsing $Ctagsfile{$i} to build ptr files\n"; }
+	while (<CTAGS>) {
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+Preprocessor macro/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Macro{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next;
+	    }
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+Preprocessor define/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Def{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next; 
+	    }
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C struct/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Struct{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next;
+	    }
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C union/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Union{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next; 
+	    }
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C typedef/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Type{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next; 
+	    }
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C enum/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Enum{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next;
+	    }
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C function/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Func{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next;
+	    }
+	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C variable/ ) {
+		($low=$1)=~tr/A-Z_/a-z/d; $Var{$low}=$1;
+		$Nfile{$1}= $3; $Nline{$1}= $2; next;
+	    }
+	    print "$0: In Ctagsfile{$i}, don't recognise $_";
+	}
+	close(CTAGS);
+	&make_dir_html($i);
+	undef %Macro; undef %Def; undef %Func; undef %Var;
+	undef %Struct; undef %Union; undef %Type; undef %Enum;
+    }
+  &make_top_html;
+}
+
+## make_letters_html: Make the lowest HTML documents, i.e those per-directory
+## per-type per-letter Htmls that point directly at the source code.
+## Arguments are:  Dir name, prefix, title, Name/dir list
+## If the file is created, set $Exists(letter) positive, else to 0.
+
+sub make_letters_html {
+    local($dir)= $_[0];
+    local($pref)= $_[1];
+    local($title)= $_[2];
+    local(*type)= $_[3];
+    local($htmlfile);
+    local($let)="@";
+  
+    foreach $i ( "a".."z" ) { $Exists{$i}=0; }
+    foreach $name (sort keys( %type )) {
+	if (substr($name,0,1) ne $let) {
+	    if ($let ne "@") {
+	        print HTML "</ul></body>\n";
+	        close(HTML);
+	        $Exists{$let}= 1;
+	    }
+	    $let= substr($name, 0, 1);
+	    $htmlfile= "$Htmltree/$Dotdir{$dir}.$pref$let.html";
+	    open(HTML, "> $htmlfile") || die "$0: Can't open $htmlfile, $!\n";
+  
+	    print HTML "<head>\n<title>$title starting with ";
+	    print HTML "`$let' in $dir</title>\n";
+	    print HTML "</head><body><h1>$title starting with ";
+	    print HTML "`$let' in $dir</h1><p>\n";
+	    print HTML "<ul>\n";
+	}
+        print HTML "<li><a href=\"$Newsrctree/$Nfile{$type{$name}}";
+        print HTML ".html#$type{$name}\">$type{$name}</a> ";
+        print HTML "$Nfile{$type{$name}}:$Nline{$type{$name}}\n"; next;
+    }
+    print HTML "</ul></body>\n";
+    close(HTML);
+    $Exists{$let}= 1;
+}
+
+## make_type_html: Make the type htmls. If there are <50 symbols for the
+## directory, create the per-directory per-type html document only. Otherwise
+## for every letter grep symbols, call make_lowest_letter_html, and
+## finally create the per-directory per-type html document that points only
+## at the letter files created.
+## Arguments are:  Dir name, prefix, title, Name/dir list
+
+sub make_type_html {
+    local($dir)= $_[0];
+    local($pref)= $_[1];
+    local($title)= $_[2];
+    local(*type)= $_[3];
+    local($i);
+    local($htmlfile);
+    local(@keys)= keys(%type);
+    local($name);
+
+    $Exists{$title}=0;
+    if ( $#keys < 0 ) { return; }
+    if ($Debug > 0) {
+	$i= $#keys + 1;
+	print "The associative array for $dir $title has $i elements\n";
+    }
+    if ( ($#keys < 50) || ($NoLetters == 1) ) {
+	$htmlfile= "$Htmltree/$Dotdir{$dir}.$pref.html";
+	open(HTML, "> $htmlfile") || die "$0: Can't open $htmlfile, $!\n";
+	print HTML "<head>\n<title>$title in $dir</title>\n";
+	print HTML "</head><body><h1>$title in $dir</h1>\n";
+	print HTML "<ul>\n";
+	foreach $name (sort keys( %type )) {
+	    print HTML "<li><a href=\"$Newsrctree/$Nfile{$type{$name}}";
+	    print HTML ".html#$type{$name}\">$type{$name}</a> ";
+	    print HTML "$Nfile{$type{$name}}:$Nline{$type{$name}}\n"; next;
+	}
+	print HTML "</ul></body>\n";
+	close(HTML);
+	$Exists{$title}=1;
+    }
+    else {
+	&make_letters_html($dir, $pref, $title, *type);
+
+	open(HTML, "> $Htmltree/$Dotdir{$dir}.$pref.html")
+		|| die "$0: Can't open $htmlfile.$pref.html, $!\n";
+	print HTML "<head>\n<title>$title in $dir</title>\n";
+	print HTML "</head><body><h1>$title in $dir</h1><p>\n";
+	print HTML "<ul>\n";
+    
+	foreach $i ( "a".."z" ) {
+	    if ($Exists{$i} > 0) {			# A file exists
+		print HTML "<li><a href=\"$Dotdir{$dir}.$pref$i.html\">";
+		print HTML "$i</a>\n"; $Exists{$title}++; $Exists{$i}=0;
+	    }
+	}
+	print HTML "</ul></body>\n";
+	close(HTML);
+	if ($Exists{$title} == 0) { unlink($htmlfile); }
+    }
+}
+
+## asappend: Append the contents of the second associative array to the
+## first.
+
+sub asappend {
+    local(*To)= $_[0];
+    local(*From)= $_[1];
+    local($i);
+
+    foreach $i (keys(%From)) { $To{$i}= $From{$i} ; }
+}
+
+## make_dir_html: Make the html document for the directory. Use the
+## Exist{} array to determine what types to include on the document.
+## Arguments are:  Dir name
+
+sub make_dir_html {
+    local($dir)= $_[0];
+    local($i);
+    local(@keys);
+
+    if ($Debug > 1) { print"In makedir, dir is $dir\n"; }
+    &make_type_html($dir, "f", $Title{"f"}, *Func);
+    &make_type_html($dir, "m", $Title{"m"}, *Macro);
+    &make_type_html($dir, "d", $Title{"d"}, *Def);
+    &make_type_html($dir, "v", $Title{"v"}, *Var);
+    &make_type_html($dir, "s", $Title{"s"}, *Struct);
+    &make_type_html($dir, "u", $Title{"u"}, *Union);
+    &make_type_html($dir, "t", $Title{"t"}, *Type);
+    &make_type_html($dir, "e", $Title{"e"}, *Enum);
+
+    if ($NoAll != 1) {
+        &asappend(*GFunc, *Func);
+        &asappend(*GMacro, *Macro);
+        &asappend(*GDef, *Def);
+        &asappend(*GVar, *Var);
+        &asappend(*GStruct, *Struct);
+        &asappend(*GUnion, *Union);
+        &asappend(*GType, *Type);
+        &asappend(*GEnum, *Enum);
+    }
+
+    &asappend(*Alldir, *Func);
+    &asappend(*Alldir, *Macro);
+    &asappend(*Alldir, *Def);
+    &asappend(*Alldir, *Var);
+    &asappend(*Alldir, *Struct);
+    &asappend(*Alldir, *Union);
+    &asappend(*Alldir, *Type);
+    &asappend(*Alldir, *Enum);
+    if ($NoLetters != 1) {
+        &make_letters_html($dir, "g", $Title{"g"}, *Alldir);
+    }
+    undef %Alldir;
+
+    open(HTML, "> $Htmltree/$Dotdir{$dir}.html")
+	|| die "$0: Can't open $Htmltree/$Dotdir{$dir}.html, $!\n";
+    print HTML "<head>\n<title>Cross-references for $dir</title>\n";
+    print HTML "</head><body><h1>Cross-references for $dir</h1><p>\n";
+    if (-f "$Headers/$Dotdir{$dir}.hdr" ) {
+	open(TOPHDR, "$Headers/$Dotdir{$dir}.hdr");
+	while (<TOPHDR>) { print HTML; }
+	close(TOPHDR);
+    }
+
+    if (defined($Formdir)) {
+        print HTML "<hr><form action=\"$Formdir/src2html.cgi\" ";
+	print HTML "method=\"POST\">\n";
+        print HTML "<input type=\"submit\" value=\"Search\">\n";
+        print HTML "<input type= \"text\" ";
+	print HTML "name=\"$Htmldir/$Newsrctree\">\n";
+        print HTML "Enter a symbol's name here to quickly find it.\n";
+        print HTML "</form><hr>\n";
+    }
+    print HTML "<h1>Cross-references for $dir by type</h1><p><ul>\n";
+    
+    foreach $i ( "f","m","d","v","s","u","t","e" ) {
+	if ($Exists{$Title{$i}} > 0) {		# A type exists
+	    print HTML "<li><a href=\"$Dotdir{$dir}.$i.html\">";
+	    print HTML "$Title{$i}</a>\n";
+	    $Exists{$dir}++; $Exists{$Title{$i}}=0;
+	}
+    }
+    print HTML "</ul><p>\n";
+    if ($NoLetters != 1) {
+        print HTML "<h1>Cross-references for $dir by letter</h1><p><ul>\n";
+        foreach $i ( "a".."z" ) {
+	    if ($Exists{$i} > 0) {			# A letter exists
+	        print HTML "<li><a href=\"$Dotdir{$dir}.g$i.html\">";
+	        print HTML "$i</a>\n"; $Exists{$i}=0;
+	    }
+        }
+    }
+    print HTML "</ul></body>\n";
+    close(HTML);
+}
+
+## Make_top_html: Make the top html document by making the ones below
+## it and then adding links to them.
+
+sub make_top_html {
+    local($i);
+    local(@keys);
+
+    $Dotdir{$Top}=$Top;
+    &make_type_html($Top, "f", $Title{"f"}, *GFunc);
+    &make_type_html($Top, "m", $Title{"m"}, *GMacro);
+    &make_type_html($Top, "d", $Title{"d"}, *GDef);
+    &make_type_html($Top, "v", $Title{"v"}, *GVar);
+    &make_type_html($Top, "s", $Title{"s"}, *GStruct);
+    &make_type_html($Top, "u", $Title{"u"}, *GUnion);
+    &make_type_html($Top, "t", $Title{"t"}, *GType);
+    &make_type_html($Top, "e", $Title{"e"}, *GEnum);
+
+    open(HTMLTOP, "> $Htmltree/$Top.html")
+	|| die "$0: Can't open $Htmltree/$Top.html, $!\n";
+    print HTMLTOP "<head>\n<title>Cross-references for $Top</title>\n";
+    print HTMLTOP "</head><body><h1>Cross-references for $Top</h1><p>\n";
+
+    if (-f "$Headers/$Top.hdr" ) {
+	open(TOPHDR, "$Headers/$Top.hdr");
+	while (<TOPHDR>) { print HTMLTOP; }
+	close(TOPHDR);
+    }
+
+    if (defined($Formdir)) {
+        print HTMLTOP "<hr><form action=\"$Formdir/src2html.cgi\" ";
+	print HTMLTOP "method=\"POST\">\n";
+        print HTMLTOP "<input type=\"submit\" value=\"Search\">\n";
+        print HTMLTOP "<input type= \"text\" ";
+	print HTMLTOP "name=\"$Htmldir/$Newsrctree\">\n";
+        print HTMLTOP "Enter a symbol's name here to quickly find it.\n";
+        print HTMLTOP "</form><hr>\n";
+    }
+    print HTMLTOP "<h2>Cross-references by directory</h2><p>\n";
+    print HTMLTOP "<ul>\n";
+    
+    foreach $i (sort keys(%Dirinfo)) {
+	if ($Exists{$i} > 0) {			# A dir exists
+	    print HTMLTOP "<li><a href=\"$Dotdir{$i}.html\">";
+	    print HTMLTOP "$i</a> $Dirinfo{$i}\n"; $Exists{$i}=0;
+	}
+    }
+    if ($NoAll != 1) {
+        print HTMLTOP "</ul><p><h2>Cross-references by type</h2><p><ul>\n";
+        foreach $i ( "f","m","d","v","s","u","t","e" ) {
+	    if ($Exists{$Title{$i}} > 0) {		# A type exists
+	        print HTMLTOP "<li><a href=\"$Top.$i.html\">";
+	        print HTMLTOP "$Title{$i}</a>\n"; 
+	    }
+        }
+        if ($NoLetters != 1) {
+            print HTMLTOP "</ul><p><h2>All Cross-references for $Top";
+	    print HTMLTOP "</h2><p><ul>\n";
+            &asappend(*Alltop, *GFunc);
+            &asappend(*Alltop, *GMacro);
+            &asappend(*Alltop, *GDef);
+            &asappend(*Alltop, *GVar);
+            &asappend(*Alltop, *GStruct);
+            &asappend(*Alltop, *GUnion);
+            &asappend(*Alltop, *GType);
+            &asappend(*Alltop, *GEnum);
+    
+            if ($Debug > 0) { print "Making top letters\n"; }
+   	    &make_letters_html($Top, "g", $Title{"g"}, *Alltop);
+    	    if ($Debug > 0) { print "Making top letters, part 2\n"; }
+    	    foreach $i ( "a".."z" ) {
+		    if ($Exists{$i} > 0) {
+	    	    print HTMLTOP "<li><a href=\"$Dotdir{$Top}.g$i.html\">";
+	    	    print HTMLTOP "$i</a>\n";
+		    }
+    	    }
+        }
+    }
+    print HTMLTOP "</ul>\n";
+    print HTMLTOP "<hr>This source tree was made with ";
+    print HTMLTOP "<a href=\"http://minnie.cs.adfa.oz.au/Src2html/index.html";
+    print HTMLTOP "\">src2html</a>.</body>\n";
+    close(HTMLTOP);
+}
+
+
+## rewrite_src: Reread the ctags file for the given directory, and
+## rewrite the source code, adding in anchor points and bolding symbols.
+## This is messy as we can have multiple symbols on a single source line,
+## therefore we must buffer each line while reading from the ctags file.
+##
+sub rewrite_src {
+    local($dir)= $_[0];
+    local($i);
+    local($file)="";
+    local($line)="";
+    local($symb);
+    local($cnt);
+    local($nextcnt);
+
+    $In_file=0;
+    open(CTAGS,"sort +2 -3 +1n -2 $Ctagsfile{$dir} |")
+	|| die "$0: Can't open sorted $Ctagsfile{$dir}, $!\n";
+    if ($Debug > 0) { print "Rewriting source in $dir\n"; }
+    while (<CTAGS>) {
+					# Get the next file, line, symbol
+	if (/^(\w+)\s+(\d+)\s+([A-Za-z0-9_\+\-\.\/]+)/) {
+            if ($Debug > 2) { print "Symb $1 at $2 in $3\n"; }
+	    $nextcnt= $2; $symb=$1;
+					# If it's in a new file
+	    if ("$file" ne "$3") {
+					# Print out the remainder of the
+					# current file, incl. the buffered line
+		if ($In_file == 1) {
+		    if ("$line" ne "") { print OUT $line; }
+		    while (<IN>) {
+	                s/\&/&amp;/g; s/\</&lt;/g; s/\>/&gt;/g; print OUT;
+		    }
+		    print OUT "\n\n\n\n\n\n\n\n\n\n</pre></body>\n";
+		    close(IN); close(OUT);
+		}
+		$file= "$3";
+					# Open the new file & do the preamble
+		open(IN, "$Srctree/$file") ||
+		    print "Cannot open $Srctree/$file\n";
+		open(OUT, "> $Htmltree/$Newsrctree/$file.html");
+		$In_file=1;
+		print OUT "<head>\n<title>$file Source</title>\n";
+		print OUT "</head><body>\n";
+		print OUT "<h1>Source to $file</h1>\n";
+		if (defined($Formdir)) {
+        	    print OUT "<hr><form action=\"$Formdir/src2html.cgi\" ";
+	 	    print OUT "method=\"POST\">\n";
+        	    print OUT "<input type=\"submit\" value=\"Search\">\n";
+        	    print OUT "<input type= \"text\" ";
+		    print OUT "name=\"$Htmldir/$Newsrctree\">\n";
+		    print OUT "Enter a symbol's name here to quickly find it.\n";
+		    print OUT "</form><hr>\n";
+		}
+		print OUT "<pre>\n";
+					# Get the first line
+		$cnt=1; $line = <IN>;
+	        $line=~ s/\&/&amp;/g;
+	        $line=~ s/\</&lt;/g;
+	        $line=~ s/\>/&gt;/g;
+	    }
+	}
+					# Print all lines until one with a symb
+	while ($cnt < $nextcnt) {
+	    print OUT $line; $cnt++; $line= <IN>;
+	    $line=~ s/\&/&amp;/g;
+	    $line=~ s/\</&lt;/g;
+	    $line=~ s/\>/&gt;/g;
+	}
+						# Now rewrite the line
+	$line=~ s/$symb/<a name="$symb"<\/a><b>$symb<\/b>/;
+	next;
+    }
+    close(CTAGS); close(IN); close(OUT);
+}
Index: doc/tools/src2html1.4a/src2html.1
===================================================================
--- doc/tools/src2html1.4a/src2html.1	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/src2html.1	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,244 @@
+.TH src2html 1L "June 1994"
+.SH NAME
+src2html \- Hyperlink a C source code tree  using HTML, Version 1.3-alpha
+
+.SH SYNOPSIS
+.B src2html
+[
+.I \-na
+] [
+.I \-nl
+] [
+.I \-d debug_level
+]
+.I configuration_file
+
+.SH DESCRIPTION
+
+.B src2html
+is a program which takes a C source tree and creates a set of
+HTML hypertext documents that allows the most important symbols in the
+source tree to be found easily. As well, a HTML version of the source
+tree is created, with the symbols given in bold font where they are defined
+in the source.
+
+.B src2html
+finds and hyperlinks the following C symbols: Preprocessor defines
+and macros, C functions, global variables, structs, unions, enums and typedefs.
+If defined in the
+.I configuration file,
+a query document is used so that symbols can be located by an index query
+as well as following the hyperlinks.
+
+.SH OPTIONS
+The
+.I debug level
+was used when debugging the program, and its only use is
+to assure the user that something is actually happening, especially for large
+source trees. The highest debug level of 3 is not particularly verbose.
+.PP
+By default,
+.B src2html
+produces html pages for each category of C symbols. If there are more than
+50 in each category,
+.B src2html
+then further subdivides the symbols on a first-letter basis, making HTML
+documents for each letter.
+.PP
+If the
+.I -nl
+flag is set, no first-letter HTML documents will ever be produced.
+Similarly,
+.B src2html
+creates a top-level document with category links. If the
+.I -na
+flag is set, no top-level category links will be produced.
+
+.SH CONFIGURATION FILE
+
+.B src2html
+takes as an argument a
+.I configuration file
+which describes the directories in a source tree to process, and
+where to place the resulting HTML documents. Lines beginning with a #
+sign are ignored, as are blank lines. The following lines have special meaning:
+.P
+.IP "set Srctree source_tree"
+Set the root of the tree where the original source is kept, e.g
+/usr/src/sys. Do not leave a trailing slash on the tree name.
+This line must appear in the configuration file.
+.P
+.IP "set Htmlroot html_tree"
+Set the root of the tree where HTML documents are normally kept.
+This is the same as DocumentRoot in the httpd(1L) configuration.
+Again, do not leave a trailing slash on the tree name.
+This line must appear in the configuration file.
+.P
+.IP "set Htmldir html_dir"
+Set the directory within Htmlroot where the HTML documents for this
+tree will be placed.
+Again, do not leave a trailing slash on the tree name.
+This line must appear in the configuration file.
+.P
+.IP "set Newsrctree new_source_tree"
+Set the directory within the Htmltree where the marked up source code
+is placed, e.g src. This allows the source to be kept separate from the
+`pointer' documents which point at the source; see the next section for
+more details. This line is optional, and the default value of
+Newsrctree is `newsrc'.
+.P
+.IP "set Headers header_dir"
+.B src2html
+allows information to be placed at the beginning of the HTML
+documents created, e.g to describe the contents of a particular
+subdirectory. Files containing this information are kept in this
+directory. This line is optional, and the default value of
+Headers is `.'.
+.P
+.IP "set Formdir form_dir"
+If set, this tells
+.B src2html
+that the active HTML document which can
+perform index lookups for the source tree is located in this
+directory. If not set,
+.B src2html
+will not put query boxes in the
+HTML documents created. This line is optional, and there is no
+default value.
+.P
+.IP "dir directory comments_about_the_dir"
+This line may appear may times, and tells
+.B src2html
+to process
+source files in the directory Srctree/dir. This allows only particular
+sections of the source tree to be marked up. The comments after the
+directory are placed in the top-level HTML document to explain
+what that directory contains.
+
+.SH DIRECTORY STRUCTURE
+
+.B src2html
+expects to be given a source tree to process, and it produces
+a new tree with HTML documents. The configuration file should have a suffix
+of `.s2h', although this is strictly not needed.
+
+As an example, consider the following configuration file named BSD.s2h:
+.PP
+.nf
+# Comments
+set Srctree /usr/src/sys
+set Htmltree /usr/local/WWW
+set Htmldir sys
+set Newsrctree newsrc				# Comments here too
+set Headers /home/staff/warren/sys_headers
+set Formdir /cgi
+dir kern        The core OS routines: processes, scheduling, syscalls
+dir sys         Widely used C-language include files
+dir i386/isa    Device drivers for peripherals on the ISA bus
+.fi
+.PP
+Three directories containing C source will be processed,
+.nf
+	/usr/src/sys/kern,
+	/usr/src/sys/sys and
+	/usr/src/sys/i386/isa
+.fi
+
+The resulting marked up source code will be placed in
+.nf
+	/usr/local/WWW/sys/newsrc/kern,
+	/usr/local/WWW/sys/newsrc/sys and
+	/usr/local/WWW/sys/newsrc/i386/isa
+.fi
+respectivey.
+.PP
+The directory /usr/local/WWW/sys will itself contain a set of pointer
+documents which point to the source code documents on a per-directory,
+per-symbol-type and per-first-letter basis (and combinations of the
+above). One file, BSD.html (named from the configuration file name), is the
+root of the hyperlinks, and the entire source tree can be browsed from this
+one document.
+
+.SH HEADER FILES
+
+.B src2html
+creates a root HTML document, and HTML documents for each directory
+named in the configuration file. Textual information can be placed in the
+head of these documents to describe the contents of the tree/directory,
+give references etc. The files that hold this information are kept in the
+Headers directory. Taking the above configuration file as an example,
+
+	/home/staff/warren/sys_headers/BSD.hdr
+	/home/staff/warren/sys_headers/kern.hdr
+	/home/staff/warren/sys_headers/sys.hdr
+	/home/staff/warren/sys_headers/i386.isa.hdr
+
+can hold the information to be placed in the head of the appropriate
+documents. Note that if a directory name has a slash as given in the
+configuration file, the name of the header file has a dot instead.
+.PP
+Header files are placed `as is' into the head of the document, and thus
+can contain HTML markup commands. Any and all header files are optional;
+if the file does not exist, nothing will be placed in the head of the
+appropriate HTML document.
+.PP
+Once
+.B src2html
+has completed, the header files may be removed. However,
+you may wish to keep them in case you ever need to re-run
+.B src2html
+on the same source tree.
+
+.SH SEARCH SCRIPT
+
+During execution,
+.B src2html
+builds a ctags directory in Htmltree and places
+the output of ctags-new(1L) on the source tree directories in this place.
+This information is needed if a search script is also requested.
+.PP
+If the Formdir is set in the configuration file,
+.B src2html
+will configure the HTML code produced to use the search script
+.I src2html.cgi
+to search for symbols in the source tree. This script
+conforms to the cgi query format as used by httpd(1). You must move the
+supplied
+.I src2html.cgi
+file into the Formdir in the httpd hierachy before the query functionality
+can be used.
+.PP
+Again, from the example configuration file above,
+/usr/local/httpd/cgi/src2html.cgi is where to place the script, if the
+httpd hierachy is kept in /usr/local/httpd.
+
+.SH EXAMPLE SOURCE TREE
+
+The output from
+.B src2html
+for the full FreeBSD 2.0.5 kernel source directory can be browsed
+from the Web page http://minnie.cs.adfa.oz.au/FreeBSD-srctree/FreeBSD.html.
+
+.SH BUGS AND SHORTCOMINGS
+
+.B src2html
+uses the ctags-new(1L) program, which does not correctly parse C variable
+declarations and function pointer usage. Someone should rewrite this in Perl.
+.PP
+Ideally,
+.B src2html
+should include hyperlinks within each source file,
+but this is difficult given C's scoping rules, and would need a more
+sophisticated parser than ctags(1L).
+.PP
+.B src2html
+looks at all files in the named source directories, including
+files that don't end in .c and .h. This may be construed as a feature.
+
+.SH SEE ALSO
+.PD
+ctags-new(1L), httpd(1L), perl(1L)
+
+.SH AUTHOR
+.PD
+Warren Toomey   wkt@cs.adfa.oz.au
Index: doc/tools/src2html1.4a/src2html.cgi
===================================================================
--- doc/tools/src2html1.4a/src2html.cgi	(revision 52461c587563822939b238379bb1d72975e80b62)
+++ doc/tools/src2html1.4a/src2html.cgi	(revision 52461c587563822939b238379bb1d72975e80b62)
@@ -0,0 +1,100 @@
+#!/usr/local/bin/perl
+#
+# src2html.cgi -- A search script to file symbols in a src2html tree.
+# You need to install this in your httpd script directory AND set the
+# httpd web root below.
+#
+# We need the cgi-lib.pl package to be available to Perl
+require 'cgi-lib.pl';
+#
+## We MUST know the root of the httpd server, so we can find the ctags
+## 
+#
+$Http_root= "/usr/pub/pub/www";
+
+						# Parse input -> %in
+&ReadParse;					# and print first 2 lines
+
+@keys= keys(%in);			# We only expect one name/val pair
+if ($#keys != 0) {			# Otherwise, return an error document
+    print <<"query_error";
+Content-type: text/html
+
+    <header><title>Query Error</title></header><body>
+    <h1>Query Error</h1>
+    The document you used to query this source tree has an error in it.
+    You should email the maintainer of the source tree with a copy of the
+    document with the query form in it.
+    </body>
+query_error
+    exit(1);
+}
+					# Given the name, determine which tree
+$Htmltree= "$Http_root/$keys[0]"; 
+$Htmltree=~ s/\/[^\/]*$//;		# Location of the Html tree root
+$Srctree= "/$keys[0]";			# URL of the actual source
+$Ctags= "$Htmltree/ctags";		# Location of the ctags files
+
+@symbol= split(/\s+/, $in{$keys[0]});	# Get one symbol to search for
+
+if ($#symbol != 0) {			# Hmm, <> 1 symbol, return an error
+    print <<"symbol_error";
+Content-type: text/html
+
+    <header><title>$Htmltree Search Error</title></header><body>
+    <h1>$Htmltree Search Error</h1>
+    Hmm, you either sent in no symbols to me to search, or a number of
+    symbols to find, separated by whitespace.<p>
+    The search function can only handle regexp expressions with no 
+    whitespace. Try resubmitting your query.
+    </body>
+symbol_error
+    exit(1);
+}
+					# Let's go to work, egrep the ctags
+
+# Naftali Schwartz (nschwart@SLINKY.CS.NYU.EDU) reports that using the ^
+# on the following line stops the script from working under SunOS 4.1.3.
+# Sounds like ctags-new doesn't start the symbol in the 1st column.
+open(IN, "cat $Ctags/* | egrep ^$symbol[0] |") || die "$0: egrep failed\n";
+$cnt=0;
+while(<IN>) {
+    ($sym, $line, $file, $com)= split(/\s+/);
+    $Sym[$cnt]=$sym; $Line[$cnt]= $line; $File[$cnt]= $file; $cnt++;
+}
+close(IN);
+					# How many did we get? Zero, no symbol
+if ($cnt == 0) {
+    print <<"symbol_missing";
+Content-type: text/html
+
+    <header><title>$Htmltree Search Error</title></header><body>
+    <h1>$Htmltree Search Error</h1>
+    The symbol $symbol[0] does not appear in the source tree.
+    </body>
+symbol_missing
+    exit(1);
+}
+
+if ($cnt == 1) {			# Exactly one, return ptr to that doc
+    print "Location: $Srctree/$File[0]";
+
+# I used to use the commented out line under NCSA httpd because the other
+# line didn't work. You may need to try things out on your server.
+    print ".html\#$Sym[0]\n\n";
+#   print ".html\n\n";
+    exit(0);
+}
+					# Else return a list of choices
+print <<"many_found";
+Content-type: text/html
+
+<header><title>$Htmltree Search</title></header><body>
+<h1>$Htmltree Search</h1><ul>
+many_found
+for ($i = 0; $i < $cnt; $i++) {
+    print "<li><a href= \"$Srctree/$File[$i]";
+    print ".html#$Sym[$i]\">$Sym[$i]</a> $File[$i]:$Line[$i]\n";
+}
+print "</ul></body>\n";
+exit(0);
