summaryrefslogtreecommitdiff
path: root/web/glasgow/lit2x-0.16/grasp-utils
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/glasgow/lit2x-0.16/grasp-utils
Initial commit
Diffstat (limited to 'web/glasgow/lit2x-0.16/grasp-utils')
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/Jmakefile6
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/Makefile.BOOT58
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/PATCHLEVEL1
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/README48
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/etags/Jmakefile5
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/etags/README2
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/etags/etags.c1757
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/etags/jbw-fixes568
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/etags/wells-fixes545
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/msub/Jmakefile7
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/msub/msub.c520
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/msub/msub.ms128
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/msub/test.makefile18
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/msub/test.stdout11
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/msub/testfile11
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/perl-4.035-fixes180
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/Jmakefile79
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/fastmake.prl126
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/lmake.sh2
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.c217
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.man61
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.sh85
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/ltx.prl215
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/m5.prl502
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdependC.prl186
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.man15
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.sh24
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/mkshadowfile.sh26
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/moan-if-old.prl49
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/perltags.prl69
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/runstdtest.prl184
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/scripts/zap-if-same.prl50
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/verbatim/Jmakefile4
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.c533
-rw-r--r--web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.lex57
35 files changed, 6349 insertions, 0 deletions
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/Jmakefile b/web/glasgow/lit2x-0.16/grasp-utils/Jmakefile
new file mode 100644
index 0000000000..96625e3d52
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/Jmakefile
@@ -0,0 +1,6 @@
+#define IHaveSubdirs
+
+SUBDIRS = scripts \
+ msub \
+ etags \
+ verbatim
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/Makefile.BOOT b/web/glasgow/lit2x-0.16/grasp-utils/Makefile.BOOT
new file mode 100644
index 0000000000..16179c7df1
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/Makefile.BOOT
@@ -0,0 +1,58 @@
+# hand-hacked Makefile to boot the "make world" process
+#---------------------------------------------------------------------
+
+# Platform-specific configuration stuff was read from: sun.cf
+
+SHELL = /bin/sh
+PATHSEP = /
+
+TOP = ..
+CURRENT_DIR = ./grasp-utils
+
+RM=rm -f
+MV=mv -f
+BOOTSTRAPCFLAGS =
+
+# Project identification -- name, version, and stuff
+
+PROJECTNAME = Booting the Make World System
+PROJECTVERSION = none
+PROJECTLABEL = none
+SETUPLABEL = std
+
+PROJECTCONFIGDIR =
+
+###########################################################################
+# Configuration stuff (jmake, its friends and templates)
+
+JMKMF = jmkmf_used_only_with_installed_utils
+JRESTOREDEPS = $(JMAKESRC)/jrestoredeps
+JMAKE = $(JMAKESRC)/jmake
+JMAKE_DEFINES =
+
+JMAKESRC = $(TOP)/mkworld
+
+JMAKE_CMD = $(NEWTOP)$(JMAKE) -I$(NEWTOP)$(JMAKESRC) $(BOOTSTRAPCFLAGS) -DTopDir=$(TOP) -DCurDir=$(CURRENT_DIR) $(BOOT_DEFINES)
+
+###########################################################################
+
+Makefile:: $(JMAKE)
+
+$(JMAKE):
+ @(cd $(JMAKESRC); if [ -f Makefile ]; then \
+ echo "checking $@ in $(JMAKESRC) first..."; $(MAKE) all; else \
+ echo "bootstrapping $@ from Makefile.BOOT in $(JMAKESRC) first..."; \
+ $(MAKE) -f Makefile.BOOT BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS); fi; \
+ echo "okay, continuing in $(CURRENT_DIR)")
+
+Makefile::
+ -@if [ -f Makefile ]; then \
+ echo " $(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(JMAKE_CMD)
+ $(JRESTOREDEPS)
+ @if cmp -s Makefile Makefile.bak; then $(RM) Makefile.bak ; fi
+ @chmod 444 Makefile
+ @echo ==== The new Makefile is for\: ====
+ @$(MAKE) whoami
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/PATCHLEVEL b/web/glasgow/lit2x-0.16/grasp-utils/PATCHLEVEL
new file mode 100644
index 0000000000..9667fc05ed
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/PATCHLEVEL
@@ -0,0 +1 @@
+Miscellaneous GRASP-project tools, version 0.16, patchlevel 0
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/README b/web/glasgow/lit2x-0.16/grasp-utils/README
new file mode 100644
index 0000000000..a98feebe81
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/README
@@ -0,0 +1,48 @@
+This directory tree's worth of stuff are utility bits that are used in
+more than one of our GRASP projects. (For the project-specific bits,
+try <project>/utils/<blah>.)
+
+msub/ a utility from Paul DuBois, that lets you substitute
+ for make variables (e.g., $(CC) ) in any old document.
+ Given that, with the "make world" configuration
+ system, Makefiles have loads of useful config info in
+ them, this is the program used to sneak that info into
+ other files.
+
+ugen/ A utility from the LML-compiler distrib to support
+ poor man's abstract data types for C. Used in the
+ parser ($(TOP)/parsers/hsp).
+
+scripts/ little utility scripts
+
+ lndir from X imake stuff (via DuBois); make a shadow tree
+ of symbolic links
+ mkdirhier "mkdir a/b/c/d" will do "mkdir a; mkdir a/b; ..."
+ (assuming none of those dirs exist)
+
+ runstdtest runs a pgm with some flags & some stdin; checks for an
+ expected exit code, expected stdout, and expected
+ stderr. (Expect this to change :-)
+
+ newer "newer a b" (obsolete?) exit code 0 if file "a" newer
+ than "b", or something like that...
+
+ tidycpp, hscpp cpp (C pre-processor) wrappers, the latter for
+ Haskell, the former obsolete?
+
+ mkdependC script version of C makedepend (from X11R4 via DuBois)
+ mkdependHS "make depend" (perl) script for Haskell code.
+
+ mkdependLML simon's makedepend1 script (needs work to function here)
+ (NOT BUILT)
+
+ fastmake a "make" wrapper for compiling Haskell programs;
+ essentially, strips out the "make depend"ed
+ dependencies to avoid so much re-checking.
+
+ update_iface a REALLY HORRIBLE hack, for updating the new Haskell
+ compiler's interface files; covers for deficiencies in
+ "nhc" (prototype compiler) i/face handling.
+
+ ltx a "latex" wrapper. Re-runs latex/bibtex/makeindex
+ enough times to "do the right thing."
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/etags/Jmakefile b/web/glasgow/lit2x-0.16/grasp-utils/etags/Jmakefile
new file mode 100644
index 0000000000..cadc4636d6
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/etags/Jmakefile
@@ -0,0 +1,5 @@
+BuildPgmFromOneCFile(etags)
+
+InstallBinaryTarget(etags,$(INSTBINDIR))
+
+CDependTarget( $(SRCS_C) )
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/etags/README b/web/glasgow/lit2x-0.16/grasp-utils/etags/README
new file mode 100644
index 0000000000..fb033eabe1
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/etags/README
@@ -0,0 +1,2 @@
+This is the "etags" program from the GNU emacs (18.??) distribution.
+Kevin Hammond has hacked it slightly to recognise more kinds of files.
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/etags/etags.c b/web/glasgow/lit2x-0.16/grasp-utils/etags/etags.c
new file mode 100644
index 0000000000..5abb1990a1
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/etags/etags.c
@@ -0,0 +1,1757 @@
+/* Tags file maker to go with GNUmacs
+ Copyright (C) 1984, 1987, 1988 Free Software Foundation, Inc. and Ken Arnold
+
+ NO WARRANTY
+
+ BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
+NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
+WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
+RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
+AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
+STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
+WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
+OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
+DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
+A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
+PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+
+ GENERAL PUBLIC LICENSE TO COPY
+
+ 1. You may copy and distribute verbatim copies of this source file
+as you receive it, in any medium, provided that you conspicuously
+and appropriately publish on each copy a valid copyright notice
+"Copyright (C) 1986 Free Software Foundation"; and include
+following the copyright notice a verbatim copy of the above disclaimer
+of warranty and of this License.
+
+ 2. You may modify your copy or copies of this source file or
+any portion of it, and copy and distribute such modifications under
+the terms of Paragraph 1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish,
+ that in whole or in part contains or is a derivative of this
+ program or any part thereof, to be licensed at no charge to all
+ third parties on terms identical to those contained in this
+ License Agreement (except that you may choose to grant more extensive
+ warranty protection to some or all third parties, at your option).
+
+ c) You may charge a distribution fee for the physical act of
+ transferring a copy, and you may at your option offer warranty
+ protection in exchange for a fee.
+
+Mere aggregation of another unrelated program with this program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other program under the scope of these terms.
+
+ 3. You may copy and distribute this program (or a portion or derivative
+of it, under Paragraph 2) in object code or executable form under the terms
+of Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal
+ shipping charge) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+For an executable file, complete source code means all the source code for
+all modules it contains; but, as a special exception, it need not include
+source code for modules which are standard libraries that accompany the
+operating system on which the executable file runs.
+
+ 4. You may not copy, sublicense, distribute or transfer this program
+except as expressly provided under this License Agreement. Any attempt
+otherwise to copy, sublicense, distribute or transfer this program is void and
+your rights to use the program under this License agreement shall be
+automatically terminated. However, parties who have received computer
+software programs from you with this License Agreement will not have
+their licenses terminated so long as such parties remain in full compliance.
+
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them. Help stamp out software-hoarding! */
+
+#include <stdio.h>
+#include <ctype.h>
+
+/* Define the symbol ETAGS to make the program "etags",
+ which makes emacs-style tag tables by default.
+ Define CTAGS to make the program "ctags" compatible with the usual one.
+ Define neither one to get behavior that depends
+ on the name with which the program is invoked
+ (but we don't normally compile it that way). */
+
+/* On VMS, CTAGS is not useful, so always do ETAGS. */
+#ifdef VMS
+#ifndef ETAGS
+#define ETAGS
+#endif
+#endif
+
+/* Exit codes for success and failure. */
+
+#ifdef VMS
+#define GOOD (1)
+#define BAD (0)
+#else
+#define GOOD (0)
+#define BAD (1)
+#endif
+
+#define reg register
+#define logical char
+
+#define TRUE (1)
+#define FALSE (0)
+
+#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 ')' */
+
+#define max(I1,I2) (I1 > I2 ? I1 : I2)
+
+/* cause token checking for typedef, struct, union, enum to distinguish
+ keywords from identifier-prefixes (e.g. struct vs struct_tag). */
+#define istoken(s, tok, len) (!strncmp(s,tok,len) && endtoken(*((s)+(len))))
+
+struct nd_st { /* sorting structure */
+ char *name; /* function or type name */
+ char *file; /* file name */
+ logical f; /* use pattern or line no */
+ int lno; /* line number tag is on */
+ long cno; /* character number line starts on */
+ char *pat; /* search pattern */
+ logical been_warned; /* set if noticed dup */
+ struct nd_st *left,*right; /* left and right sons */
+};
+
+long ftell();
+typedef struct nd_st NODE;
+
+int number; /* tokens found so far on line starting with # (including #) */
+logical gotone, /* found a func already on line */
+ /* boolean "func" (see init) */
+ _wht[0177],_etk[0177],_itk[0177],_btk[0177],_gd[0177];
+
+ /* typedefs are recognized using a simple finite automata,
+ * tydef is its state variable.
+ */
+typedef enum {none, begin, tag_ok, middle, end } TYST;
+
+TYST tydef = none;
+
+char searchar = '/'; /* use /.../ searches */
+
+int lineno; /* line number of current line */
+long charno; /* current character number */
+long linecharno; /* character number of start of line */
+
+char *curfile, /* current input file name */
+ *outfile= 0, /* output file */
+ *white = " \f\t\n", /* white chars */
+ *endtk = " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?",
+ /* token ending chars */
+ *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$",
+ /* token starting chars */
+ *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789",
+ /* valid in-token chars */
+ *notgd = ",;"; /* non-valid after-function chars */
+
+int file_num = 0; /* current file number */
+int aflag = 0; /* -a: append to tags */
+int tflag = 0; /* -t: create tags for typedefs */
+int uflag = 0; /* -u: update tags */
+int wflag = 0; /* -w: suppress warnings */
+int vflag = 0; /* -v: create vgrind style index output */
+int xflag = 0; /* -x: create cxref style output */
+int eflag = 0; /* -e: emacs style output */
+
+/* Name this program was invoked with. */
+char *progname;
+
+FILE *inf, /* ioptr for current input file */
+ *outf; /* ioptr for tags file */
+
+NODE *head; /* the head of the sorted binary tree */
+
+char *savestr();
+char *savenstr ();
+char *rindex();
+char *index();
+char *concat ();
+void initbuffer ();
+long readline ();
+
+/* A `struct linebuffer' is a structure which holds a line of text.
+ `readline' reads a line from a stream into a linebuffer
+ and works regardless of the length of the line. */
+
+struct linebuffer
+ {
+ long size;
+ char *buffer;
+ };
+
+struct linebuffer lb, lb1;
+
+#if 0 /* VMS now provides the `system' function. */
+#ifdef VMS
+
+#include <descrip.h>
+
+void
+system (buf)
+ char *buf;
+{
+ struct dsc$descriptor_s command =
+ {
+ strlen(buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf
+ };
+
+ LIB$SPAWN(&command);
+}
+#endif /* VMS */
+#endif /* 0 */
+
+main(ac,av)
+ int ac;
+ char *av[];
+{
+ char cmd[100];
+ int i;
+ int fflag = 0;
+ char *this_file;
+#ifdef VMS
+ char got_err;
+
+ extern char *gfnames();
+ extern char *massage_name();
+#endif
+
+ progname = av[0];
+
+#ifdef ETAGS
+ eflag = 1;
+#else
+#ifdef CTAGS
+ eflag = 0;
+#else
+ {
+ char *subname = rindex (progname, '/');
+ if (subname++ == NULL)
+ subname = progname;
+ eflag = ! strcmp(subname, "ctags");
+ }
+#endif
+#endif
+
+ while (ac > 1 && av[1][0] == '-')
+ {
+ for (i=1; av[1][i]; i++)
+ {
+ switch(av[1][i])
+ {
+#ifndef VMS /* These options are useful only with ctags,
+ and VMS can't input them, so just omit them. */
+ case 'B':
+ searchar='?';
+ eflag = 0;
+ break;
+ case 'F':
+ searchar='/';
+ eflag = 0;
+ break;
+#endif
+ case 'a':
+ aflag++;
+ break;
+ case 'e':
+ eflag++;
+ break;
+ case 'f':
+ if (fflag > 0)
+ {
+ fprintf(stderr,
+ "%s: -f flag may only be given once\n", progname);
+ goto usage;
+ }
+ fflag++, ac--; av++;
+ if (ac <= 1 || av[1][0] == '\0')
+ {
+ fprintf(stderr,
+ "%s: -f flag must be followed by a filename\n",
+ progname);
+ goto usage;
+ }
+ outfile = av[1];
+ goto end_loop;
+ case 't':
+ tflag++;
+ break;
+#ifndef VMS
+ case 'u':
+ uflag++;
+ eflag = 0;
+ break;
+#endif
+ case 'w':
+ wflag++;
+ break;
+ case 'v':
+ vflag++;
+ xflag++;
+ eflag = 0;
+ break;
+ case 'x':
+ xflag++;
+ eflag = 0;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ end_loop: ;
+ ac--; av++;
+ }
+
+ if (ac <= 1)
+ {
+ usage:
+#ifdef VMS
+ fprintf (stderr, "Usage: %s [-aetwvx] [-f outfile] file ...\n", progname);
+#else
+ fprintf (stderr, "Usage: %s [-BFaetuwvx] [-f outfile] file ...\n", progname);
+#endif
+ exit(BAD);
+ }
+
+ if (outfile == 0)
+ {
+ outfile = eflag ? "TAGS" : "tags";
+ }
+
+ init(); /* set up boolean "functions" */
+
+ initbuffer (&lb);
+ initbuffer (&lb1);
+ /*
+ * loop through files finding functions
+ */
+ if (eflag)
+ {
+ outf = fopen (outfile, aflag ? "a" : "w");
+ if (!outf)
+ {
+ fprintf (stderr, "%s: ", progname);
+ perror (outfile);
+ exit (BAD);
+ }
+ }
+
+ file_num = 1;
+#ifdef VMS
+ for (ac--, av++;
+ (this_file = gfnames (&ac, &av, &got_err)) != NULL; file_num++)
+ {
+ if (got_err)
+ {
+ error("Can't find file %s\n", this_file);
+ ac--, av++;
+ }
+ else
+ {
+ this_file = massage_name (this_file);
+#else
+ for (; file_num < ac; file_num++)
+ {
+ this_file = av[file_num];
+ if (1)
+ {
+#endif
+ find_entries (this_file);
+ if (eflag)
+ {
+ fprintf (outf, "\f\n%s,%d\n",
+ this_file, total_size_of_entries (head));
+ put_entries (head);
+ free_tree (head);
+ head = NULL;
+ }
+ }
+ }
+
+ if (eflag)
+ {
+ fclose (outf);
+ exit (GOOD);
+ }
+
+ if (xflag)
+ {
+ put_entries(head);
+ exit(GOOD);
+ }
+ if (uflag)
+ {
+ for (i=1; i<ac; i++)
+ {
+ sprintf(cmd,
+ "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
+ outfile, av[i], outfile);
+ system(cmd);
+ }
+ aflag++;
+ }
+ outf = fopen(outfile, aflag ? "a" : "w");
+ if (outf == NULL)
+ {
+ fprintf (stderr, "%s: ", outfile);
+ perror(outfile);
+ exit(BAD);
+ }
+ put_entries(head);
+ fclose(outf);
+#ifndef VMS
+ if (uflag)
+ {
+ sprintf(cmd, "sort %s -o %s", outfile, outfile);
+ system(cmd);
+ }
+#endif
+ exit(GOOD);
+}
+
+/*
+ * This routine sets up the boolean psuedo-functions which work
+ * by seting boolean flags dependent upon the corresponding character
+ * Every char which is NOT in that string is not a white char. Therefore,
+ * all of the array "_wht" is set to FALSE, and then the elements
+ * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
+ * of a char is TRUE if it is the string "white", else FALSE.
+ */
+init()
+{
+
+ reg char *sp;
+ reg int i;
+
+ for (i = 0; i < 0177; i++)
+ {
+ _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE;
+ _gd[i] = TRUE;
+ }
+ for (sp = white; *sp; sp++)
+ _wht[*sp] = TRUE;
+ for (sp = endtk; *sp; sp++)
+ _etk[*sp] = TRUE;
+ for (sp = intk; *sp; sp++)
+ _itk[*sp] = TRUE;
+ for (sp = begtk; *sp; sp++)
+ _btk[*sp] = TRUE;
+ for (sp = notgd; *sp; sp++)
+ _gd[*sp] = FALSE;
+ _wht[0] = _wht['\n'];
+ _etk[0] = _etk['\n'];
+ _btk[0] = _btk['\n'];
+ _itk[0] = _itk['\n'];
+ _gd[0] = _gd['\n'];
+}
+
+/*
+ * This routine opens the specified file and calls the function
+ * which finds the function and type definitions.
+ */
+find_entries (file)
+ char *file;
+{
+ char *cp;
+
+ if ((inf=fopen(file,"r")) == NULL)
+ {
+ fprintf (stderr, "%s: ", progname);
+ perror(file);
+ return;
+ }
+ curfile = savestr(file);
+ cp = rindex(file, '.');
+ /* .tex, .aux or .bbl implies LaTeX source code */
+ if (cp && (!strcmp (cp + 1, "tex") || !strcmp (cp + 1, "aux")
+ || !strcmp (cp + 1, "bbl")))
+ {
+ TEX_funcs(inf);
+ fclose(inf);
+ return;
+ }
+ /* .l or .el or .lisp (or .cl or .clisp or ...) implies lisp source code */
+ if (cp && (!strcmp (cp + 1, "l") ||
+ !strcmp (cp + 1, "el") ||
+ !strcmp (cp + 1, "lsp") ||
+ !strcmp (cp + 1, "lisp") ||
+ !strcmp (cp + 1, "cl") ||
+ !strcmp (cp + 1, "clisp")))
+ {
+ L_funcs(inf);
+ fclose(inf);
+ return;
+ }
+ /* .scm or .sm or .scheme implies scheme source code */
+ if (cp && (!strcmp (cp + 1, "sm")
+ || !strcmp (cp + 1, "scm")
+ || !strcmp (cp + 1, "scheme")
+ || !strcmp (cp + 1, "t")
+ || !strcmp (cp + 1, "sch")
+ || !strcmp (cp + 1, "SM")
+ || !strcmp (cp + 1, "SCM")
+ /* The `SCM' or `scm' prefix with a version number */
+ || (cp[-1] == 'm' && cp[-2] == 'c' && cp[-3] == 's')
+ || (cp[-1] == 'M' && cp[-2] == 'C' && cp[-3] == 'S')))
+ {
+ Scheme_funcs(inf);
+ fclose(inf);
+ return;
+ }
+ /* .M implies Mcode source code */
+ if (cp && !strcmp (cp + 1, "M"))
+ {
+ Mcode_funcs(inf);
+ fclose(inf);
+ return;
+ }
+
+ /* if not a .c or .h or .y file, try fortran */
+ if (cp && (cp[1] != 'c' && cp[1] != 'h' && cp[1] != 'y')
+ && cp[2] == '\0')
+ {
+ if (PF_funcs(inf) != 0)
+ {
+ fclose(inf);
+ return;
+ }
+ rewind(inf); /* no fortran tags found, try C */
+ }
+ C_entries();
+ fclose(inf);
+}
+
+/* Record a tag on the current line.
+ name is the tag name,
+ f is nonzero to use a pattern, zero to use line number instead. */
+
+pfnote (name, f, linestart, linelen, lno, cno)
+ char *name;
+ logical f; /* f == TRUE when function */
+ char *linestart;
+ int linelen;
+ int lno;
+ long cno;
+{
+ register char *fp;
+ register NODE *np;
+ char *altname;
+ char tem[51];
+
+ if ((np = (NODE *) malloc (sizeof (NODE))) == NULL)
+ {
+ fprintf(stderr, "%s: too many entries to sort\n", progname);
+ put_entries(head);
+ free_tree(head);
+ head = NULL;
+ np = (NODE *) xmalloc(sizeof (NODE));
+ }
+ /* Change name "main" to M<thisfilename>. */
+ if (!eflag && !xflag && !strcmp(name, "main"))
+ {
+ fp = rindex(curfile, '/');
+ if (fp == 0)
+ fp = curfile;
+ else
+ fp++;
+ altname = concat ("M", fp, "");
+ fp = rindex(altname, '.');
+ if (fp && fp[2] == 0)
+ *fp = 0;
+ name = altname;
+ }
+ np->name = savestr(name);
+ np->file = curfile;
+ np->f = f;
+ np->lno = lno;
+ np->cno = cno;
+ np->left = np->right = 0;
+ if (eflag)
+ {
+ linestart[linelen] = 0;
+ }
+ else if (xflag == 0)
+ {
+ sprintf (tem, strlen (linestart) < 50 ? "%s$" : "%.50s", linestart);
+ linestart = tem;
+ }
+ np->pat = savestr (linestart);
+ if (head == NULL)
+ head = np;
+ else
+ add_node(np, head);
+}
+
+free_tree(node)
+ NODE *node;
+{
+ while (node)
+ {
+ free_tree(node->right);
+ free(node);
+ node = node->left;
+ }
+}
+
+add_node(node, cur_node)
+ NODE *node,*cur_node;
+{
+ register int dif;
+
+ dif = strcmp(node->name, cur_node->name);
+
+ /* If this tag name matches an existing one, then
+ unless -e was given, do not add the node, but maybe print a warning */
+ if (!eflag && !dif)
+ {
+ if (node->file == cur_node->file)
+ {
+ if (!wflag)
+ {
+ fprintf(stderr,"%s: Duplicate entry in file %s, line %d: %s\n",
+ progname, node->file,lineno,node->name);
+ fprintf(stderr,"Second entry ignored\n");
+ }
+ return;
+ }
+ if (!cur_node->been_warned)
+ if (!wflag)
+ fprintf(stderr,"%s: Duplicate entry in files %s and %s: %s (Warning only)\n",
+ progname, node->file, cur_node->file, node->name);
+ cur_node->been_warned = TRUE;
+ return;
+ }
+
+ /* Actually add the node */
+ if (dif < 0)
+ {
+ if (cur_node->left != NULL)
+ add_node(node,cur_node->left);
+ else
+ cur_node->left = node;
+ return;
+ }
+ if (cur_node->right != NULL)
+ add_node(node,cur_node->right);
+ else
+ cur_node->right = node;
+}
+
+put_entries(node)
+ reg NODE *node;
+{
+ reg char *sp;
+
+ if (node == NULL)
+ return;
+
+ /* Output subentries that precede this one */
+ put_entries (node->left);
+
+ /* Output this entry */
+
+ if (eflag)
+ {
+ fprintf (outf, "%s%c%d,%d\n",
+ node->pat, 0177, node->lno, node->cno);
+ }
+ else if (!xflag)
+ {
+ fprintf (outf, "%s\t%s\t",
+ node->name, node->file);
+
+ if (node->f)
+ { /* a function */
+ putc (searchar, outf);
+ putc ('^', outf);
+
+ for (sp = node->pat; *sp; sp++)
+ {
+ if (*sp == '\\' || *sp == searchar)
+ putc ('\\', outf);
+ putc (*sp, outf);
+ }
+ putc (searchar, outf);
+ }
+ else
+ { /* a typedef; text pattern inadequate */
+ fprintf (outf, "%d", node->lno);
+ }
+ putc ('\n', outf);
+ }
+ else if (vflag)
+ fprintf (stdout, "%s %s %d\n",
+ node->name, node->file, (node->lno+63)/64);
+ else
+ fprintf (stdout, "%-16s%4d %-16s %s\n",
+ node->name, node->lno, node->file, node->pat);
+
+ /* Output subentries that follow this one */
+ put_entries (node->right);
+}
+
+/* Return total number of characters that put_entries will output for
+ the nodes in the subtree of the specified node.
+ Works only if eflag is set, but called only in that case. */
+
+total_size_of_entries(node)
+ reg NODE *node;
+{
+ reg int total = 0;
+ reg long num;
+
+ if (node == NULL)
+ return 0;
+
+ /* Count subentries that precede this one */
+ total = total_size_of_entries (node->left);
+
+ /* Count subentries that follow this one */
+ total += total_size_of_entries (node->right);
+
+ /* Count this entry */
+
+ total += strlen (node->pat) + 3;
+
+ num = node->lno;
+ while (num)
+ {
+ total++;
+ num /= 10;
+ }
+
+ num = node->cno;
+ if (!num) total++;
+ while (num)
+ {
+ total++;
+ num /= 10;
+ }
+ return total;
+}
+
+/*
+ * This routine finds functions and typedefs in C syntax and adds them
+ * to the list.
+ */
+#ifdef VMS
+long vmslinecharno;
+#define VMS_SET_LINECHARNO (vmslinecharno = ftell(inf))
+#else
+#define VMS_SET_LINECHARNO
+#endif
+
+#define CNL_SAVE_NUMBER \
+{ \
+ VMS_SET_LINECHARNO; \
+ linecharno = charno; lineno++; \
+ charno += 1 + readline (&lb, inf); \
+ lp = lb.buffer; \
+}
+
+#define CNL \
+{ \
+ CNL_SAVE_NUMBER; \
+ number = 0; \
+}
+
+C_entries ()
+{
+ register int c;
+ register char *token, *tp, *lp;
+ logical incomm, inquote, inchar, midtoken;
+ int level;
+ char tok[BUFSIZ];
+
+ lineno = 0;
+ charno = 0;
+ lp = lb.buffer;
+ *lp = 0;
+
+ number = 0;
+ gotone = midtoken = inquote = inchar = incomm = FALSE;
+ level = 0;
+
+ while (!feof (inf))
+ {
+ c = *lp++;
+ if (c == 0)
+ {
+ CNL;
+ gotone = FALSE;
+ }
+ if (c == '\\')
+ {
+ c = *lp++;
+ if (c == 0)
+ CNL_SAVE_NUMBER;
+ c = ' ';
+ }
+ else if (incomm)
+ {
+ if (c == '*')
+ {
+ while ((c = *lp++) == '*')
+ continue;
+ if (c == 0)
+ CNL;
+ if (c == '/')
+ incomm = FALSE;
+ }
+ }
+ else if (inquote)
+ {
+ /*
+ * Too dumb to know about \" not being magic, but
+ * they usually occur in pairs anyway.
+ */
+ if (c == '"')
+ inquote = FALSE;
+ continue;
+ }
+ else if (inchar)
+ {
+ if (c == '\'')
+ inchar = FALSE;
+ continue;
+ }
+ else switch (c)
+ {
+ case '"':
+ inquote = TRUE;
+ continue;
+ case '\'':
+ inchar = TRUE;
+ continue;
+ case '/':
+ if (*lp == '*')
+ {
+ lp++;
+ incomm = TRUE;
+ }
+ continue;
+ case '#':
+ if (lp == lb.buffer + 1)
+ number = 1;
+ continue;
+ case '{':
+ if (tydef == tag_ok)
+ {
+ tydef=middle;
+ }
+ level++;
+ continue;
+ case '}':
+ if (lp == lb.buffer + 1)
+ level = 0; /* reset */
+ else
+ level--;
+ if (!level && tydef==middle)
+ {
+ tydef=end;
+ }
+ continue;
+ }
+ if (!level && !inquote && !incomm && gotone == FALSE)
+ {
+ if (midtoken)
+ {
+ if (endtoken(c))
+ {
+ int f;
+ char *buf = lb.buffer;
+ int endpos = lp - lb.buffer;
+ char *lp1 = lp;
+ int line = lineno;
+ long linestart = linecharno;
+#ifdef VMS
+ long vmslinestart = vmslinecharno;
+#endif
+ int tem = consider_token (&lp1, token, &f, level);
+ lp = lp1;
+ if (tem)
+ {
+ if (linestart != linecharno)
+ {
+#ifdef VMS
+ getline (vmslinestart);
+#else
+ getline (linestart);
+#endif
+ strncpy (tok, token + (lb1.buffer - buf),
+ tp-token+1);
+ tok[tp-token+1] = 0;
+ pfnote(tok, f, lb1.buffer, endpos, line, linestart);
+ }
+ else
+ {
+ strncpy (tok, token, tp-token+1);
+ tok[tp-token+1] = 0;
+ pfnote(tok, f, lb.buffer, endpos, line, linestart);
+ }
+ gotone = f; /* function */
+ }
+ midtoken = FALSE;
+ token = lp - 1;
+ }
+ else if (intoken(c))
+ tp++;
+ }
+ else if (begtoken(c))
+ {
+ token = tp = lp - 1;
+ midtoken = TRUE;
+ }
+ }
+ if (c == ';' && tydef==end) /* clean with typedefs */
+ tydef=none;
+ }
+}
+
+/*
+ * This routine checks to see if the current token is
+ * at the start of a function, or corresponds to a typedef
+ * It updates the input line * so that the '(' will be
+ * in it when it returns.
+ */
+consider_token (lpp, token, f, level)
+ char **lpp, *token;
+ int *f, level;
+{
+ reg char *lp = *lpp;
+ reg char c;
+ static logical next_token_is_func;
+ logical firsttok; /* T if have seen first token in ()'s */
+ int bad, win;
+
+ *f = 1; /* a function */
+ c = lp[-1];
+ bad = FALSE;
+ if (!number)
+ { /* space is not allowed in macro defs */
+ while (iswhite(c))
+ {
+ c = *lp++;
+ if (c == 0)
+ {
+ if (feof (inf))
+ break;
+ CNL;
+ }
+ }
+ }
+ else
+ {
+ /* the following tries to make it so that a #define a b(c) */
+ /* doesn't count as a define of b. */
+
+ number++;
+ if (number >= 4 || (number==2 && strncmp (token, "define", 6)==0))
+ {
+ /* Force the next symbol to be recognised, even if it is #define a b(c)! */
+ if(number == 2) next_token_is_func = 1;
+ else
+ gotone = TRUE;
+ badone:
+ bad = TRUE;
+ goto ret;
+ }
+ }
+ /* check for the typedef cases */
+ if (tflag && istoken(token, "typedef", 7))
+ {
+ tydef=begin;
+ goto badone;
+ }
+ if (tydef==begin && (istoken(token, "struct", 6) ||
+ istoken(token, "union", 5) || istoken(token, "enum", 4)))
+ {
+ tydef=tag_ok;
+ goto badone;
+ }
+ if (tydef==tag_ok)
+ {
+ tydef=middle;
+ goto badone;
+ }
+ if (tydef==begin) /* e.g. typedef ->int<- */
+ {
+ tydef=end;
+ goto badone;
+ }
+ if (tydef==middle && level == 0) /* e.g. typedef struct tag ->struct_t<- */
+ {
+ tydef=end;
+ }
+ if (tydef==end)
+ {
+ *f = 0;
+ win = 1;
+ goto ret;
+ }
+ /* Detect GNUmacs's function-defining macros. */
+ if (!number && !strncmp (token, "DEF", 3))
+
+ {
+ next_token_is_func = 1;
+ goto badone;
+ }
+ if (next_token_is_func)
+ {
+ next_token_is_func = 0;
+ win = 1;
+ goto ret;
+ }
+ if (c != '(')
+ goto badone;
+ firsttok = FALSE;
+ while ((c = *lp++) != ')')
+ {
+ if (c == 0)
+ {
+ if (feof (inf))
+ break;
+ CNL;
+ }
+ /*
+ * This line used to confuse ctags:
+ * int (*oldhup)();
+ * This fixes it. A nonwhite char before the first
+ * token, other than a / (in case of a comment in there)
+ * makes this not a declaration.
+ */
+ if (begtoken(c) || c=='/') firsttok++;
+ else if (!iswhite(c) && !firsttok) goto badone;
+ }
+ while (iswhite (c = *lp++))
+ {
+ if (c == 0)
+ {
+ if (feof (inf))
+ break;
+ CNL;
+ }
+ }
+ win = isgood (c);
+ret:
+ *lpp = lp - 1;
+ return !bad && win;
+}
+
+getline (atchar)
+ long atchar;
+{
+ long saveftell = ftell (inf);
+
+ fseek (inf, atchar, 0);
+ readline (&lb1, inf);
+ fseek (inf, saveftell, 0);
+}
+
+/* Fortran parsing */
+
+char *dbp;
+int pfcnt;
+
+PF_funcs(fi)
+ FILE *fi;
+{
+ lineno = 0;
+ charno = 0;
+ pfcnt = 0;
+
+ while (!feof (fi))
+ {
+ lineno++;
+ linecharno = charno;
+ charno += readline (&lb, fi) + 1;
+ dbp = lb.buffer;
+ if (*dbp == '%') dbp++ ; /* Ratfor escape to fortran */
+ while (isspace(*dbp))
+ dbp++;
+ if (*dbp == 0)
+ continue;
+ switch (*dbp |' ')
+ {
+ case 'i':
+ if (tail("integer"))
+ takeprec();
+ break;
+ case 'r':
+ if (tail("real"))
+ takeprec();
+ break;
+ case 'l':
+ if (tail("logical"))
+ takeprec();
+ break;
+ case 'c':
+ if (tail("complex") || tail("character"))
+ takeprec();
+ break;
+ case 'd':
+ if (tail("double"))
+ {
+ while (isspace(*dbp))
+ dbp++;
+ if (*dbp == 0)
+ continue;
+ if (tail("precision"))
+ break;
+ continue;
+ }
+ break;
+ }
+ while (isspace(*dbp))
+ dbp++;
+ if (*dbp == 0)
+ continue;
+ switch (*dbp|' ')
+ {
+ case 'f':
+ if (tail("function"))
+ getit();
+ continue;
+ case 's':
+ if (tail("subroutine"))
+ getit();
+ continue;
+ case 'p':
+ if (tail("program"))
+ {
+ getit();
+ continue;
+ }
+ if (tail("procedure"))
+ getit();
+ continue;
+ }
+ }
+ return (pfcnt);
+}
+
+tail(cp)
+ char *cp;
+{
+ register int len = 0;
+
+ while (*cp && (*cp&~' ') == ((*(dbp+len))&~' '))
+ cp++, len++;
+ if (*cp == 0)
+ {
+ dbp += len;
+ return (1);
+ }
+ return (0);
+}
+
+takeprec()
+{
+ while (isspace(*dbp))
+ dbp++;
+ if (*dbp != '*')
+ return;
+ dbp++;
+ while (isspace(*dbp))
+ dbp++;
+ if (!isdigit(*dbp))
+ {
+ --dbp; /* force failure */
+ return;
+ }
+ do
+ dbp++;
+ while (isdigit(*dbp));
+}
+
+getit()
+{
+ register char *cp;
+ char c;
+ char nambuf[BUFSIZ];
+
+ while (isspace(*dbp))
+ dbp++;
+ if (*dbp == 0 || !isalpha(*dbp))
+ return;
+ for (cp = dbp+1; *cp && (isalpha(*cp) || isdigit(*cp)); cp++)
+ continue;
+ c = cp[0];
+ cp[0] = 0;
+ strcpy(nambuf, dbp);
+ cp[0] = c;
+ pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
+ pfcnt++;
+}
+
+/*
+ * lisp tag functions
+ * just look for (def or (DEF
+ */
+
+L_funcs (fi)
+ FILE *fi;
+{
+ lineno = 0;
+ charno = 0;
+ pfcnt = 0;
+
+ while (!feof (fi))
+ {
+ lineno++;
+ linecharno = charno;
+ charno += readline (&lb, fi) + 1;
+ dbp = lb.buffer;
+ if (dbp[0] == '(' &&
+ (dbp[1] == 'D' || dbp[1] == 'd') &&
+ (dbp[2] == 'E' || dbp[2] == 'e') &&
+ (dbp[3] == 'F' || dbp[3] == 'f'))
+ {
+ while (!isspace(*dbp)) dbp++;
+ while (isspace(*dbp)) dbp++;
+ L_getit();
+ }
+ }
+}
+
+L_getit()
+{
+ register char *cp;
+ char c;
+ char nambuf[BUFSIZ];
+
+ if (*dbp == 0) return;
+ for (cp = dbp+1; *cp && *cp != '(' && *cp != ' '; cp++)
+ continue;
+ c = cp[0];
+ cp[0] = 0;
+ strcpy(nambuf, dbp);
+ cp[0] = c;
+ pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
+ pfcnt++;
+}
+
+/*
+ * Scheme tag functions
+ * look for (def... xyzzy
+ * look for (def... (xyzzy
+ * look for (def ... ((...(xyzzy ....
+ * look for (set! xyzzy
+ */
+
+static get_scheme ();
+Scheme_funcs (fi)
+ FILE *fi;
+{
+ lineno = 0;
+ charno = 0;
+ pfcnt = 0;
+
+ while (!feof (fi))
+ {
+ lineno++;
+ linecharno = charno;
+ charno += readline (&lb, fi) + 1;
+ dbp = lb.buffer;
+ if (dbp[0] == '(' &&
+ (dbp[1] == 'D' || dbp[1] == 'd') &&
+ (dbp[2] == 'E' || dbp[2] == 'e') &&
+ (dbp[3] == 'F' || dbp[3] == 'f'))
+ {
+ while (!isspace(*dbp)) dbp++;
+ /* Skip over open parens and white space */
+ while (*dbp && (isspace(*dbp) || *dbp == '(')) dbp++;
+ get_scheme ();
+ }
+ if (dbp[0] == '(' &&
+ (dbp[1] == 'S' || dbp[1] == 's') &&
+ (dbp[2] == 'E' || dbp[2] == 'e') &&
+ (dbp[3] == 'T' || dbp[3] == 't') &&
+ (dbp[4] == '!' || dbp[4] == '!') &&
+ (isspace(dbp[5])))
+ {
+ while (!isspace(*dbp)) dbp++;
+ /* Skip over white space */
+ while (isspace(*dbp)) dbp++;
+ get_scheme ();
+ }
+ }
+}
+
+static
+get_scheme()
+{
+ register char *cp;
+ char c;
+ char nambuf[BUFSIZ];
+
+ if (*dbp == 0) return;
+ /* Go till you get to white space or a syntactic break */
+ for (cp = dbp+1; *cp && *cp != '(' && *cp != ')' && !isspace(*cp); cp++)
+ continue;
+ /* Null terminate the string there. */
+ c = cp[0];
+ cp[0] = 0;
+ /* Copy the string */
+ strcpy(nambuf, dbp);
+ /* Unterminate the string */
+ cp[0] = c;
+ /* Announce the change */
+ pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
+ pfcnt++;
+}
+static get_mcode ();
+Mcode_funcs (fi)
+ FILE *fi;
+{
+ lineno = 0;
+ charno = 0;
+ pfcnt = 0;
+
+ while (!feof (fi))
+ {
+ lineno++;
+ linecharno = charno;
+ charno += readline (&lb, fi) + 1;
+ dbp = lb.buffer;
+
+ while (*dbp != 0)
+ {
+ /* Skip over white space */
+ while (isspace(*dbp)) dbp++;
+ get_mcode();
+ }
+ }
+}
+
+static
+get_mcode()
+{
+ register char *cp;
+ char c;
+ char nambuf[BUFSIZ];
+
+ if (*dbp == 0) return;
+ /* Go till you get to white space or a syntactic break */
+ for (cp = dbp; *cp && *cp != ':' && *cp != ';' && !isspace(*cp); cp++)
+ continue;
+
+ if(*cp == ':')
+ {
+ /* Null terminate the string there. */
+ c = cp[0];
+ cp[0] = 0;
+ /* Copy the string */
+ strcpy(nambuf, dbp);
+ /* Unterminate the string */
+ cp[0] = c;
+ /* Announce the change */
+ pfnote(nambuf, TRUE, lb.buffer, strlen(lb.buffer), lineno, linecharno);
+ pfcnt++;
+ *dbp = 0;
+ }
+ if (*cp == ';')
+ *dbp = 0;
+ else
+ dbp = cp;
+}
+
+/* Find tags in TeX and LaTeX input files. */
+
+/* TEX_toktab is a table of TeX control sequences that define tags.
+ Each TEX_tabent records one such control sequence. */
+
+struct TEX_tabent
+{
+ char *name;
+ int len;
+};
+
+struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
+
+/* Default set of control sequences to put into TEX_toktab.
+ The value of environment var TEXTAGS is prepended to this. */
+
+static char *TEX_defenv =
+ ":chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
+
+struct TEX_tabent *TEX_decode_env ();
+
+static char TEX_esc = '\\';
+static char TEX_opgrp = '{';
+static char TEX_clgrp = '}';
+
+/*
+ * TeX/LaTeX scanning loop.
+ */
+
+TEX_funcs (fi)
+ FILE *fi;
+{
+ char *lasthit;
+
+ lineno = 0;
+ charno = 0;
+ pfcnt = 0;
+
+ /* Select either \ or ! as escape character. */
+ TEX_mode (fi);
+
+ /* Initialize token table once from environment. */
+ if (!TEX_toktab)
+ TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
+
+ while (!feof (fi))
+ {
+ lineno++;
+ linecharno = charno;
+ charno += readline (&lb, fi) + 1;
+ dbp = lb.buffer;
+ lasthit = dbp;
+
+ while (!feof (fi))
+ { /* Scan each line in file */
+ lineno++;
+ linecharno = charno;
+ charno += readline (&lb, fi) + 1;
+ dbp = lb.buffer;
+ lasthit = dbp;
+ while (dbp = index (dbp, TEX_esc)) /* Look at each escape in line */
+ {
+ register int i;
+
+ if (! *(++dbp))
+ break;
+ linecharno += dbp - lasthit;
+ lasthit = dbp;
+ i = TEX_Token (lasthit);
+ if (0 <= i)
+ {
+ TEX_getit (lasthit, TEX_toktab[i].len);
+ break; /* We only save a line once */
+ }
+ }
+ }
+ }
+}
+
+#define TEX_LESC '\\'
+#define TEX_SESC '!'
+
+/* Figure out whether TeX's escapechar is '\\' or '!' and set grouping */
+/* chars accordingly. */
+
+TEX_mode (f)
+ FILE *f;
+{
+ int c;
+
+ while ((c = getc (f)) != EOF)
+ if (c == TEX_LESC || c == TEX_SESC)
+ break;
+
+ if (c == TEX_LESC)
+ {
+ TEX_esc = TEX_LESC;
+ TEX_opgrp = '{';
+ TEX_clgrp = '}';
+ }
+ else
+ {
+ TEX_esc = TEX_SESC;
+ TEX_opgrp = '<';
+ TEX_clgrp = '>';
+ }
+ rewind (f);
+}
+
+/* Read environment and prepend it to the default string. */
+/* Build token table. */
+
+struct TEX_tabent *
+TEX_decode_env (evarname, defenv)
+ char *evarname;
+ char *defenv;
+{
+ register char *env, *p;
+ extern char *savenstr (), *index ();
+
+ struct TEX_tabent *tab;
+ int size, i;
+
+ /* Append deafult string to environment. */
+ env = (char *) getenv (evarname);
+ if (!env)
+ env = defenv;
+ else
+ env = concat (env, defenv, "");
+
+ /* Allocate a token table */
+ for (size = 1, p=env; p;)
+ if ((p = index (p, ':')) && *(++p))
+ size++;
+ tab = (struct TEX_tabent *) xmalloc (size * sizeof (struct TEX_tabent));
+
+ /* Unpack environment string into token table. Be careful about */
+ /* zero-length strings (leading ':', "::" and trailing ':') */
+ for (i = 0; *env;)
+ {
+ p = index (env, ':');
+ if (!p) /* End of environment string. */
+ p = env + strlen (env);
+ if (p - env > 0)
+ { /* Only non-zero strings. */
+ tab[i].name = savenstr (env, p - env);
+ tab[i].len = strlen (tab[i].name);
+ i++;
+ }
+ if (*p)
+ env = p + 1;
+ else
+ {
+ tab[i].name = NULL; /* Mark end of table. */
+ tab[i].len = 0;
+ break;
+ }
+ }
+ return tab;
+}
+
+/* Record a tag defined by a TeX command of length LEN and starting at NAME.
+ The name being defined actually starts at (NAME + LEN + 1).
+ But we seem to include the TeX command in the tag name. */
+
+TEX_getit (name, len)
+ char *name;
+ int len;
+{
+ char *p = name + len;
+ char nambuf[BUFSIZ];
+
+ if (*name == 0) return;
+
+ /* Let tag name extend to next group close (or end of line) */
+ while (*p && *p != TEX_clgrp)
+ p++;
+ strncpy (nambuf, name, p - name);
+ nambuf[p - name] = 0;
+
+ pfnote (nambuf, TRUE, lb.buffer, strlen (lb.buffer), lineno, linecharno);
+ pfcnt++;
+}
+
+/* If the text at CP matches one of the tag-defining TeX command names,
+ return the index of that command in TEX_toktab.
+ Otherwise return -1. */
+
+/* Keep the capital `T' in `Token' for dumb truncating compilers
+ (this distinguishes it from `TEX_toktab' */
+TEX_Token (cp)
+ char *cp;
+{
+ int i;
+
+ for (i = 0; TEX_toktab[i].len > 0; i++)
+ if (strncmp (TEX_toktab[i].name, cp, TEX_toktab[i].len) == 0)
+ return i;
+ return -1;
+}
+
+/* Initialize a linebuffer for use */
+
+void
+initbuffer (linebuffer)
+ struct linebuffer *linebuffer;
+{
+ linebuffer->size = 200;
+ linebuffer->buffer = (char *) xmalloc (200);
+}
+
+/* Read a line of text from `stream' into `linebuffer'.
+ Return the length of the line. */
+
+long
+readline (linebuffer, stream)
+ struct linebuffer *linebuffer;
+ register FILE *stream;
+{
+ char *buffer = linebuffer->buffer;
+ register char *p = linebuffer->buffer;
+ register char *pend = p + linebuffer->size;
+
+ while (1)
+ {
+ int c = getc (stream);
+ if (p == pend)
+ {
+ linebuffer->size *= 2;
+ buffer = (char *) xrealloc (buffer, linebuffer->size);
+ p += buffer - linebuffer->buffer;
+ pend = buffer + linebuffer->size;
+ linebuffer->buffer = buffer;
+ }
+ if (c < 0 || c == '\n')
+ {
+ *p = 0;
+ break;
+ }
+ *p++ = c;
+ }
+
+ return p - buffer;
+}
+
+char *
+savestr(cp)
+ char *cp;
+{
+ return savenstr (cp, strlen (cp));
+}
+
+char *
+savenstr(cp, len)
+ char *cp;
+ int len;
+{
+ register char *dp;
+
+ dp = (char *) xmalloc (len + 1);
+ strncpy (dp, cp, len);
+ dp[len] = '\0';
+ return dp;
+}
+
+/*
+ * Return the ptr in sp at which the character c last
+ * appears; NULL if not found
+ *
+ * Identical to v7 rindex, included for portability.
+ */
+
+char *
+rindex(sp, c)
+ register char *sp, c;
+{
+ register char *r;
+
+ r = NULL;
+ do
+ {
+ if (*sp == c)
+ r = sp;
+ } while (*sp++);
+ return(r);
+}
+
+/*
+ * Return the ptr in sp at which the character c first
+ * appears; NULL if not found
+ *
+ * Identical to v7 index, included for portability.
+ */
+
+char *
+index(sp, c)
+ register char *sp, c;
+{
+ do
+ {
+ if (*sp == c)
+ return (sp);
+ } while (*sp++);
+ return (NULL);
+}
+
+/* Print error message and exit. */
+
+fatal (s1, s2)
+ char *s1, *s2;
+{
+ error (s1, s2);
+ exit (BAD);
+}
+
+/* Print error message. `s1' is printf control string, `s2' is arg for it. */
+
+error (s1, s2)
+ char *s1, *s2;
+{
+ fprintf (stderr, "%s: ", progname);
+ fprintf (stderr, s1, s2);
+ fprintf (stderr, "\n");
+}
+
+/* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
+
+char *
+concat (s1, s2, s3)
+ char *s1, *s2, *s3;
+{
+ int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
+ char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
+
+ strcpy (result, s1);
+ strcpy (result + len1, s2);
+ strcpy (result + len1 + len2, s3);
+ *(result + len1 + len2 + len3) = 0;
+
+ return result;
+}
+
+/* Like malloc but get fatal error if memory is exhausted. */
+
+int
+xmalloc (size)
+ int size;
+{
+ int result = malloc (size);
+ if (!result)
+ fatal ("virtual memory exhausted", 0);
+ return result;
+}
+
+int
+xrealloc (ptr, size)
+ char *ptr;
+ int size;
+{
+ int result = realloc (ptr, size);
+ if (!result)
+ fatal ("virtual memory exhausted");
+ return result;
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/etags/jbw-fixes b/web/glasgow/lit2x-0.16/grasp-utils/etags/jbw-fixes
new file mode 100644
index 0000000000..324c0d447e
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/etags/jbw-fixes
@@ -0,0 +1,568 @@
+From jbw@bigbird.bu.edu Tue Aug 18 08:07:53 1992
+From: jbw@bigbird.bu.edu (Joe Wells)
+Newsgroups: comp.emacs
+Subject: Re: How do I include symbols defined with #define in TAGS ?
+Date: 16 Aug 92 23:27:25 GMT
+Distribution: comp.emacs
+Organization: Boston University Computer Science Department
+In-reply-to: podi@ESD.3Com.COM's message of 14 Aug 92 17:53:29 GMT
+
+In article <podi.713814809@chamundi.NSD.3Com.COM> podi@ESD.3Com.COM (Podibanda Kuruppu) writes:
+
+ Keywords: Symbols defined by #defines in TAGS
+
+ I would greatly appreciate it if someone could tell me if I could
+ include symbols ( defined in .h files with #defines ) in a TAG file.
+
+Enclosed below is an earlier article with my solution to this.
+
+--
+Enjoy,
+
+Joe Wells <jbw@cs.bu.edu>
+Member of the League for Programming Freedom --- send e-mail for details
+
+----------------------------------------------------------------------
+Date: Sat, 4 Apr 92 00:46:52 -0500
+From: jbw@bigbird.bu.edu (Joe Wells)
+Message-Id: <9204040546.AA15208@bigbird.bu.edu>
+To: bug-gnu-emacs@prep.ai.mit.edu
+Subject: numerous bug fixes for etags
+
+Enclosed is a patch with numerous changes for etags. The following are
+the changes and bugs fixed:
+
+1. Improvement: don't waste time calling strncmp (with "struct", "union",
+ "enum", "typedef") if the lengths are different.
+
+2. Bug: pfnote placed a NUL in the line buffer after the tag token which caused
+ things like `{' or `/*' to be ignored, thus severely screwing up the
+ parser. Or it did something horrible, I don't remember for sure.
+
+3. Improvement: record defining occurrences of struct/union/enum tags.
+ This works even if combined with a typedef definition, for example:
+
+ typedef struct XXX {
+ .....
+ } YYY;
+
+4. Bug: when a tag token was the last item on the line before the newline
+ character, garbage would be seen as the token. This is because when a
+ NUL was seen in the buffer the buffer was replaced with the next line.
+
+5. Bug: tag tokens immediately followed by a `{' with no intervening space
+ were not recorded. This was only a problem because of improvement 3
+ above.
+
+6. Bug: a newline in the middle of a comment zeroed the `number' variable.
+ (Just for good measure I made it not zero `number' in strings even when
+ the newline is not preceded by `\', in case someone wants to run etags
+ on illegal code :-) (`number' is used only on lines that begin with
+ `#'.)
+
+7. Bug: handling of #define lines was severely broken. I don't actually
+ remember what etags did with them, but it was really bad. It now
+ records macro definitions.
+
+8. Bug: when a tag token was the last item on the line except for
+ whitespace, etags would replace the contents of the line buffer and
+ then later do various string comparisons and inspections against
+ garbage values instead of against the token. Fixing this required
+ copying the token into a buffer. (This is roughly the same as bug 4
+ above, but in a different function.)
+
+9. Bug: when a tag token was the last item on the line before the newline
+ (and under various other circumstances), etags would skip over the NUL
+ in the buffer and skip to the first non-whitespace character in the
+ buffer.
+
+10. Improvement (possibly bug fix): parse typedefs even when we aren't
+ going to print them out. I seem to remember that this fixed some bug,
+ but I don't remember the specific case that would trigger the bug.
+
+11. An unfinished attempt to detect and record global variable
+ definitions.
+
+The changes are to the 18.57 version of etags, but the only change in
+18.58 to the C code handling is to initialize some variables when starting
+on a new file, so these changes are orthogonal.
+
+--
+Enjoy,
+
+Joe Wells <jbw@cs.bu.edu>
+
+Member of the League for Programming Freedom --- send e-mail for details
+
+----------------------------------------------------------------------
+--- etags.c-dist Tue Jan 8 14:08:38 1991
++++ etags.c Sat Apr 4 00:41:22 1992
+@@ -62,7 +62,10 @@
+
+ /* cause token checking for typedef, struct, union, enum to distinguish
+ keywords from identifier-prefixes (e.g. struct vs struct_tag). */
+-#define istoken(s, tok, len) (!strncmp(s,tok,len) && endtoken(*((s)+(len))))
++#define istoken(s, t, len) \
++ (((len) == (sizeof (t) -1)) && \
++ ((strncmp(s, t, len)) == 0) && \
++ (endtoken(*((s)+(len)))))
+
+ struct nd_st { /* sorting structure */
+ char *name; /* function or type name */
+@@ -505,6 +508,7 @@
+ {
+ register char *fp;
+ register NODE *np;
++ char save;
+ char *altname;
+ char tem[51];
+
+@@ -538,6 +542,7 @@
+ np->left = np->right = 0;
+ if (eflag)
+ {
++ save = linestart[linelen];
+ linestart[linelen] = 0;
+ }
+ else if (xflag == 0)
+@@ -546,6 +551,7 @@
+ linestart = tem;
+ }
+ np->pat = savestr (linestart);
++ linestart[linelen] = save;
+ if (head == NULL)
+ head = np;
+ else
+@@ -725,6 +731,17 @@
+ number = 0; \
+ }
+
++/* These two are part of a never-finished attempt to record global */
++/* variable definitions. This is nearly impossible in C without the full */
++/* power of a C compiler due to C's stupid grammar. */
++logical infunc;
++int idents_in_decl;
++
++/* indicates whether the next token (if any) is the tag corresponding to */
++/* `struct', `union', or `enum' */
++logical next_token_is_tag;
++
++
+ C_entries ()
+ {
+ register int c;
+@@ -731,6 +748,15 @@
+ register char *token, *tp, *lp;
+ logical incomm, inquote, inchar, midtoken;
+ int level;
++
++ /* there are certain things that must be done when the end of line is */
++ /* encountered, but they must be delayed until after other things are */
++ /* done. */
++ logical new_line_flag;
++
++ /* same as new_line_flag for left braces. */
++ logical left_brace_flag;
++
+ char tok[BUFSIZ];
+
+ lineno = 0;
+@@ -739,17 +765,22 @@
+ *lp = 0;
+
+ number = 0;
+- gotone = midtoken = inquote = inchar = incomm = FALSE;
++ gotone = midtoken = inquote = inchar = incomm = infunc = FALSE;
++ new_line_flag = FALSE;
++ left_brace_flag = FALSE;
+ level = 0;
++ idents_in_decl = 0;
++ next_token_is_tag = FALSE;
+
+ while (!feof (inf))
+ {
+ c = *lp++;
+ if (c == 0)
+- {
+- CNL;
+- gotone = FALSE;
+- }
++ new_line_flag = TRUE;
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "E: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
+ if (c == '\\')
+ {
+ c = *lp++;
+@@ -756,15 +787,18 @@
+ if (c == 0)
+ CNL_SAVE_NUMBER;
+ c = ' ';
++ /* is this correct? I thought escaped newlines disappeared even */
++ /* before the token breaker got to see things. */
+ }
+ else if (incomm)
+ {
++ new_line_flag = FALSE;
+ if (c == '*')
+ {
+ while ((c = *lp++) == '*')
+ continue;
+ if (c == 0)
+- CNL;
++ CNL_SAVE_NUMBER;
+ if (c == '/')
+ incomm = FALSE;
+ }
+@@ -771,6 +805,7 @@
+ }
+ else if (inquote)
+ {
++ new_line_flag = FALSE;
+ /*
+ * Too dumb to know about \" not being magic, but
+ * they usually occur in pairs anyway.
+@@ -781,6 +816,7 @@
+ }
+ else if (inchar)
+ {
++ new_line_flag = FALSE;
+ if (c == '\'')
+ inchar = FALSE;
+ continue;
+@@ -809,8 +845,8 @@
+ {
+ tydef=middle;
+ }
+- level++;
+- continue;
++ left_brace_flag = TRUE;
++ break;
+ case '}':
+ if (lp == lb.buffer + 1)
+ level = 0; /* reset */
+@@ -820,8 +856,17 @@
+ {
+ tydef=end;
+ }
++ if (level == 0 && infunc)
++ {
++ idents_in_decl = 0;
++ infunc = FALSE;
++ }
+ continue;
+ }
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "D: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
+ if (!level && !inquote && !incomm && gotone == FALSE)
+ {
+ if (midtoken)
+@@ -852,6 +897,11 @@
+ tp-token+1);
+ tok[tp-token+1] = 0;
+ pfnote(tok, f, lb1.buffer, endpos, line, linestart);
++#ifdef DEBUG
++ fprintf (stderr,
++ "f: %d, infunc %d, tok: %s\nlb1.buffer: %s\n",
++ f, infunc, tok, lb1.buffer);
++#endif /* DEBUG */
+ }
+ else
+ {
+@@ -858,8 +908,15 @@
+ strncpy (tok, token, tp-token+1);
+ tok[tp-token+1] = 0;
+ pfnote(tok, f, lb.buffer, endpos, line, linestart);
++#ifdef DEBUG
++ fprintf (stderr,
++ "f: %d, infunc %d, tok: %s\nlb.buffer: %s\n",
++ f, infunc, tok, lb.buffer);
++#endif /* DEBUG */
+ }
+ gotone = f; /* function */
++ if (f)
++ infunc = TRUE;
+ }
+ midtoken = FALSE;
+ token = lp - 1;
+@@ -873,8 +930,32 @@
+ midtoken = TRUE;
+ }
+ }
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "F: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
++ if (left_brace_flag)
++ {
++ left_brace_flag = FALSE;
++ next_token_is_tag = FALSE;
++ level++;
++ }
++ if (new_line_flag)
++ {
++ new_line_flag = FALSE;
++ number = 0;
++ gotone = FALSE;
++ }
++ if (lp > lb.buffer && lp[-1] == 0)
++ CNL_SAVE_NUMBER;
+ if (c == ';' && tydef==end) /* clean with typedefs */
+ tydef=none;
++ if (c == ';' && level == 0 && !infunc)
++ idents_in_decl = 0;
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "G: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
+ }
+ }
+
+@@ -891,70 +972,176 @@
+ reg char *lp = *lpp;
+ reg char c;
+ static logical next_token_is_func;
++
++ /* indicates that the next token will be a macro defined with #define */
++ static logical next_token_is_macro;
++
+ logical firsttok; /* T if have seen first token in ()'s */
+- int bad, win;
++ int bad = FALSE, win = FALSE;
++ int length = (lp - 1) - token;
++
++ /* used to keep a copy of the token when we have to fill the line buffer */
++ /* with the contents of the next line */
++ static char *tok_buffer = NULL;
++ static long tok_buffer_size = 0;
+
+ *f = 1; /* a function */
+ c = lp[-1];
+- bad = FALSE;
+ if (!number)
+ { /* space is not allowed in macro defs */
+- while (iswhite(c))
++ while ((c == 0) || iswhite(c))
+ {
+- c = *lp++;
+- if (c == 0)
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "C: token: %s, c: [%c], lp - token: %d\n",
++ token, c, lp - token);
++#endif /* DEBUG */
++ while (c == 0)
+ {
+ if (feof (inf))
+- break;
++ goto break_while_1;
++ if (token != tok_buffer)
++ {
++ if (length + 1 > tok_buffer_size)
++ if (tok_buffer_size == 0)
++ {
++ tok_buffer_size = length + 1;
++ tok_buffer = (char *) xmalloc (tok_buffer_size);
++ }
++ else
++ {
++ tok_buffer_size = length + 1;
++ tok_buffer =
++ (char *) xrealloc (tok_buffer, tok_buffer_size);
++ }
++ strncpy (tok_buffer, token, length);
++ tok_buffer[length] = '\0';
++ token = tok_buffer;
++ }
+ CNL;
++ c = *lp++;
+ }
++ while ((c != 0) && iswhite(c))
++ c = *lp++;
+ }
+- /* the following tries to make it so that a #define a b(c) */
+- /* doesn't count as a define of b. */
++ break_while_1:
++ ;
+ }
+ else
+ {
++ /* the following tries to make it so that a #define a b(c) */
++ /* doesn't count as a define of b. */
+ number++;
+- if (number >= 4 || (number==2 && strncmp (token, "define", 6)))
+- {
+- gotone = TRUE;
+- badone:
++#ifdef DEBUG
++ fprintf (stderr, "number: %d, n_t_i_m: %d, token: %s\n",
++ number, next_token_is_macro, token);
++#endif /* DEBUG */
++ if (number == 2 && strncmp (token, "define", 6) == 0)
++ next_token_is_macro = TRUE;
++ else if (number == 3 && next_token_is_macro)
++ {
++ next_token_is_macro = FALSE;
++ while ((c != 0) && iswhite(c))
++ {
++#ifdef DEBUG
++ fprintf (stderr, "c: %c, %d\n", c, c);
++#endif /* DEBUG */
++ c = *lp++;
++ }
++#ifdef DEBUG
++ fprintf (stderr, "c: %c, %d\n", c, c);
++#endif /* DEBUG */
++ if (c == 0) /* ignore plain "#define FLAG" */
+ bad = TRUE;
++ else
++ win = TRUE;
++ /* speed up skipping the rest of this line */
++ gotone = TRUE;
++ /* never treat a macro as a function, because it doesn't have a */
++ /* function body, which is what "f" really stands for (now). */
++ *f = FALSE;
+ goto ret;
+ }
++ else
++ /* speed up skipping the rest of this line */
++ gotone = TRUE;
++ goto badone;
+ }
++ idents_in_decl ++;
++#ifdef DEBUG
++ fprintf (stderr,
++ "A: iid: %d, tydef: %d, ntit: %d, ntif: %d, c: %c, token: %.*s\n",
++ idents_in_decl, tydef, next_token_is_tag, next_token_is_func, c,
++ length + 5, token);
++#endif /* DEBUG */
+ /* check for the typedef cases */
+- if (tflag && istoken(token, "typedef", 7))
++ if (istoken (token, "typedef", length))
+ {
+ tydef=begin;
+ goto badone;
+ }
+- if (tydef==begin && (istoken(token, "struct", 6) ||
+- istoken(token, "union", 5) || istoken(token, "enum", 4)))
+- {
++#ifdef DEBUG
++ fprintf (stderr, "D\n");
++#endif /* DEBUG */
++ if (istoken (token, "struct", length) ||
++ istoken (token, "union", length) ||
++ istoken (token, "enum", length))
++ {
++ next_token_is_tag = 1;
++#ifdef DEBUG
++ fprintf (stderr, "A: token: %s\n", token);
++#endif /* DEBUG */
++ if (tydef == begin)
+ tydef=tag_ok;
+ goto badone;
+ }
+- if (tydef==tag_ok)
++ else if (next_token_is_tag)
+ {
++#ifdef DEBUG
++ fprintf (stderr, "B: token: %s, c: [%c]\n", token, c);
++#endif /* DEBUG */
++ if (tydef==tag_ok)
+ tydef=middle;
+- goto badone;
++ next_token_is_tag = 0;
++ *f = 0;
++ /* only notice when a tag is being defined, not when it is merely */
++ /* being used. */
++ if (c == '{')
++ win = TRUE;
++ else
++ bad = TRUE;
++ goto ret;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "E\n");
++#endif /* DEBUG */
+ if (tydef==begin) /* e.g. typedef ->int<- */
+ {
+ tydef=end;
+ goto badone;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "F\n");
++#endif /* DEBUG */
+ if (tydef==middle && level == 0) /* e.g. typedef struct tag ->struct_t<- */
+ {
+ tydef=end;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "G\n");
++#endif /* DEBUG */
+ if (tydef==end)
+ {
+ *f = 0;
+- win = 1;
++#ifdef DEBUG
++ fprintf (stderr, "C token: %s\n", token);
++#endif /* DEBUG */
++ win = tflag;
+ goto ret;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "H\n");
++#endif /* DEBUG */
+ /* Detect GNUmacs's function-defining macros. */
+ if (!number && !strncmp (token, "DEF", 3))
+
+@@ -962,6 +1149,9 @@
+ next_token_is_func = 1;
+ goto badone;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "I\n");
++#endif /* DEBUG */
+ if (next_token_is_func)
+ {
+ next_token_is_func = 0;
+@@ -968,9 +1158,15 @@
+ win = 1;
+ goto ret;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "J\n");
++#endif /* DEBUG */
+ if (c != '(')
+ goto badone;
+ firsttok = FALSE;
++#ifdef DEBUG
++ fprintf (stderr, "K\n");
++#endif /* DEBUG */
+ while ((c = *lp++) != ')')
+ {
+ if (c == 0)
+@@ -999,9 +1195,20 @@
+ }
+ }
+ win = isgood (c);
++
+ ret:
++#ifdef DEBUG
++ fprintf (stderr,
++ "B: iid: %d, tydef: %d, ntit: %d, ntif: %d, c: %c, token: %.*s\n",
++ idents_in_decl, tydef, next_token_is_tag, next_token_is_func, c,
++ length + 5, token);
++#endif /* DEBUG */
+ *lpp = lp - 1;
+ return !bad && win;
++
++ badone:
++ bad = TRUE;
++ goto ret;
+ }
+
+ getline (atchar)
+----------------------------------------------------------------------
+
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/etags/wells-fixes b/web/glasgow/lit2x-0.16/grasp-utils/etags/wells-fixes
new file mode 100644
index 0000000000..242e4e1002
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/etags/wells-fixes
@@ -0,0 +1,545 @@
+From jbw@bigbird.bu.edu Sun Apr 5 14:58:19 1992
+From: jbw@bigbird.bu.edu (Joe Wells)
+Newsgroups: gnu.emacs.bug
+Subject: numerous bug fixes for etags
+Date: 3 Apr 92 19:46:52 GMT
+Distribution: gnu
+Organization: GNUs Not Usenet
+
+Enclosed is a patch with numerous changes for etags. The following are
+the changes and bugs fixed:
+
+1. Improvement: don't waste time calling strncmp (with "struct", "union",
+ "enum", "typedef") if the lengths are different.
+
+2. Bug: pfnote placed a NUL in the line buffer after the tag token which caused
+ things like `{' or `/*' to be ignored, thus severely screwing up the
+ parser. Or it did something horrible, I don't remember for sure.
+
+3. Improvement: record defining occurrences of struct/union/enum tags.
+ This works even if combined with a typedef definition, for example:
+
+ typedef struct XXX {
+ .....
+ } YYY;
+
+4. Bug: when a tag token was the last item on the line before the newline
+ character, garbage would be seen as the token. This is because when a
+ NUL was seen in the buffer the buffer was replaced with the next line.
+
+5. Bug: tag tokens immediately followed by a `{' with no intervening space
+ were not recorded. This was only a problem because of improvement 3
+ above.
+
+6. Bug: a newline in the middle of a comment zeroed the `number' variable.
+ (Just for good measure I made it not zero `number' in strings even when
+ the newline is not preceded by `\', in case someone wants to run etags
+ on illegal code :-) (`number' is used only on lines that begin with
+ `#'.)
+
+7. Bug: handling of #define lines was severely broken. I don't actually
+ remember what etags did with them, but it was really bad. It now
+ records macro definitions.
+
+8. Bug: when a tag token was the last item on the line except for
+ whitespace, etags would replace the contents of the line buffer and
+ then later do various string comparisons and inspections against
+ garbage values instead of against the token. Fixing this required
+ copying the token into a buffer. (This is roughly the same as bug 4
+ above, but in a different function.)
+
+9. Bug: when a tag token was the last item on the line before the newline
+ (and under various other circumstances), etags would skip over the NUL
+ in the buffer and skip to the first non-whitespace character in the
+ buffer.
+
+10. Improvement (possibly bug fix): parse typedefs even when we aren't
+ going to print them out. I seem to remember that this fixed some bug,
+ but I don't remember the specific case that would trigger the bug.
+
+11. An unfinished attempt to detect and record global variable
+ definitions.
+
+The changes are to the 18.57 version of etags, but the only change in
+18.58 to the C code handling is to initialize some variables when starting
+on a new file, so these changes are orthogonal.
+
+--
+Enjoy,
+
+Joe Wells <jbw@cs.bu.edu>
+
+Member of the League for Programming Freedom --- send e-mail for details
+
+----------------------------------------------------------------------
+--- etags.c-dist Tue Jan 8 14:08:38 1991
++++ etags.c Sat Apr 4 00:41:22 1992
+@@ -62,7 +62,10 @@
+
+ /* cause token checking for typedef, struct, union, enum to distinguish
+ keywords from identifier-prefixes (e.g. struct vs struct_tag). */
+-#define istoken(s, tok, len) (!strncmp(s,tok,len) && endtoken(*((s)+(len))))
++#define istoken(s, t, len) \
++ (((len) == (sizeof (t) -1)) && \
++ ((strncmp(s, t, len)) == 0) && \
++ (endtoken(*((s)+(len)))))
+
+ struct nd_st { /* sorting structure */
+ char *name; /* function or type name */
+@@ -505,6 +508,7 @@
+ {
+ register char *fp;
+ register NODE *np;
++ char save;
+ char *altname;
+ char tem[51];
+
+@@ -538,6 +542,7 @@
+ np->left = np->right = 0;
+ if (eflag)
+ {
++ save = linestart[linelen];
+ linestart[linelen] = 0;
+ }
+ else if (xflag == 0)
+@@ -546,6 +551,7 @@
+ linestart = tem;
+ }
+ np->pat = savestr (linestart);
++ linestart[linelen] = save;
+ if (head == NULL)
+ head = np;
+ else
+@@ -725,6 +731,17 @@
+ number = 0; \
+ }
+
++/* These two are part of a never-finished attempt to record global */
++/* variable definitions. This is nearly impossible in C without the full */
++/* power of a C compiler due to C's stupid grammar. */
++logical infunc;
++int idents_in_decl;
++
++/* indicates whether the next token (if any) is the tag corresponding to */
++/* `struct', `union', or `enum' */
++logical next_token_is_tag;
++
++
+ C_entries ()
+ {
+ register int c;
+@@ -731,6 +748,15 @@
+ register char *token, *tp, *lp;
+ logical incomm, inquote, inchar, midtoken;
+ int level;
++
++ /* there are certain things that must be done when the end of line is */
++ /* encountered, but they must be delayed until after other things are */
++ /* done. */
++ logical new_line_flag;
++
++ /* same as new_line_flag for left braces. */
++ logical left_brace_flag;
++
+ char tok[BUFSIZ];
+
+ lineno = 0;
+@@ -739,17 +765,22 @@
+ *lp = 0;
+
+ number = 0;
+- gotone = midtoken = inquote = inchar = incomm = FALSE;
++ gotone = midtoken = inquote = inchar = incomm = infunc = FALSE;
++ new_line_flag = FALSE;
++ left_brace_flag = FALSE;
+ level = 0;
++ idents_in_decl = 0;
++ next_token_is_tag = FALSE;
+
+ while (!feof (inf))
+ {
+ c = *lp++;
+ if (c == 0)
+- {
+- CNL;
+- gotone = FALSE;
+- }
++ new_line_flag = TRUE;
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "E: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
+ if (c == '\\')
+ {
+ c = *lp++;
+@@ -756,15 +787,18 @@
+ if (c == 0)
+ CNL_SAVE_NUMBER;
+ c = ' ';
++ /* is this correct? I thought escaped newlines disappeared even */
++ /* before the token breaker got to see things. */
+ }
+ else if (incomm)
+ {
++ new_line_flag = FALSE;
+ if (c == '*')
+ {
+ while ((c = *lp++) == '*')
+ continue;
+ if (c == 0)
+- CNL;
++ CNL_SAVE_NUMBER;
+ if (c == '/')
+ incomm = FALSE;
+ }
+@@ -771,6 +805,7 @@
+ }
+ else if (inquote)
+ {
++ new_line_flag = FALSE;
+ /*
+ * Too dumb to know about \" not being magic, but
+ * they usually occur in pairs anyway.
+@@ -781,6 +816,7 @@
+ }
+ else if (inchar)
+ {
++ new_line_flag = FALSE;
+ if (c == '\'')
+ inchar = FALSE;
+ continue;
+@@ -809,8 +845,8 @@
+ {
+ tydef=middle;
+ }
+- level++;
+- continue;
++ left_brace_flag = TRUE;
++ break;
+ case '}':
+ if (lp == lb.buffer + 1)
+ level = 0; /* reset */
+@@ -820,8 +856,17 @@
+ {
+ tydef=end;
+ }
++ if (level == 0 && infunc)
++ {
++ idents_in_decl = 0;
++ infunc = FALSE;
++ }
+ continue;
+ }
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "D: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
+ if (!level && !inquote && !incomm && gotone == FALSE)
+ {
+ if (midtoken)
+@@ -852,6 +897,11 @@
+ tp-token+1);
+ tok[tp-token+1] = 0;
+ pfnote(tok, f, lb1.buffer, endpos, line, linestart);
++#ifdef DEBUG
++ fprintf (stderr,
++ "f: %d, infunc %d, tok: %s\nlb1.buffer: %s\n",
++ f, infunc, tok, lb1.buffer);
++#endif /* DEBUG */
+ }
+ else
+ {
+@@ -858,8 +908,15 @@
+ strncpy (tok, token, tp-token+1);
+ tok[tp-token+1] = 0;
+ pfnote(tok, f, lb.buffer, endpos, line, linestart);
++#ifdef DEBUG
++ fprintf (stderr,
++ "f: %d, infunc %d, tok: %s\nlb.buffer: %s\n",
++ f, infunc, tok, lb.buffer);
++#endif /* DEBUG */
+ }
+ gotone = f; /* function */
++ if (f)
++ infunc = TRUE;
+ }
+ midtoken = FALSE;
+ token = lp - 1;
+@@ -873,8 +930,32 @@
+ midtoken = TRUE;
+ }
+ }
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "F: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
++ if (left_brace_flag)
++ {
++ left_brace_flag = FALSE;
++ next_token_is_tag = FALSE;
++ level++;
++ }
++ if (new_line_flag)
++ {
++ new_line_flag = FALSE;
++ number = 0;
++ gotone = FALSE;
++ }
++ if (lp > lb.buffer && lp[-1] == 0)
++ CNL_SAVE_NUMBER;
+ if (c == ';' && tydef==end) /* clean with typedefs */
+ tydef=none;
++ if (c == ';' && level == 0 && !infunc)
++ idents_in_decl = 0;
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "G: c: [%c], lp[-2]: [%c]\n", c, lp[-2]);
++#endif /* DEBUG */
+ }
+ }
+
+@@ -891,70 +972,176 @@
+ reg char *lp = *lpp;
+ reg char c;
+ static logical next_token_is_func;
++
++ /* indicates that the next token will be a macro defined with #define */
++ static logical next_token_is_macro;
++
+ logical firsttok; /* T if have seen first token in ()'s */
+- int bad, win;
++ int bad = FALSE, win = FALSE;
++ int length = (lp - 1) - token;
++
++ /* used to keep a copy of the token when we have to fill the line buffer */
++ /* with the contents of the next line */
++ static char *tok_buffer = NULL;
++ static long tok_buffer_size = 0;
+
+ *f = 1; /* a function */
+ c = lp[-1];
+- bad = FALSE;
+ if (!number)
+ { /* space is not allowed in macro defs */
+- while (iswhite(c))
++ while ((c == 0) || iswhite(c))
+ {
+- c = *lp++;
+- if (c == 0)
++#ifdef DEBUG
++ if (next_token_is_tag)
++ fprintf (stderr, "C: token: %s, c: [%c], lp - token: %d\n",
++ token, c, lp - token);
++#endif /* DEBUG */
++ while (c == 0)
+ {
+ if (feof (inf))
+- break;
++ goto break_while_1;
++ if (token != tok_buffer)
++ {
++ if (length + 1 > tok_buffer_size)
++ if (tok_buffer_size == 0)
++ {
++ tok_buffer_size = length + 1;
++ tok_buffer = (char *) xmalloc (tok_buffer_size);
++ }
++ else
++ {
++ tok_buffer_size = length + 1;
++ tok_buffer =
++ (char *) xrealloc (tok_buffer, tok_buffer_size);
++ }
++ strncpy (tok_buffer, token, length);
++ tok_buffer[length] = '\0';
++ token = tok_buffer;
++ }
+ CNL;
++ c = *lp++;
+ }
++ while ((c != 0) && iswhite(c))
++ c = *lp++;
+ }
+- /* the following tries to make it so that a #define a b(c) */
+- /* doesn't count as a define of b. */
++ break_while_1:
++ ;
+ }
+ else
+ {
++ /* the following tries to make it so that a #define a b(c) */
++ /* doesn't count as a define of b. */
+ number++;
+- if (number >= 4 || (number==2 && strncmp (token, "define", 6)))
+- {
+- gotone = TRUE;
+- badone:
++#ifdef DEBUG
++ fprintf (stderr, "number: %d, n_t_i_m: %d, token: %s\n",
++ number, next_token_is_macro, token);
++#endif /* DEBUG */
++ if (number == 2 && strncmp (token, "define", 6) == 0)
++ next_token_is_macro = TRUE;
++ else if (number == 3 && next_token_is_macro)
++ {
++ next_token_is_macro = FALSE;
++ while ((c != 0) && iswhite(c))
++ {
++#ifdef DEBUG
++ fprintf (stderr, "c: %c, %d\n", c, c);
++#endif /* DEBUG */
++ c = *lp++;
++ }
++#ifdef DEBUG
++ fprintf (stderr, "c: %c, %d\n", c, c);
++#endif /* DEBUG */
++ if (c == 0) /* ignore plain "#define FLAG" */
+ bad = TRUE;
++ else
++ win = TRUE;
++ /* speed up skipping the rest of this line */
++ gotone = TRUE;
++ /* never treat a macro as a function, because it doesn't have a */
++ /* function body, which is what "f" really stands for (now). */
++ *f = FALSE;
+ goto ret;
+ }
++ else
++ /* speed up skipping the rest of this line */
++ gotone = TRUE;
++ goto badone;
+ }
++ idents_in_decl ++;
++#ifdef DEBUG
++ fprintf (stderr,
++ "A: iid: %d, tydef: %d, ntit: %d, ntif: %d, c: %c, token: %.*s\n",
++ idents_in_decl, tydef, next_token_is_tag, next_token_is_func, c,
++ length + 5, token);
++#endif /* DEBUG */
+ /* check for the typedef cases */
+- if (tflag && istoken(token, "typedef", 7))
++ if (istoken (token, "typedef", length))
+ {
+ tydef=begin;
+ goto badone;
+ }
+- if (tydef==begin && (istoken(token, "struct", 6) ||
+- istoken(token, "union", 5) || istoken(token, "enum", 4)))
+- {
++#ifdef DEBUG
++ fprintf (stderr, "D\n");
++#endif /* DEBUG */
++ if (istoken (token, "struct", length) ||
++ istoken (token, "union", length) ||
++ istoken (token, "enum", length))
++ {
++ next_token_is_tag = 1;
++#ifdef DEBUG
++ fprintf (stderr, "A: token: %s\n", token);
++#endif /* DEBUG */
++ if (tydef == begin)
+ tydef=tag_ok;
+ goto badone;
+ }
+- if (tydef==tag_ok)
++ else if (next_token_is_tag)
+ {
++#ifdef DEBUG
++ fprintf (stderr, "B: token: %s, c: [%c]\n", token, c);
++#endif /* DEBUG */
++ if (tydef==tag_ok)
+ tydef=middle;
+- goto badone;
++ next_token_is_tag = 0;
++ *f = 0;
++ /* only notice when a tag is being defined, not when it is merely */
++ /* being used. */
++ if (c == '{')
++ win = TRUE;
++ else
++ bad = TRUE;
++ goto ret;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "E\n");
++#endif /* DEBUG */
+ if (tydef==begin) /* e.g. typedef ->int<- */
+ {
+ tydef=end;
+ goto badone;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "F\n");
++#endif /* DEBUG */
+ if (tydef==middle && level == 0) /* e.g. typedef struct tag ->struct_t<- */
+ {
+ tydef=end;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "G\n");
++#endif /* DEBUG */
+ if (tydef==end)
+ {
+ *f = 0;
+- win = 1;
++#ifdef DEBUG
++ fprintf (stderr, "C token: %s\n", token);
++#endif /* DEBUG */
++ win = tflag;
+ goto ret;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "H\n");
++#endif /* DEBUG */
+ /* Detect GNUmacs's function-defining macros. */
+ if (!number && !strncmp (token, "DEF", 3))
+
+@@ -962,6 +1149,9 @@
+ next_token_is_func = 1;
+ goto badone;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "I\n");
++#endif /* DEBUG */
+ if (next_token_is_func)
+ {
+ next_token_is_func = 0;
+@@ -968,9 +1158,15 @@
+ win = 1;
+ goto ret;
+ }
++#ifdef DEBUG
++ fprintf (stderr, "J\n");
++#endif /* DEBUG */
+ if (c != '(')
+ goto badone;
+ firsttok = FALSE;
++#ifdef DEBUG
++ fprintf (stderr, "K\n");
++#endif /* DEBUG */
+ while ((c = *lp++) != ')')
+ {
+ if (c == 0)
+@@ -999,9 +1195,20 @@
+ }
+ }
+ win = isgood (c);
++
+ ret:
++#ifdef DEBUG
++ fprintf (stderr,
++ "B: iid: %d, tydef: %d, ntit: %d, ntif: %d, c: %c, token: %.*s\n",
++ idents_in_decl, tydef, next_token_is_tag, next_token_is_func, c,
++ length + 5, token);
++#endif /* DEBUG */
+ *lpp = lp - 1;
+ return !bad && win;
++
++ badone:
++ bad = TRUE;
++ goto ret;
+ }
+
+ getline (atchar)
+----------------------------------------------------------------------
+
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/msub/Jmakefile b/web/glasgow/lit2x-0.16/grasp-utils/msub/Jmakefile
new file mode 100644
index 0000000000..cc855bd99e
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/msub/Jmakefile
@@ -0,0 +1,7 @@
+BuildPgmFromOneCFile(msub)
+
+InstallBinaryTarget(msub,$(INSTBINDIR))
+
+CDependTarget( $(SRCS_C) )
+
+RunStdTest(msub001,msub,-f test.makefile testfile -o1 test.stdout)
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/msub/msub.c b/web/glasgow/lit2x-0.16/grasp-utils/msub/msub.c
new file mode 100644
index 0000000000..dccefa990f
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/msub/msub.c
@@ -0,0 +1,520 @@
+/*
+ msub - Read file(s) and perform substitutions using values of
+ variables defined in makefile.
+
+ Syntax: msub [-f makefile] [file ...]
+
+ Multiple -f options may be given.
+
+ 27 Mar 1990 Paul DuBois dubois@primate.wisc.edu
+
+ 27 Mar 1990 V1.0. Created.
+*/
+
+# include <stdio.h>
+# include <ctype.h>
+
+
+# define true (1)
+# define false (0)
+
+
+extern char *calloc (), *strcpy ();
+
+
+char *NewString();
+
+
+typedef struct Def Def;
+
+struct Def
+{
+ char *var; /* variable name */
+ char *val; /* variable value */
+ int simple; /* whether value has been expanded */
+ Def *nextDef; /* next definition in list */
+};
+
+
+char *usage = "Usage: msub [ -f makefile ] file";
+char *makefile = NULL;
+Def *defList = NULL; /* list of definitions */
+int nDefs = 0; /* number of definitions */
+int changes;
+
+main (argc, argv)
+int argc;
+char **argv;
+{
+FILE *f;
+Def *dp;
+int i, pass;
+
+ --argc;
+ ++argv;
+
+ while (argc > 0 && argv[0][0] == '-')
+ {
+ if (strcmp (argv[0], "-f") == 0)
+ {
+ if (argc < 2)
+ panic (usage);
+ if ((f = fopen (makefile = argv[1], "r")) == NULL)
+ panic ("Can't open makefile");
+ ReadMake (f);
+ fclose (f);
+ argc -= 2;
+ argv += 2;
+ }
+ else
+ panic (usage); /* bad flag */
+ }
+
+ if (makefile == NULL) /* no -f options given */
+ {
+ if ((f = fopen ("makefile", "r")) == NULL)
+ {
+ if ((f = fopen ("Makefile", "r")) == NULL)
+ panic ("Can't open makefile");
+ }
+ ReadMake (f);
+ fclose (f);
+ }
+
+ EncodeEscapes ();
+
+ /* determine which values need expanding */
+ for (dp = defList; dp != NULL; dp = dp->nextDef)
+ dp->simple = !FindVarRef (dp->val, NULL, NULL, false);
+
+ /* expand values to eliminate embedded var references */
+ for (pass = 0; pass < nDefs; pass++)
+ {
+ changes = 0;
+ for (dp = defList; dp != NULL; dp = dp->nextDef)
+ {
+ if (!dp->simple)
+ Expand (dp);
+ }
+ if (changes == 0) /* loop while values expand */
+ break;
+ }
+
+ /* sanity check: shouldn't have to make more than nDefs passes */
+ if (pass >= nDefs)
+ panic ("Too many expansion passes. Something's wrong!");
+
+ DecodeEscapes ();
+
+ /* partain addition:
+ args of form "foo=bar" are taken to be defs to add in
+ */
+ while (argc > 0 && strchr(argv[0], '=') && isalpha(argv[0][0]))
+ {
+ char name[BUFSIZ], *np, *p;
+ int len;
+ p = argv[0];
+ /* copied from below */
+ np = name;
+ while (isalnum (*p) || *p == '_')
+ *np++ = *p++;
+ *np = '\0';
+ while (isspace (*p)) /* skip whitespace */
+ ++p;
+ if (*p++ == '=') /* it's a definition */
+ {
+ /* skip leading/trailing whitespace */
+ while (isspace (*p))
+ ++p;
+ len = strlen (p);
+ while (len > 0 && isspace (p[len-1]))
+ p[--len] = '\0';
+ AddDef (name, p, 1);
+ /* find var refs in value -- NUKED */
+ /* FindAllVarRefs (p); */
+ /* also NUKED: continue; */
+ }
+ /* end of: copied from below */
+ --argc;
+ ++argv;
+ }
+ /* end of partain addition */
+
+ /* read source file(s) and perform substitutions */
+ if (argc == 0)
+ DoSub (stdin);
+ else while (argc > 0)
+ {
+ if ((f = fopen (*argv, "r")) == NULL)
+ {
+ fprintf (stderr, "Can't open \"%s\". ", *argv);
+ panic ("Quitting.");
+ }
+ DoSub (f);
+ fclose (f);
+ --argc;
+ ++argv;
+ }
+
+ exit (0);
+}
+
+
+/*
+ Read a makefile.
+*/
+
+ReadMake (f)
+FILE *f;
+{
+char input[BUFSIZ * 4], name[BUFSIZ], *p, *np;
+int i, len;
+
+ while (GetLine (f, input)) /* get line, check whether def'n */
+ {
+ for (p = input; isspace (*p); p++) { /* nop */ }
+ if (*p == '#' || *p == '\0') /* comment or blank line */
+ continue;
+ if (isalpha (*p)) /* look for var name */
+ {
+ np = name;
+ while (isalnum (*p) || *p == '_')
+ *np++ = *p++;
+ *np = '\0';
+ while (isspace (*p)) /* skip whitespace */
+ ++p;
+ if (*p++ == '=') /* it's a definition */
+ {
+ /* skip leading/trailing whitespace */
+ while (isspace (*p))
+ ++p;
+ len = strlen (p);
+ while (len > 0 && isspace (p[len-1]))
+ p[--len] = '\0';
+ AddDef (name, p, 1);
+ /* find var refs in value */
+ FindAllVarRefs (p);
+ continue;
+ }
+ }
+ /* not a definition; find var refs anywhere in line */
+ FindAllVarRefs (input);
+ }
+}
+
+
+/*
+ Find definition by variable name.
+*/
+
+Def *FindDefByVar (s)
+char *s;
+{
+Def *dp;
+
+ for (dp = defList; dp != NULL; dp = dp->nextDef)
+ {
+ if (strcmp (dp->var, s) == 0)
+ return (dp);
+ }
+ return (NULL);
+}
+
+
+/*
+ Add a definition. If the name hasn't been seen yet, create a new
+ definition on the list. If the name has been seen, and replace is
+ non-zero, replace the current value with the new one. (replace will
+ be zero if we're just adding a variable which is known by its being
+ referenced somewhere.)
+*/
+
+AddDef (name, value, replace)
+char *name, *value;
+int replace;
+{
+Def *dp;
+
+ if ((dp = FindDefByVar (name)) == NULL)
+ {
+ if ((dp = (Def *) calloc (1, sizeof (Def))) == NULL)
+ panic ("AddDef: out of memory");
+ dp->var = NewString (name);
+ dp->val = NewString (value);
+ dp->simple = 0; /* assume not */
+ dp->nextDef = defList;
+ defList = dp;
+ ++nDefs;
+ }
+ else if (replace)
+ {
+ free (dp->val);
+ dp->val = NewString (value);
+ }
+}
+
+
+/*
+ Replace instances of '$$' with a single ^A.
+*/
+
+EncodeEscapes ()
+{
+Def *dp;
+char *p, *q;
+
+ for (dp = defList; dp != NULL; dp = dp->nextDef)
+ {
+ for (p = q = dp->val; *p != '\0'; p++, q++)
+ {
+ *q = *p;
+ if (*p == '$' && *(p+1) == '$')
+ {
+ *q = '\01';
+ p++;
+ }
+ }
+ *q = '\0';
+ }
+}
+
+
+/*
+ Replace instances of ^A with a '$'.
+*/
+
+DecodeEscapes ()
+{
+Def *dp;
+char *p;
+
+ for (dp = defList; dp != NULL; dp = dp->nextDef)
+ {
+ for (p = dp->val; *p != '\0'; p++)
+ {
+ if (*p == '\01')
+ *p = '$';
+ }
+ }
+}
+
+
+/*
+ Find variable reference in variable value. begin is set to
+ the index of the '$' and end is set to the index of the closing
+ delimiter. (If either is NULL, it is not set.)
+
+ recogEsc is non-zero (true) if '$$' is recognized as an escaped '$'
+ and skipped. It will be true during initial searching for var refs
+ and while substituting in source files, false while expanding variable
+ values.
+
+ $v, ${}, ${1}, ${v), etc. are not accepted as valid and are ignored.
+*/
+
+FindVarRef (s, beg, end, recogEsc)
+char *s;
+int *beg, *end, recogEsc;
+{
+int i;
+char c, delim;
+
+ i = 0;
+ for (;;)
+ {
+ while ((c = s[i]) != '\0')
+ {
+ if (c == '$')
+ {
+ if ((c = s[i+1]) == '{' || c == '(')
+ break;
+ if (recogEsc && c == '$') /* escaped $ */
+ ++i;
+ }
+ ++i;
+ }
+ if (c == '\0')
+ return (0); /* no reference */
+ if (beg != (int *) NULL)
+ *beg = i;
+ if (s[++i] == '{')
+ delim = '}';
+ else
+ delim = ')';
+ ++i;
+ if (!isalpha (s[i])) /* must have at least one char, must */
+ continue; /* begin with letter */
+ while ((c = s[++i]) != '\0')
+ {
+ if (c == delim) /* find matching delim */
+ {
+ if (end != (int *) NULL)
+ *end = i;
+ return (1);
+ }
+ if (!isalnum (c) && c != '_')
+ break;
+ }
+ }
+}
+
+
+FindAllVarRefs (s)
+char *s;
+{
+char name[BUFSIZ];
+int begin, end;
+
+ while (FindVarRef (s, &begin, &end, true))
+ {
+ /* add with empty value if unknown, */
+ /* but don't replace value if known */
+ strncpy (name, s + begin + 2, end - begin - 2);
+ name[end-begin-2] = '\0';
+ AddDef (name, "", 0);
+ s += end + 1;
+ }
+}
+
+
+/*
+ Pull out a variable reference, skipping leading '$(' or '${' and
+ trailing ')' or '}'.
+*/
+
+YankVarRef (dst, src, begin, end)
+char *dst, *src;
+int begin, end;
+{
+ strncpy (dst, src + begin + 2, end - begin - 2);
+ dst[end - begin - 2] = '\0';
+}
+
+
+/*
+ Look for variable references in a variable value and expand them
+ when possible. If a variable is referenced but never defined, it
+ disappears. If a variable is referenced, but its value has not itself
+ been fully expanded, defer expansion of value until another pass, at
+ which time the referenced variable might then be expanded. This
+ prevents infinite expansions on circular references.
+*/
+
+Expand (dp)
+Def *dp;
+{
+Def *dp2;
+/* partain: made 4 * BUFSIZ
+char buf[BUFSIZ];
+*/
+char buf[4 * BUFSIZ];
+int begin, end, vn;
+
+ while (FindVarRef (dp->val, &begin, &end, false))
+ {
+ YankVarRef (buf, dp->val, begin, end);
+ if ((dp2 = FindDefByVar (buf)) == NULL)
+ {
+ fprintf (stderr, "Expand error: can't find %s, ", buf);
+ panic ("quitting");
+ }
+ if (!dp2->simple) /* can't expand, give up for now */
+ break;
+ dp->val[begin] = '\0';
+ sprintf (buf, "%s%s%s", dp->val, dp2->val, &(dp->val)[end+1]);
+ free (dp->val);
+ dp->val = NewString (buf);
+ ++changes;
+ }
+ dp->simple = !FindVarRef (dp->val, NULL, NULL, false);
+}
+
+
+/*
+ Read through file, performing substitutions for any variables
+ known from Makefile. If a variable reference is found that is
+ for an unknown variable, leave it alone, as it may be a reference
+ to a real variable in a shell script.
+*/
+
+DoSub (f)
+FILE *f;
+{
+Def *dp;
+char input[BUFSIZ], var[BUFSIZ], *p;
+int begin, end;
+
+ while (fgets (input, sizeof (input), f) != NULL)
+ {
+ p = input;
+ while (FindVarRef (p, &begin, &end, true))
+ {
+ write (1, p, begin); /* write prefix */
+ YankVarRef (var, p, begin, end);
+ /* if var is known from makefile, write */
+ /* value, else just echo the reference */
+ if ((dp = FindDefByVar (var)) != NULL)
+ write (1, dp->val, strlen (dp->val));
+ else
+ write (1, p + begin, end - begin + 1);
+ p += end + 1;
+ }
+ write (1, p, strlen (p));
+ }
+}
+
+
+/*
+ Get next line from Makefile (combines continuation lines into one).
+ No overflow checking, oops.
+*/
+
+GetLine (f, lbuf)
+FILE *f;
+char *lbuf;
+{
+char buf[BUFSIZ];
+int loop = 1, haveLine = 0, len;
+
+ *lbuf = '\0';
+ while (loop && fgets (buf, sizeof (buf), f) != NULL)
+ {
+ loop = 0;
+ haveLine = 1;
+ len = strlen (buf);
+ if (len > 0 && buf[len-1] == '\n') /* trim newline */
+ buf[--len] = '\0';
+ if (len > 0 && buf[len-1] == '\\') /* need continuation */
+ {
+ loop = 1;
+ buf[--len] = ' ';
+ }
+ strcat (lbuf, buf);
+ }
+ return (haveLine);
+}
+
+
+/*
+ Allocate space for a string, copy the string into it, and return
+ a pointer to the copy.
+*/
+
+
+char *NewString (s)
+char *s;
+{
+char *p;
+
+ if ((p = calloc (1, strlen (s) + 1)) == NULL)
+ panic ("NewString: out of space");
+ return (strcpy (p, s));
+}
+
+
+panic (s)
+char *s;
+{
+ fprintf (stderr, "%s\n", s);
+ exit (1);
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/msub/msub.ms b/web/glasgow/lit2x-0.16/grasp-utils/msub/msub.ms
new file mode 100644
index 0000000000..7fe019f509
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/msub/msub.ms
@@ -0,0 +1,128 @@
+.SH
+Theory of Operation
+.LP
+.I msub
+reads the makefile in the current directory (or the file named after the
+.B \-f
+flag) and finds all variable definitions and references.
+Definitions are lines of the form ``\fIname\fR = \fIvalue\fR''.
+References are instances of ``$(\fIvar\fR)'' or ``${\fIvar\fR}'', either in
+the value part of definition lines, or any part of dependency or command lines.
+Then variable values are examined to eliminate references to other variables
+by replacing the referenced variables with their values.
+Variables which are referenced but never defined have a value of the empty
+string.
+.LP
+Then
+.I msub
+reads any files named on the command line (or
+.I stdin
+if none) and looks for instances of ``$(\fIvar\fR)'' or ``${\fIvar\fR}'',
+where
+.I var
+is known from the makefile, and substitutes the value of
+.I var .
+.SH
+Purpose
+.LP
+The motivation for
+.I msub
+is that project configuration information is often contained in makefiles
+and it is often desirable to make use of that information.
+.I msub
+allows files to be produced from templates that contain references
+to makefile variables.
+In this sense it is similar to the way that the C preprocessor
+.I cpp
+uses #define statements in header files; the
+makefile is the implicit ``header'' file and definition lines are the
+``#define'' statements.
+.LP
+Although it is possible to use
+.I cpp
+to perform substitutions on templates, a disadvantage of
+.I cpp
+is that it modifies its source in other ways (eg., lines beginning with
+``#'' are special and comments (``/* ... */'') are deleted.
+Also, it is necessary to pass a -D flag for every symbol to be substituted.
+Similarly, for C programs it can be simpler to use
+.I msub
+to produce a single configuration header file from a template
+than to pass a lot of -D flags to each invocation of
+.I cc .
+.LP
+.I msub
+performs no textual modification besides substitution of references
+to makefile variables; it leaves everything else alone.
+In particular,
+references to variables not known from the makefile are left untouched.
+This allows
+.I msub
+to be used to produce shell scripts that use variables of
+their own.
+.LP
+.I msub
+is particularly useful in software projects that use
+.I imake .
+Virtually all configuration information is propagated into makefiles
+thus produced, so it is available for propagation into other files using
+.I msub .
+.SH
+Problems
+.LP
+If
+.I msub
+is used to produce shell scripts, it is unwise for the script to use names
+for its own variables that are the same as those in the makefile.
+The problem can be avoided entirely if, for instance, variables in makefiles
+are all uppercase and the scripts' own variables are lowercase or mixed case.
+.LP
+Circular references in makefile variables are not expanded.
+If a makefile contains the definitions ``X = ${Y}'' and ``Y = ${X}'',
+neither X nor Y will be expanded.
+But that is really a problem with the makefile, not
+.I msub .
+.LP
+.I make
+recognizes
+.B \-f\ \-
+to mean the makefile should be read from
+.I stdin .
+.I msub
+does not.
+.LP
+CC, YACC, etc., have implicit values in
+.I make
+even if not defined in the makefile.
+Not true in
+.I msub .
+.LP
+.I msub
+is more restrictive in the variable names that it recognizes and
+performs substitutions on.
+Names that do not begin with a letter and
+that contain any characters besides letters, digits and underscores are
+ignored.
+This means that variable names such as ``${1}'' are not recognized;
+the reason for this is that shell scripts often use such variables and
+they should be left untouched.
+Also,
+``$\fIx\fR'' is legal in
+.I make
+when
+.I x
+is a single character, but
+.I msub
+ignores such references.
+.i msub
+.LP
+.I make
+allows variables to be defined on the command line.
+.I msub
+does not.
+.LP
+If you try to be tricky with your variable references, e.g., by using
+recursive references, you may get burned.
+.LP
+There is no way to prevent substitution, in a source file, of a reference to
+a variable known from the makefile.
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/msub/test.makefile b/web/glasgow/lit2x-0.16/grasp-utils/msub/test.makefile
new file mode 100644
index 0000000000..b20a2b7868
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/msub/test.makefile
@@ -0,0 +1,18 @@
+foo = ${bar}
+bar = ${ugh}
+ugh = Huh?
+space = x
+a = ${wildcard x}
+
+# xyz should be found in next line, given empty value and then the
+# value should be replaced later...
+
+c : ${xyz}
+
+xyz = abc
+
+
+dollar = $$
+doubledollar = ${dollar}${dollar}
+
+
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/msub/test.stdout b/web/glasgow/lit2x-0.16/grasp-utils/msub/test.stdout
new file mode 100644
index 0000000000..506999f3c1
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/msub/test.stdout
@@ -0,0 +1,11 @@
+foo = Huh?
+bar = Huh?
+ugh = Huh?
+xy
+${wildcard x}
+
+This (abc) should be abc.
+
+This should be a single dollar: $
+This should be a double dollar: $$
+So should this: $$
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/msub/testfile b/web/glasgow/lit2x-0.16/grasp-utils/msub/testfile
new file mode 100644
index 0000000000..ba3f4ebbf0
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/msub/testfile
@@ -0,0 +1,11 @@
+foo = ${foo}
+bar = ${bar}
+ugh = ${ugh}
+${space}y
+${a}
+
+This (${xyz}) should be abc.
+
+This should be a single dollar: ${dollar}
+This should be a double dollar: ${dollar}${dollar}
+So should this: ${doubledollar}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/perl-4.035-fixes b/web/glasgow/lit2x-0.16/grasp-utils/perl-4.035-fixes
new file mode 100644
index 0000000000..e456aa49e8
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/perl-4.035-fixes
@@ -0,0 +1,180 @@
+From mjeffery@reed.edu Sun Nov 29 14:07:23 1992
+From: mjeffery@reed.edu (Mark Jefferys)
+Newsgroups: comp.lang.perl
+Subject: Re: Recursion error in perl 4.035 ?
+Date: 28 Nov 92 23:31:14 GMT
+Organization: Reed College, Portland, OR
+
+In article <1f7uvvINN9tp@roundup.crhc.uiuc.edu> parkes@uiuc.edu writes:
+
+% In cons.c, change the code at or around 1423 from
+%
+% if (willsave)
+% (void)apush(tosave,arg->arg_ptr.arg_str);
+%
+% to
+%
+% if (willsave && arg->arg_ptr.arg_str )
+% (void)apush(tosave,arg->arg_ptr.arg_str);
+
+This is half of my patch to which Larry gave a "Looks OK to me."
+It's been a few months, do I'll post it again.
+
+
+Mark
+
+
+Index: cons.c
+*** Orig/cons.c Thu Jun 11 22:42:01 1992
+--- cons.c Sun Jun 28 18:31:20 1992
+***************
+*** 1353,1359 ****
+
+ /* in any event, save the iterator */
+
+! (void)apush(tosave,cmd->c_short);
+ }
+ shouldsave |= tmpsave;
+ }
+--- 1353,1360 ----
+
+ /* in any event, save the iterator */
+
+! if (cmd->c_short) /* Better safe than sorry */
+! (void)apush(tosave,cmd->c_short);
+ }
+ shouldsave |= tmpsave;
+ }
+***************
+*** 1420,1426 ****
+ shouldsave = TRUE;
+ break;
+ }
+! if (willsave)
+ (void)apush(tosave,arg->arg_ptr.arg_str);
+ return shouldsave;
+ }
+--- 1421,1427 ----
+ shouldsave = TRUE;
+ break;
+ }
+! if (willsave && arg->arg_ptr.arg_str)
+ (void)apush(tosave,arg->arg_ptr.arg_str);
+ return shouldsave;
+ }
+--
+Mark Jefferys Internet: mjeffery@reed.edu
+
+From ezk@cs.columbia.edu Fri Dec 4 19:44:03 1992
+From: ezk@cs.columbia.edu (Erez "HWank1" Zadok)
+Newsgroups: comp.lang.perl
+Subject: REPOST: FIXES to perl/makewhatis (core dump on OW3 man pages)
+Date: 3 Dec 92 12:42:05 GMT
+
+[This is a repost... -Erez]
+
+I've found three small bugs in the the latest version of perl (4.035), which
+I fixed.
+
+The bugs only appeared when I got Tom Christiansen's man package, and ran
+the makewhatis script. Furthermore, it only occurred for one particular set
+of manual pages -- SunOS's OpenWindows 3.
+
+Since it seemed related to DBM, I tried to recompile perl with several
+possible combinations of Sun's /bin/cc, gcc (2.2.2), ndbm, gdbm,
+- -DDEBUGGING, -traditional (for gcc), Perl's malloc, Sun's malloc, etc. to no
+avail. Perl was still dumping core with a segmentation fault. "make test"
+was ok. I was running on various Sun 4 machines, running SunOS 4.1.2.
+
+After debugging I found out that perl was trying to dereference pointers
+that were not initialized.
+
+I fixed this by adding initialization to three declarations in perl.h. The
+ones to rsfp and statstab were needed for non-compressed man pages. When I
+started using compressed man pages I discovered I had to initialize fdpid as
+well. Now everything works fine. Here is the diff file:
+
+*** array.h.orig Tue Nov 24 02:16:30 1992
+--- array.h Mon Nov 23 14:31:16 1992
+***************
+*** 17,22 ****
+--- 17,33 ----
+ *
+ */
+
++ #ifdef NULL
++ #undef NULL
++ #endif
++ #ifndef I286
++ # define NULL 0
++ #else
++ # define NULL 0L
++ #endif
++ #define Null(type) ((type)NULL)
++ #define Nullarray Null(ARRAY*)
++
+ struct atbl {
+ STR **ary_array;
+ STR **ary_alloc;
+*** perl.h.orig Tue Nov 24 02:16:10 1992
+--- perl.h Mon Nov 23 14:30:51 1992
+***************
+*** 868,874 ****
+
+ EXT char *hexdigit INIT("0123456789abcdef0123456789ABCDEFx");
+ EXT char *origfilename;
+! EXT FILE * VOLATILE rsfp;
+ EXT char buf[1024];
+ EXT char *bufptr;
+ EXT char *oldbufptr;
+--- 868,874 ----
+
+ EXT char *hexdigit INIT("0123456789abcdef0123456789ABCDEFx");
+ EXT char *origfilename;
+! EXT FILE * VOLATILE rsfp INIT(Nullfp);
+ EXT char buf[1024];
+ EXT char *bufptr;
+ EXT char *oldbufptr;
+***************
+*** 952,958 ****
+ EXT struct stat statbuf;
+ EXT struct stat statcache;
+ EXT STAB *statstab INIT(Nullstab);
+! EXT STR *statname;
+ #ifndef MSDOS
+ EXT struct tms timesbuf;
+ #endif
+--- 952,958 ----
+ EXT struct stat statbuf;
+ EXT struct stat statcache;
+ EXT STAB *statstab INIT(Nullstab);
+! EXT STR *statname INIT(Nullstr);
+ #ifndef MSDOS
+ EXT struct tms timesbuf;
+ #endif
+***************
+*** 1013,1019 ****
+ EXT ARRAY *lineary; /* lines of script for debugger */
+ EXT ARRAY *dbargs; /* args to call listed by caller function */
+
+! EXT ARRAY *fdpid; /* keep fd-to-pid mappings for mypopen */
+ EXT HASH *pidstatus; /* keep pid-to-status mappings for waitpid */
+
+ EXT int *di; /* for tmp use in debuggers */
+--- 1013,1019 ----
+ EXT ARRAY *lineary; /* lines of script for debugger */
+ EXT ARRAY *dbargs; /* args to call listed by caller function */
+
+! EXT ARRAY *fdpid INIT(Nullarray); /* keep fd-to-pid mappings for mypopen */
+ EXT HASH *pidstatus; /* keep pid-to-status mappings for waitpid */
+
+ EXT int *di; /* for tmp use in debuggers */
+
+
+Erez Zadok.
+Central Research Facilities.
+Columbia University Department of Computer Science.
+- ---
+"A wank's morning starts one jiffy | Arpa: ezk@cs.columbia.edu
+ after midnight." | Usenet: ...!rutgers!columbia!cs!ezk
+ -HebrewWank #1 (US meaning, not UK!) | Bitnet: erzus@cuvmb.BITNET
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/Jmakefile b/web/glasgow/lit2x-0.16/grasp-utils/scripts/Jmakefile
new file mode 100644
index 0000000000..22d1ccb32f
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/Jmakefile
@@ -0,0 +1,79 @@
+PROGRAMS = lndir \
+ mkdirhier \
+ runstdtest \
+ mkdependC \
+ fastmake \
+ lmake \
+ zap-if-same \
+ moan-if-old \
+ ltx \
+ perltags
+
+all:: $(PROGRAMS)
+/* stuff to have before we get going */
+MsubNeededHere($(PROGRAMS))
+
+/* === BUILD STUFF (installation, etc., below) ========== */
+
+/* std X11 stuff */
+MsubProgramScriptTarget(BourneShell,mkdirhier,mkdirhier.sh,/*no flags*/,/*no dep*/)
+
+BuildPgmFromOneCFile(lndir)
+#if 0
+MsubProgramScriptTarget(BourneShell,lndir,lndir.sh,/*no flags*/,/*no dep*/)
+InstallScriptTarget(lndir, $(INSTSCRIPTDIR))
+#endif
+
+MsubMakefileDependentProgramScriptTarget(PerlCmd,runstdtest,runstdtest.prl,/*no flags*/,/*Makefile*/)
+MsubMakefileDependentProgramScriptTarget(PerlCmd,ltx,ltx.prl,/*no flags*/,/*Makefile*/)
+MsubProgramScriptTarget(PerlCmd,fastmake,fastmake.prl,/*no flags*/,/**/)
+MsubProgramScriptTarget(PerlCmd,zap-if-same,zap-if-same.prl,/*no flags*/,/**/)
+MsubProgramScriptTarget(PerlCmd,moan-if-old,moan-if-old.prl,/*no flags*/,/**/)
+MsubProgramScriptTarget(PerlCmd,perltags,perltags.prl,/*no flags*/,/**/)
+
+MsubProgramScriptTarget(BourneShell,lmake,lmake.sh,/*no flags*/,/*no dep*/)
+
+/*
+mkdependC has to go in "bin" directory, because there may be
+machine-dependent ideas of what CC to use, etc.
+
+ltx, runstdtest: ditto, but only because of TMPDIR
+*/
+MsubMakefileDependentProgramScriptTarget(PerlCmd,mkdependC,mkdependC.prl,/*noflags*/,/*Makefile*/)
+
+#ifdef UseCCMakeDepend
+install::
+ @echo "install makedepend (in ${CURRENT_DIR}) by hand..."
+#endif
+/*
+ lobotomized... install by hand...
+#ifdef UseCCMakeDepend
+InstallProgramTarget(makedepend,$(BINDIR))
+#endif
+*/
+
+/* === INSTALLATION ======== */
+
+/* the rest of these vary from std/useful to hackish dans le extreme */
+
+MakeDirectories(install, $(INSTBINDIR) $(INSTSCRIPTDIR))
+InstallScriptTarget(fastmake, $(INSTSCRIPTDIR))
+InstallScriptTarget(lmake, $(INSTSCRIPTDIR))
+InstallBinaryTarget(lndir, $(INSTBINDIR))
+InstallScriptTarget(ltx, $(INSTBINDIR))
+InstallScriptTarget(mkdependC, $(INSTBINDIR))
+InstallScriptTarget(mkdirhier, $(INSTSCRIPTDIR))
+InstallScriptTarget(perltags, $(INSTSCRIPTDIR))
+InstallScriptTarget(runstdtest, $(INSTBINDIR))
+InstallScriptTarget(zap-if-same, $(INSTSCRIPTDIR))
+InstallScriptTarget(moan-if-old, $(INSTSCRIPTDIR))
+
+InstallManPageTarget(lndir,$(INSTCOMMANDIR),$(COMMANSUFFIX))
+InstallManPageTarget(mkdirhier,$(INSTCOMMANDIR),$(COMMANSUFFIX))
+
+/* === OTHER STUFF ========= */
+
+ExtraStuffToClean($(PROGRAMS))
+
+ClearTagsFile()
+PerlTagsTarget( *.prl ) /* nothing for the Bourne shell scripts */
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/fastmake.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/fastmake.prl
new file mode 100644
index 0000000000..388b4ed44d
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/fastmake.prl
@@ -0,0 +1,126 @@
+#! /usr/local/bin/perl
+#
+($Pgm = $0) =~ s/.*\/([^\/]+)$/\1/;
+$Usage = "\n" . <<EOUSAGE;
+Usage:
+ $Pgm [-? or -help] [-k] [-n] [-v] [-t] dir/module-target(s)
+
+This script runs `make' to build the requested target, WITHOUT
+including the dependencies generated by `mkdependHS' (i.e., all those
+derived from import declarations).
+
+With a -t flag, it also sets the modification time of the resulting
+.hi file (one target only, please) to some EARLY date, so that changes
+to that interface will not trigger much useless recompilation.
+
+Typical uses, for module "Bar" in directory "foo":
+
+(1) You've changed "Bar" and you want to recompile it; you know that
+ other module interfaces are stable, so you'd rather do without all
+ of `make''s prognostications:
+
+ $Pgm foo/Bar.s
+
+(2) You've ADDED a new function to "Bar"; you want to recompile that
+ module, BUT NOT TRIGGER LOTS OF FURTHER COMPILATION because of the
+ "changed" interface file:
+
+ $Pgm -t foo/Bar.s
+
+USE AT YOUR OWN RISK: you can make a big mess with this script!
+EOUSAGE
+
+$Makefile = 'Makefile';
+$Tmpfile = "/tmp/Makefile$$";
+chop($Arch = `/bin/arch`);
+$SleazyTouch = '/usr/5bin/touch';
+$DoTouch = 0;
+$Verbose = 0;
+$MakeFlags = '';
+
+sub rm_temp_file {
+ print STDERR "rm $Tmpfile\n" if $Verbose;
+ unlink $Tmpfile;
+ exit(1);
+}
+$SIG{'INT'} = 'rm_temp_file';
+$SIG{'QUIT'} = 'rm_temp_file';
+
+$Target = '';
+$DirMod = ''; # the dir/module-file to make
+
+# process ARGV
+while ($_ = $ARGV[0]) {
+ shift(@ARGV);
+ if (/^-\?$/ || /^-help$/) {
+ print $Usage;
+ exit 1;
+ } elsif (/^-v$/) {
+ $Verbose = 1;
+ } elsif (/^-t$/) {
+ $Do_touch = 1;
+ } elsif (/^-k$/) {
+ $MakeFlags .= ' -k';
+ } elsif (/^-n$/) {
+ $MakeFlags .= ' -n';
+ } elsif (/^-d$/) {
+ $MakeFlags .= ' -d';
+ } elsif (/^-/) {
+ print STDERR "$Pgm: unknown option: $_\n\n$Usage";
+ exit 1;
+ } elsif (/^([A-Z_]+)=(.+)/) {
+ $MakeFlags .= " $1=\"$2\"";
+
+ } elsif ($Do_touch) { # the module file
+ $Target = $_;
+ if ( /([^\/]+\/[^\/\.]+)\.[a-z]+/ ) {
+ $DirMod = $1;
+ } else {
+ print STDERR "$Pgm: argument not of the form: directory/Module.suffix: $_\n\n$Usage";
+ exit 1;
+ }
+ } else { # accumulate as "Target"...
+ $Target .= " $_";
+ }
+}
+
+if ($Do_touch && $Target =~ / /) {
+ print STDERR "$Pgm: too many arguments\n\n$Usage";
+ exit 1;
+}
+
+open(INF, "<$Makefile") || die "Can't open $Makefile for input\n";
+
+open(OUTF,">$Tmpfile") || die "Can't open $Tmpfile for output\n";
+select(OUTF);
+
+$_ = <INF>;
+
+# copy through until ...
+while ( $_ && ! /^# DO NOT DELETE: Beginning of Haskell dependencies/ ) {
+ print $_;
+ $_ = <INF>;
+}
+
+# now copy through 'til the end, omittin the %.[so] : %.hi dependencies
+while ( $_ ) {
+ print $_ if ! /^\S+ : \S+\.hi$/;
+ $_ = <INF>;
+}
+
+close(INF);
+close(OUTF);
+
+if ($Arch ne "sun3") {
+ $Make = 'make JMAKE=jmake LIT2PGM=lit2pgm LIT2LATEX=lit2latex LIT2TEXI=lit2texi MKDEPENDLIT=mkdependlit MAKEINFO=makeinfo POSTMAKEINFO=postmakeinfo';
+} else {
+ $Make = 'make';
+}
+print STDERR "$Make $MakeFlags -f $Tmpfile $Target; rm $Tmpfile\n" if $Verbose;
+
+system( "$Make $MakeFlags -f $Tmpfile $Target; rm $Tmpfile" );
+
+if ($Do_touch) {
+ print STDERR "$SleazyTouch -m 01010101 $DirMod\.hi\n" if $Verbose;
+ system( "$SleazyTouch -m 01010101 $DirMod\.hi" );
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/lmake.sh b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lmake.sh
new file mode 100644
index 0000000000..133405cb07
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lmake.sh
@@ -0,0 +1,2 @@
+#! /bin/sh
+make JMAKE=jmake LIT2PGM=lit2pgm LIT2LATEX=lit2latex LIT2TEXI=lit2texi MKDEPENDLIT=mkdependlit MAKEINFO=makeinfo POSTMAKEINFO=postmakeinfo $*
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.c b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.c
new file mode 100644
index 0000000000..d365de6755
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.c
@@ -0,0 +1,217 @@
+/* $XConsortium: lndir.c,v 1.5 91/07/21 15:52:11 rws Exp $ */
+/* Create shadow link tree (after X11R4 script of the same name)
+ Mark Reinhold (mbr@lcs.mit.edu)/3 January 1990 */
+
+/* Copyright 1990, Massachusetts Institute of Technology
+
+ Permission to use, copy, modify, and distribute this program for any purpose
+ and without fee is hereby granted, provided that this copyright and
+ permission notice appear on all copies and supporting documentation, that
+ the name of MIT not be used in advertising or publicity pertaining to
+ distribution of this program without specific prior permission, and that
+ notice be given in supporting documentation that copying and distribution is
+ by permission of MIT. MIT makes no representations about the suitability of
+ this software for any purpose. It is provided "as is" without expressed or
+ implied warranty.
+*/
+
+/* From the original /bin/sh script:
+
+ Used to create a copy of the a directory tree that has links for all
+ non-directories (except those named RCS or SCCS). If you are
+ building the distribution on more than one machine, you should use
+ this script.
+
+ If your master sources are located in /usr/local/src/X and you would like
+ your link tree to be in /usr/local/src/new-X, do the following:
+
+ % mkdir /usr/local/src/new-X
+ % cd /usr/local/src/new-X
+ % lndir ../X
+*/
+
+/*#include <X11/Xos.h> */
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <errno.h>
+
+#ifndef X_NOT_POSIX
+#include <dirent.h>
+#else
+#ifdef SYSV
+#include <dirent.h>
+#else
+#ifdef USG
+#include <dirent.h>
+#else
+#include <sys/dir.h>
+#ifndef dirent
+#define dirent direct
+#endif
+#endif
+#endif
+#endif
+
+extern int errno;
+int silent;
+
+void
+quit (code, fmt, a1, a2, a3)
+char *fmt;
+{
+ fprintf (stderr, fmt, a1, a2, a3);
+ putc ('\n', stderr);
+ exit (code);
+}
+
+void
+quiterr (code, s)
+char *s;
+{
+ perror (s);
+ exit (code);
+}
+
+void
+msg (fmt, a1, a2, a3)
+char *fmt;
+{
+ fprintf (stderr, fmt, a1, a2, a3);
+ putc ('\n', stderr);
+}
+
+
+/* Recursively create symbolic links from the current directory to the "from"
+ directory. Assumes that files described by fs and ts are directories. */
+
+dodir (fn, fs, ts, rel)
+char *fn; /* name of "from" directory, either absolute or
+ relative to cwd */
+struct stat *fs, *ts; /* stats for the "from" directory and cwd */
+int rel; /* if true, prepend "../" to fn before using */
+{
+ DIR *df;
+ struct dirent *dp;
+ char buf[MAXPATHLEN + 1], *p;
+ char symbuf[MAXPATHLEN + 1];
+ struct stat sb, sc;
+ int n_dirs;
+
+ if ((fs->st_dev == ts->st_dev) && (fs->st_ino == ts->st_ino)) {
+ msg ("%s: From and to directories are identical!", fn);
+ return 1;
+ }
+
+ if (rel)
+ strcpy (buf, "../");
+ else
+ buf[0] = '\0';
+ strcat (buf, fn);
+
+ if (!(df = opendir (buf))) {
+ msg ("%s: Cannot opendir", buf);
+ return 1;
+ }
+
+ p = buf + strlen (buf);
+ *p++ = '/';
+ n_dirs = fs->st_nlink;
+ while (dp = readdir (df)) {
+ strcpy (p, dp->d_name);
+
+ if (n_dirs > 0) {
+ if (stat (buf, &sb) < 0) {
+ perror (buf);
+ continue;
+ }
+
+ if (sb.st_mode & S_IFDIR) {
+ /* directory */
+ n_dirs--;
+ if (dp->d_name[0] == '.' &&
+ (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
+ dp->d_name[2] == '\0')))
+ continue;
+ if (!strcmp (dp->d_name, "RCS"))
+ continue;
+ if (!strcmp (dp->d_name, "SCCS"))
+ continue;
+ if (!silent)
+ printf ("%s:\n", buf);
+ if ((stat (dp->d_name, &sc) < 0) && (errno == ENOENT)) {
+ if (mkdir (dp->d_name, 0777) < 0 ||
+ stat (dp->d_name, &sc) < 0) {
+ perror (dp->d_name);
+ continue;
+ }
+ }
+ if (readlink (dp->d_name, symbuf, sizeof(symbuf) - 1) >= 0) {
+ msg ("%s: is a link instead of a directory\n", dp->d_name);
+ continue;
+ }
+ if (chdir (dp->d_name) < 0) {
+ perror (dp->d_name);
+ continue;
+ }
+ dodir (buf, &sb, &sc, (buf[0] != '/'));
+ if (chdir ("..") < 0)
+ quiterr (1, "..");
+ continue;
+ }
+ }
+
+ /* non-directory */
+ if (symlink (buf, dp->d_name) < 0) {
+ int saverrno = errno;
+ int symlen;
+ symlen = readlink(dp->d_name, symbuf, sizeof(symbuf) - 1);
+ errno = saverrno;
+ if (symlen > 0)
+ symbuf[symlen] = '\0';
+ if (symlen < 0 || strcmp(symbuf, buf))
+ perror (dp->d_name);
+ }
+ }
+
+ closedir (df);
+ return 0;
+}
+
+
+main (ac, av)
+int ac;
+char **av;
+{
+ char *fn, *tn;
+ struct stat fs, ts;
+
+ silent = 0;
+ if (ac > 1 && !strcmp(av[1], "-silent")) {
+ silent = 1;
+ }
+ if (ac < silent + 2 || ac > silent + 3)
+ quit (1, "usage: %s [-silent] fromdir [todir]", av[0]);
+
+ fn = av[silent + 1];
+ if (ac == silent + 3)
+ tn = av[silent + 2];
+ else
+ tn = ".";
+
+ /* to directory */
+ if (stat (tn, &ts) < 0)
+ quiterr (1, tn);
+ if (!(ts.st_mode & S_IFDIR))
+ quit (2, "%s: Not a directory", tn);
+ if (chdir (tn) < 0)
+ quiterr (1, tn);
+
+ /* from directory */
+ if (stat (fn, &fs) < 0)
+ quiterr (1, fn);
+ if (!(fs.st_mode & S_IFDIR))
+ quit (2, "%s: Not a directory", fn);
+
+ exit (dodir (fn, &fs, &ts, 0));
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.man b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.man
new file mode 100644
index 0000000000..ae5b4285bd
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.man
@@ -0,0 +1,61 @@
+.TH LNDIR 1 "Release 5" "X Version 11"
+.SH NAME
+lndir \- create a shadow directory of symbolic links to another directory tree
+.SH SYNOPSIS
+.B lndir
+fromdir [todir]
+.SH DESCRIPTION
+.I Lndir
+makes a shadow copy
+.I todir
+of a directory tree
+.I fromdir,
+except that the shadow is not
+populated with real files but instead with symbolic links pointing at
+the real files in the
+.I fromdir
+directory tree. This is usually useful for maintaining source code for
+different machine architectures. You create a shadow directory
+containing links to the real source which you will have usually NFS
+mounted from a machine of a different architecture, and then recompile
+it. The object files will be in the shadow directory, while the
+source files in the shadow directory are just symlinks to the real
+files.
+.PP
+This has the advantage that if you update the source, you need not
+propagate the change to the other architectures by hand, since all
+source in shadow directories are symlinks to the real thing: just cd
+to the shadow directory and recompile away.
+.PP
+The
+.I todir
+argument is optional and defaults to the current directory. The
+.I fromdir
+argument may be relative (e.g., ../src) and is relative to
+.I todir
+(not the current directory).
+.PP
+.ft B
+Note that RCS and SCCS directories are not shadowed.
+.ft
+.PP
+Note that if you add files, you must run
+.I lndir
+again. Deleting files is a more painful problem; the symlinks will
+just point into never never land.
+.SH BUGS
+.I Patch
+gets upset if it cannot change the files. You should never run
+.I patch
+from a shadow directory anyway.
+.PP
+You need to use something like
+.nf
+ find todir -type l -print | xargs rm
+.fi
+to clear out all files before you can relink (if fromdir moved, for instance).
+Something like
+.nf
+ find . \\! -type d -print
+.fi
+will find all files that are not directories.
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.sh b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.sh
new file mode 100644
index 0000000000..f09bf7f590
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/lndir.sh
@@ -0,0 +1,85 @@
+#! /bin/sh
+
+# lndir - create shadow link tree
+#
+# $XConsortium: lndir.sh,v 1.8 91/04/15 17:55:03 rws Exp $
+#
+# Used to create a copy of the a directory tree that has links for all
+# non- directories (except those named RCS or SCCS). If you are
+# building the distribution on more than one machine, you should use
+# this script.
+#
+# If your master sources are located in /usr/local/src/X and you would like
+# your link tree to be in /usr/local/src/new-X, do the following:
+#
+# % mkdir /usr/local/src/new-X
+# % cd /usr/local/src/new-X
+# % lndir ../X
+
+USAGE="Usage: $0 fromdir [todir]"
+
+if [ $# -lt 1 -o $# -gt 2 ]
+then
+ echo "$USAGE"
+ exit 1
+fi
+
+DIRFROM=$1
+
+if [ $# -eq 2 ];
+then
+ DIRTO=$2
+else
+ DIRTO=.
+fi
+
+if [ ! -d $DIRTO ]
+then
+ echo "$0: $DIRTO is not a directory"
+ echo "$USAGE"
+ exit 2
+fi
+
+cd $DIRTO
+
+if [ ! -d $DIRFROM ]
+then
+ echo "$0: $DIRFROM is not a directory"
+ echo "$USAGE"
+ exit 2
+fi
+
+pwd=`pwd`
+
+if [ `(cd $DIRFROM; pwd)` = $pwd ]
+then
+ echo "$pwd: FROM and TO are identical!"
+ exit 1
+fi
+
+for file in `ls -af $DIRFROM`
+do
+ if [ ! -d $DIRFROM/$file ]
+ then
+ ln -s $DIRFROM/$file .
+ else
+ if [ $file != RCS -a $file != SCCS -a $file != . -a $file != .. ]
+ then
+ echo $file:
+ mkdir $file
+ (cd $file
+ pwd=`pwd`
+ case "$DIRFROM" in
+ /*) ;;
+ *) DIRFROM=../$DIRFROM ;;
+ esac
+ if [ `(cd $DIRFROM/$file; pwd)` = $pwd ]
+ then
+ echo "$pwd: FROM and TO are identical!"
+ exit 1
+ fi
+ $0 $DIRFROM/$file
+ )
+ fi
+ fi
+done
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/ltx.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/ltx.prl
new file mode 100644
index 0000000000..1bce758270
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/ltx.prl
@@ -0,0 +1,215 @@
+$Pgm = $0; $Pgm =~ s/.*\/([^\/]+)$/\1/;
+#
+# set up signal handler
+sub quit_upon_signal { &rm_temp_files_and_exit(); }
+$SIG{'INT'} = 'quit_upon_signal';
+$SIG{'QUIT'} = 'quit_upon_signal';
+#
+$Verbose = 0;
+if ($ARGV[0] eq '-v') {
+ $Verbose = 1;
+ shift(@ARGV);
+}
+#
+die "$Pgm: must have exactly one argument\n" if $#ARGV != 0;
+# figure out input file and its filename root
+if (-f $ARGV[0]) {
+ $TeX_input = $ARGV[0];
+ if ($TeX_input =~ /(.+)\.[^\.\/\n]+$/) {
+ $TeX_root = $1;
+ } else {
+ $TeX_root = $TeX_input;
+ }
+} elsif (-f $ARGV[0].'.tex') {
+ $TeX_input = $ARGV[0].'.tex';
+ $TeX_root = $ARGV[0];
+} else {
+ die "$Pgm: input file $ARGV[0] doesn't exist\n";
+}
+
+sub rm_temp_files {
+ system("rm -f $(TMPDIR)/ltx-*.$$");
+}
+sub rm_temp_files_and_exit {
+ system("rm -f $(TMPDIR)/ltx-*.$$");
+ exit(1);
+}
+$SIG{'INT'} = 'rm_temp_files_and_exit';
+$SIG{'QUIT'} = 'rm_temp_files_and_exit';
+
+sub die_gracefully {
+ local($msg) = @_;
+
+ print STDERR $msg;
+ &rm_temp_files_and_exit();
+}
+
+# must read through root file to see if a \bibliography
+# is there...
+$Bibliography_requested = 0;
+open(TEXIF, "<$TeX_input")
+ || &die_gracefully("$Pgm: Can't read $TeX_input\n");
+while (<TEXIF>) {
+ $Bibliography_requested = 1 if /^\\bibliography/;
+}
+close(TEXIF);
+&die_gracefully("$Pgm: reading $TeX_input had errors\n") if $? >> 8;
+
+# run latex first time (?)
+&run_latex(); # sets $Says_labels_changed
+$Times_run = 1;
+
+while (&something_more_needed()) {
+
+ print STDERR "labels_changed=$Says_label_changed;bibtex_needed=$BibTeX_run_needed;makeindex_needed=$MakeIndex_run_needed\n" if $Verbose;
+
+ if ($BibTeX_run_needed) {
+ &run_bibtex();
+ }
+ if ($MakeIndex_run_needed) {
+ unlink "$TeX_root.ind";
+ (system("makeindex $TeX_root.idx") >> 8)
+ && &die_gracefully("$Pgm: makeindex $TeX_root.idx had errors\n");
+ }
+
+ # save (copy) .aux file as .aux-prev file for future ref
+ # ditto for .idx file
+ unlink "$TeX_root.aux-prev";
+ (system("cp $TeX_root.aux $TeX_root.aux-prev") >> 8)
+ && &die_gracefully("$Pgm: cp $TeX_root.aux $TeX_root.aux-prev failed\n");
+ if (-f "$TeX_root.idx") {
+ unlink "$TeX_root.idx-prev";
+ (system("cp $TeX_root.idx $TeX_root.idx-prev") >> 8)
+ && &die_gracefully("$Pgm: cp $TeX_root.idx $TeX_root.idx-prev failed\n");
+ }
+
+ # run latex again
+ &run_latex(); # sets $Says_labels_changed
+ $Times_run++;
+
+ if ($Times_run >= 4) {
+ print STDERR "*** I don't run LaTeX more than four times;\n";
+ print STDERR "*** Something is probably wrong...\n";
+ &rm_temp_files_and_exit();
+ }
+}
+&rm_temp_files();
+exit(0);
+
+sub run_latex {
+ $Says_labels_changed = 0;
+ $Multiply_defined_labels = 0;
+
+ select(STDERR); $| = 1; select(STDOUT); # no buffering on STDERR
+ print STDERR "$Pgm: *** running LaTeX...\n" if $Verbose;
+ unlink "$TeX_root.dvi";
+
+ open(LTXPIPE, "latex $TeX_input 2>&1 |")
+ || &die_gracefully("$Pgm: Can't run latex pipe\n");
+ while (<LTXPIPE>) {
+ $Multiply_defined_labels = 1 if /^LaTeX Warning: Label .* multiply defined/;
+ $Says_labels_changed = 1 if /^LaTeX Warning: Label\(s\) may have changed/
+ && ! $Multiply_defined_labels;
+ print STDERR $_;
+ }
+ close(LTXPIPE);
+ &die_gracefully("$Pgm: LaTeX run had errors\n") if $? >> 8;
+
+ # sort .idx file, because this helps makeindex
+ # (can you say `bug'?)
+ if (-f "$TeX_root.idx") {
+ print STDERR "$Pgm: *** sorting $TeX_root.idx...\n" if $Verbose;
+ (system("sort $TeX_root.idx -o $TeX_root.idx") >> 8)
+ && &die_gracefully("$Pgm: sorting $TeX_root.idx failed\n");
+ }
+
+}
+
+sub run_bibtex { # ugly because bibtex doesn't return a correct error status
+ local($bibtex_had_errors) = 0;
+
+ print STDERR "$Pgm: *** running BibTeX...\n" if $Verbose;
+ unlink "$TeX_root.bbl";
+
+ $| = 1; # no buffering
+ open(BIBTXPIPE, "bibtex $TeX_root 2>&1 |")
+ || &die_gracefully("$Pgm: Can't run bibtex pipe\n");
+ while (<BIBTXPIPE>) {
+ $bibtex_had_errors = 1 if /^\(There.*error message(s)?\)$/;
+ print STDERR $_;
+ }
+ close(BIBTXPIPE);
+ &die_gracefully("$Pgm: BibTeX run had errors\n")
+ if $? >> 8 || $bibtex_had_errors;
+}
+
+sub something_more_needed {
+ # returns 1 or 0 if we need to run LaTeX
+ # possibly preceded by bibtex and/or makeindex run
+
+ # $Says_labels_changed was set by previous &run_latex...
+ $BibTeX_run_needed = 0;
+ $MakeIndex_run_needed = 0;
+
+ if ( ! -f ($TeX_root . '.aux-prev')) { # this was the first run
+
+ print STDERR "$Pgm: *** 'twas first run of LaTeX on $TeX_input\n" if $Verbose;
+
+ # we need makeindex to run if a non-zero-sized .idx file exists
+ #
+ $MakeIndex_run_needed = 1
+ if -f "$TeX_root.idx" && -s "$TeX_root.idx";
+
+ # we need bibtex to run if there are \citations in the .aux file
+ #
+ &slurp_aux_file('aux');
+ $BibTeX_run_needed = 1
+ if $Bibliography_requested &&
+ -f "$(TMPDIR)/ltx-aux-cite.$$" &&
+ -s "$(TMPDIR)/ltx-aux-cite.$$";
+
+
+ } else { # ltx had been run before (.aux-prev/.idx-prev files exist)
+
+ # slurp both .aux and .aux-prev files
+ &slurp_aux_file('aux');
+ &slurp_aux_file('aux-prev');
+
+ local($tmp_pre) = "$(TMPDIR)/ltx";
+
+ if ((-s "$tmp_pre-.aux-cite.$$") # there are still \cite's in there
+ && (system("cmp -s $tmp_pre-.aux-cite.$$ $tmp_pre-.aux-prev-cite.$$") >> 8)) {
+ $BibTeX_run_needed = 1 if $Bibliography_requested;
+ if ($Verbose) {
+ system("diff -c1 $tmp_pre-.aux-prev-cite.$$ $tmp_pre-.aux-cite.$$");
+ }
+ }
+
+ if (-f "$TeX_root.idx") {
+ $MakeIndex_run_needed =
+ (system("cmp -s $TeX_root.idx $TeX_root.idx-prev") >> 8) ? 1 : 0;
+ if ($MakeIndex_run_needed && $Verbose) {
+ system("diff -c1 $TeX_root.idx-prev $TeX_root.idx");
+ }
+ }
+ }
+
+ $Says_labels_changed || $BibTeX_run_needed || $MakeIndex_run_needed;
+}
+
+sub slurp_aux_file {
+ local($ext) = @_;
+
+ # copy all citations from slurpfile into $(TMPDIR)/ltx-$ext-cite.$$
+
+ open(SLURPF,"< $TeX_root.$ext")
+ || &die_gracefully("$Pgm: Can't open $TeX_root.$ext for reading\n");
+ open(CITEF,"> $(TMPDIR)/ltx-$ext-cite.$$")
+ || &die_gracefully("$Pgm: Can't open $(TMPDIR)/ltx-$ext-cite.$$ for writing\n");
+
+ while (<SLURPF>) {
+ print CITEF $_ if /\\citation/;
+ }
+ close(CITEF);
+ close(SLURPF);
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/m5.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/m5.prl
new file mode 100644
index 0000000000..f352f64e48
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/m5.prl
@@ -0,0 +1,502 @@
+#!/usr/local/bin/perl -- # -*-Perl-*-
+##############################################################################
+#
+# m5 is a poor-man's m4
+#
+# written in March of 1991 by Bill Mann; tested with v3.044 of perl
+# bill@ksr.com (ksr!bill@uunet.uu.net)
+#
+# This program may be used or modified for any purpose, but I would
+# appreciate it if you would reports bugs and fixes to me, and credit
+# yourself with any modifications you make. -bill
+#
+# I have mailed Larry Wall a fix for the 'perl bug' mentioned in the
+# comments below. Once this bug is fixed, removing the 'redundant'
+# double-quotes will provide some improvement in speed; the speed-up
+# will be application dependent. -bill
+#
+##############################################################################
+
+#-- where I got it -----------------------------------------------------------
+#From: Adrian F Clark <alien@sx.ac.uk>
+#To: partain
+#Subject: Re: Macro-processor in Perl?
+#Date: Thu, 25 Jul 91 09:43:05 BST
+#
+#"Ask and ye shall receive" ... this sounds like just what we both
+#want!
+#
+#..a
+#
+#Date: Wed, 24 Jul 91 18:09:30 EDT
+#From: bill%ksr.com@uk.ac.essex.mailhost
+#To: "Adrian F Clark" <alien%sx.ac.uk@uk.ac.essex.mailhost>
+#In-Reply-To: alien@essex.ac.uk's message of 24 Jul 91 09:32:13 EDT
+#Subject: Re: Macro-processor in Perl?
+#Sender: bill%ksr.com%ksr%uunet.uu.net@uk.ac.essex.mailhost
+#
+#I wrote a m4 clone, with just a couple of features missing, and a
+#couple added, because the versions of m4 we had in-house, mostly from
+#SUN, were either very old or buggy.
+#
+#The major missing feature is multiple separate output files. The
+#major addition is that eval() now does a full-fledged perl eval, which
+#'just happens' to include everything the m4 eval includes, in the same
+#syntax.
+#
+#This program is in daily use, and has been tested by the author, but
+#it is only used for a few applications, so problems may still be
+#lurking. I'll be happy to answer a few questions, but can't promise
+#to spend too much time, and I provide no guarantees. I call it m5
+#just keep it distinct from m4.
+#-----------------------------------------------------------------------------
+
+# Auto identification
+#$program_path = $0;
+#$program_name = $program_path;
+#$program_name =~ s:^.*/::;
+#$cmd_line = join(' ', $program_name, @ARGV);
+#$rcs_id = '$Id: m5,v 1.1 1991/03/12 19:48:13 bill Exp $ ';
+select (STDERR); $| = 1; select (STDOUT);
+#print STDERR "$program_path ", '$Revision: 1.1 $ ', "\n";
+#print STDERR $rcs_id, "\n";
+
+
+#eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';"
+# while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV));
+#exit 255 if $die; # process any FOO=bar switches
+
+%D = ("changecom", "\000changecom",
+ "changequote", "\000changequote",
+ "decr", "\000decr",
+ "define", "\000define",
+ "defn", "\000defn",
+ "dnl", "\000dnl",
+ "dumpdef", "\000dumpdef",
+ "errprint", "\000errprint",
+ "eval", "\000eval",
+ "ifdef", "\000ifdef",
+ "ifelse", "\000ifelse",
+ "include", "\000include",
+ "incr", "\000incr",
+ "index", "\000index",
+ "len", "\000len",
+ "maketemp", "\000maketemp",
+ "m4exit", "\000m4exit",
+ "m4wrap", "\000m4wrap",
+ "popdef", "\000popdef",
+ "pushdef", "\000pushdef",
+ "repeat", "\000repeat",
+ "shift", "\000shift",
+ "substr", "\000substr",
+ "syscmd", "\000syscmd",
+ "undefine", "\000undefine",
+ "unix", "",
+ );
+
+$ccp = 0; $file = '';
+@inc = '';
+while ($ARGV[0] =~ /^-./) {
+ $_ = shift(@ARGV);
+ /^-D(\w+)(=(.*))?$/ && ($D{$1} = (defined($3)? $3 : ''), next);
+ /^-U(\w+)$/ && (delete $D{$1}, next);
+ /^-e$/ && (next); # not implemented yet -bill
+ /^-s$/ && ($ccp = 1, next);
+ /^-I(.*)$/ && (push(@inc, ($1 || shift(@ARGV)) . '/'), next);
+ die "unrecognized switch: $_\n";
+}
+
+# other globals: @args, $ab, $mi, $lq, $rq, $skip
+$ab = $mi = 0; # undef would be ok
+$m4wrap = '';
+
+$lcom = "\#";
+$rcom = "\n";
+&changequote;
+
+@ARGV || unshift(@ARGV, '-');
+
+for (shift(@ARGV)) { # 'feature': each file must end cleanly
+ print &expand('', &openf($_));
+}
+$m4wrap ne '' && print &expand($m4wrap, '');
+exit;
+
+sub openf {
+ $ARGV = $_[0];
+ $FH = "F" . @FH;
+ open($FH, $ARGV) || die "Can't open '$ARGV': $@";
+ $line = 0;
+ $ccp && printf ("#line %s \"%s\"\n", 1, $ARGV);
+ $FH;
+}
+
+# $st states:
+# 0: normal text, or reading macro arguments if $pf != 0
+# 1: quoted string
+# 2: comment
+# 3: starting to read an argument (skipping white space)
+
+# expand expands its input string, removing one layer of matching quotes;
+# it expands defined symbols as long as they are not between quotes.
+# whenever it reaches the end of the string it reads a new line and extends
+# its input if possible; if it can't it returns errors if in a macro
+# argument or in a quoted string.
+sub expand {
+ local($in,$FH) = @_;
+ local($i,$st,$qn,$pn) = (0,0,0,0); # used recursively
+ local($ci,$pi,$t); # not used recursively, but declared anyway
+
+ while (1) { # for 'each' character
+ if ($i == length($in)) {
+ if ($FH) {
+ unless ($pn) { # defer output while reading macro arguments
+ print $in;
+ $in = '';
+ $i = $ci = 0;
+ }
+
+ if ($t = <$FH>) {
+ $in .= $t;
+ $line++;
+ next; # process next line
+ }
+
+ close($FH);
+
+ if (@argv) {
+ $FH = pop(@FH);
+ $ARGV = pop(@argv);
+ $line = pop(@line);
+ $in .= pop(@in);
+ $ccp && printf ("#line %s \"%s\"\n", $line, $ARGV);
+ next;
+ }
+ }
+ $st == 1 && die "missing close quote\n";
+ $st == 2 && die "missing close comment\n";
+ $pn && die "missing close parenthesis\n";
+ last;
+ }
+
+## substr($in, $i) =~ $skip && ($i += length($&)) == length($in) && next;
+ substr($in, $i) =~ /^[ \t0-9]+/ &&
+ ($i += length($&)) == length($in) && next;
+
+ if ($st == 1) { # if in a quoted string
+ if (substr($in, $i, length($rq)) eq $rq) {
+ if (--$qn) {
+ $i += length($rq);
+ } else {
+ substr($in, $i, length($rq)) = '';
+ $st = 0;
+ }
+ next;
+ }
+ if (substr($in, $i, length($lq)) eq $lq) {
+ ++$qn;
+ $i += length($lq);
+ next;
+ }
+ ++$i;
+ next;
+ }
+ elsif ($st == 2) { # if in a comment
+ if (($i = index($in, $rcom, $i)) == -1) { # extends past eol
+ $i = length($in);
+ next;
+ }
+
+ $i += length($rcom);
+ if ($pn) { # if in parens
+ substr($in, $ci, $i-$ci) = '';
+ $i = $ci;
+ $rcom eq "\n" && (substr($in, $i++, 0) = "\n");
+ }
+ $st = 0;
+ next;
+ }
+ elsif ($st == 3) { # if starting an argument
+ substr($in, $pi, $i-$pi+1) =~ s/^(\s*)(\S)/$2/ &&
+ ($i -= length($1), $st = 0);
+ }
+
+ if (substr($in, $i, length($lq)) eq $lq && $lq) {
+ substr($in, $i, length($lq)) = '';
+ $st = $qn = 1;
+ next;
+ }
+
+ if (substr($in, $i, length($lcom)) eq $lcom && $lcom) {
+ $i += length($lcom);
+ $ci = $i;
+ $st = 2;
+ next;
+ }
+
+ if ($pn) {
+ $t = substr($in, $i, 1);
+ if ($t eq '(') {
+ ++$pn;
+ ++$i;
+ next;
+ }
+ elsif ($t eq ',') {
+ if ($pn == 1) {
+ push(@args, substr($in, $pi, $i-$pi));
+ $pi = $i+1;
+ $st = 3;
+ }
+ ++$i;
+ next;
+ }
+ elsif ($t eq ')') {
+ if (--$pn == 0) {
+ push(@args, substr($in, $pi, $i-$pi));
+ ++$i;
+ &callm;
+ $pi = pop(@pi);
+ $pn = pop(@pn);
+ next;
+ }
+ ++$i;
+ next;
+ }
+ }
+
+ substr($in, $i) =~ /^([a-z_]\w*)(\()?/i || (++$i, next);
+ defined($D{$1}) || ($i += length($1), next);
+
+ push(@ab, $ab);
+ push(@args, $1);
+ $ab = $#args;
+ push(@mi, $mi);
+ $mi = $i;
+ $i += length($&);
+
+ if ($2) {
+ push(@pi, $pi);
+ push(@pn, $pn);
+ $pi = $i;
+ $pn = 1;
+ $st = 3;
+ next;
+ }
+
+ &callm;
+ }
+ $in;
+}
+
+sub callm {
+
+ if (($t = $D{$args[$ab]}) =~ s/^\000//) {
+ $t = &$t; # may recurse here
+ } else {
+ $t =~ s/\$(\#|\*|\@|\d)/$1 eq '#' ? $#args-$ab :
+ $1 eq '*' ? join(',', @args[$ab+1..$#args]) :
+ $1 eq '@' ? join(',', &quotelist(@args[$ab+1..$#args])) :
+ $args[$ab+$1]/ge;
+ }
+
+ $ccp &&
+ (substr($in, $mi, $i-$mi) =~ tr/\n/\n/) != ($t =~ tr/\n/\n/) &&
+ ($t =~ s/\n$//,
+ $t .= sprintf("\n#line %s \"%s\"\n", $line, $ARGV));
+ substr($in, $mi, $i-$mi) = $t;
+
+ $i = $mi; # rescan
+ $#args = $ab-1;
+ $mi = pop(@mi);
+ $ab = pop(@ab);
+}
+
+sub quotelist {
+ local(@T);
+ for (@_) {
+ push(@T, $lq . $_ . $rq);
+ }
+ @T;
+}
+
+sub setskip {
+ ($skip = "$lcom$rcom$lq$rq(,)") =~ s/(\W)/\\$1/g;
+ $skip = "^[^a-zA-Z_$skip]+";
+}
+
+# m5 functions:
+
+sub changecom {
+ $lcom = $args[$ab+1];
+ $rcom = $args[$ab+2] || "\n";
+ &setskip;
+ "";
+}
+
+sub changequote {
+ $lq = $args[$ab+1];
+ $rq = $args[$ab+2] || $lq;
+ if ($#args <= $ab) { # if no arguments at all
+ $lq = "\`";
+ $rq = "\'";
+ }
+ &setskip;
+ "";
+}
+
+sub decr {
+ $t = $args[$ab+1] - 1;
+ "$t"; # quotes required for perl bug
+}
+
+sub define {
+ $args[$ab+1] =~ /^[a-z_]\w*$/i || die "bad macro name: '$args[$ab+1]'\n";
+ $D{$args[$ab+1]} = $args[$ab+2];
+ "";
+}
+
+sub defn {
+ $t = '';
+ for (@args[$ab+1..$#args]) {
+ $t .= $lq . $D{$_} . $rq;
+ }
+ $t;
+}
+
+sub dnl {
+ substr($in, $i) =~ s/[^\n]*\n?//;
+ "";
+}
+
+sub dumpdef {
+ for (sort(keys %D)) {
+ if (($t = $D{$_}) =~ s/^\000//) {
+ printf STDERR ("%s:\t<%s>\n", $_, $t);
+ } else {
+ printf STDERR ("%s:\t%s%s%s\n", $_, $lq, $t, $rq);
+ }
+ }
+ "";
+}
+
+sub errprint {
+ print STDERR $args[$ab+1], "\n";
+ "";
+}
+
+sub eval {
+ local($r) = int($args[$ab+2]);
+ package m5;
+ $main't = eval $main'args[$main'ab+1]; #'];
+ package main;
+ $@ && die "eval($args[$ab+1]) failed: $@\n";
+ if ($r > 1 && $t =~ s/^(-)?(\d+)$//) { # if a radix is specified
+ local($d) = $2;
+ do {
+ $t = ('0'..'9','A'..'Z')[$d % $r] . $t;
+ $d = int($d / $r);
+ } while $d;
+
+ $d = $args[$ab+3] - length($t);
+ $d > 0 && ($t = ('0' x $d) . $t);
+ $t = $1 . $t;
+ }
+ "$t"; # quotes required for perl bug
+}
+
+sub ifdef {
+ defined($D{$args[$ab+1]}) ? $args[$ab+2] : $args[$ab+3];
+}
+
+sub ifelse {
+ for ($t = $ab+1; $t < $#args; $t += 3) {
+ $args[$t] eq $args[$t+1] && return "$args[$t+2]";
+ }
+ return "$args[$t]"; # quotes required for perl bug
+}
+
+sub include {
+ for (@inc) { # search -I list
+ $t = "$_$args[$ab+1]";
+ if (-f $t) {
+ push(@FH, $FH);
+ push(@argv, $ARGV);
+ push(@line, $line);
+ push(@in, substr($in, $i));
+ substr($in, $i) = '';
+ &openf($t);
+ return "";
+ }
+ }
+ die "Can't find include file $args[$ab+1]";
+}
+
+sub incr {
+ $t = $args[$ab+1] + 1;
+ "$t"; # quotes required for perl bug
+}
+
+sub index {
+ $t = index($args[$ab+1], $args[$ab+2]);
+ "$t"; # quotes required for perl bug
+}
+
+sub len {
+ $t = length($args[$ab+1]);
+ "$t"; # quotes required for perl bug
+}
+
+sub maketemp {
+ ($t = $args[$ab+1]) =~ s/X{1,6}$/a$$/; # via experiments
+ "$t"; # quotes required for perl bug
+}
+
+sub m4exit {
+ exit($args[$ab+1]);
+}
+
+sub m4wrap {
+ $m4wrap = $args[$ab+1];
+ "";
+}
+
+sub popdef {
+ eval "\$D{$args[$ab+1]} = pop(@M5'$args[$ab+1])";
+ "";
+}
+
+sub pushdef {
+ eval "push(@M5'$args[$ab+1], \$D{$args[$ab+1]})";
+ $D{$args[$ab+1]} = $args[$ab+2];
+ "";
+}
+
+sub repeat { # repeat(#, expr); evals expr # times; $0 = 0..#-1
+ local($t);
+ for ($args[$ab] = 0; $args[$ab] < $args[$ab+1]; $args[$ab]++) {
+ $t .= &expand($args[$ab+2], '');
+ }
+ $t;
+}
+
+sub shift {
+ join(',', &quotelist(@args[$ab+2..$#args]));
+}
+
+sub substr {
+ $t = substr($args[$ab+1], $args[$ab+2], $args[$ab+3] || 1000000000);
+ "$t"; # quotes required for perl bug
+}
+
+sub syscmd {
+ $m5'sysval = system($args[$ab+1]); #' this is wrong, but close
+ "";
+}
+
+sub undefine {
+ delete $D{$args[$ab+1]};
+ "";
+}
+
+- ---------------------- end ----------------------
+
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdependC.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdependC.prl
new file mode 100644
index 0000000000..edffc6b7ba
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdependC.prl
@@ -0,0 +1,186 @@
+# *** MSUB does some substitutions here ***
+# *** grep for $( ***
+#
+# tries to work like mkdependC
+#
+# ToDo: strip out all the .h junk
+#
+($Pgm = $0) =~ s/.*\/([^\/]+)$/\1/;
+$Usage = "usage: $Pgm: not done yet\n";
+
+$Status = 0; # just used for exit() status
+$Verbose = '';
+$Dashdashes_seen = 0;
+
+$Begin_magic_str = "# DO NOT DELETE: Beginning of C dependencies\n";
+$End_magic_str = "# DO NOT DELETE: End of C dependencies\n";
+$Obj_suffix = '.o';
+@Defines = ();
+$Include_dirs = '';
+$Col_width = 78; # ignored
+$Makefile = '';
+@Src_files = ();
+
+&mangle_command_line_args();
+
+if ( ! $Makefile && -f 'makefile' ) {
+ $Makefile = 'makefile';
+} elsif ( ! $Makefile && -f 'Makefile') {
+ $Makefile = 'Makefile';
+} else {
+ die "$Pgm: no makefile or Makefile found\n";
+}
+
+@Depend_lines = ();
+%Depend_seen = ();
+
+print STDERR "CPP defines=@Defines\n" if $Verbose;
+print STDERR "Include_dirs=$Include_dirs\n" if $Verbose;
+
+foreach $sf (@Src_files) {
+ # just like lit-inputter
+ # except it puts each file through CPP and
+ # a de-commenter (not implemented);
+ # builds up @Depend_lines
+ print STDERR "Here we go for source file: $sf\n" if $Verbose;
+ ($of = $sf) =~ s/\.(c|hc)$/$Obj_suffix/;
+
+ &slurp_file($sf, 'fh00');
+}
+
+# OK, mangle the Makefile
+unlink("$Makefile.bak");
+rename($Makefile,"$Makefile.bak");
+# now copy Makefile.bak into Makefile, rm'ing old dependencies
+# and adding the new
+open(OMKF,"< $Makefile.bak") || die "$Pgm: can't open $Makefile.bak: $!\n";
+open(NMKF,"> $Makefile") || die "$Pgm: can't open $Makefile: $!\n";
+select(NMKF);
+$_ = <OMKF>;
+while ($_ && $_ ne $Begin_magic_str) { # copy through, 'til Begin_magic_str
+ print $_;
+ $_ = <OMKF>;
+}
+while ($_ && $_ ne $End_magic_str) { # delete 'til End_magic_str
+ $_ = <OMKF>;
+}
+# insert dependencies
+print $Begin_magic_str;
+print @Depend_lines;
+print $End_magic_str;
+while (<OMKF>) { # copy the rest through
+ print $_;
+}
+close(NMKF);
+close(OMKF);
+chmod 0444, 'Makefile';
+exit 0;
+
+sub mangle_command_line_args {
+ while($_ = $ARGV[0]) {
+ shift(@ARGV);
+
+ if ( /^--$/ ) {
+ $Dashdashes_seen++;
+
+ } elsif ( /^-D(.*)/ ) { # recognized wherever they occur
+ push(@Defines, $_);
+ } elsif ( /^-I/ ) {
+ $Include_dirs .= " $_";
+
+ } elsif ($Dashdashes_seen != 1) { # not between -- ... --
+ if ( /^-v$/ ) {
+ $Verbose = '-v';
+ } elsif ( /^-f/ ) {
+ $Makefile = &grab_arg_arg($_);
+ } elsif ( /^-o/ ) {
+ $Obj_suffix = &grab_arg_arg($_);
+ } elsif ( /^-bs/ ) {
+ $Begin_magic_str = &grab_arg_arg($_) . "\n";
+ } elsif ( /^-es/ ) {
+ $End_magic_str = &grab_arg_arg($_) . "\n";
+ } elsif ( /^-w/ ) {
+ $Width = &grab_arg_arg($_);
+ } elsif ( /^-/ ) {
+ print STDERR "$Pgm: unknown option ignored: $_\n";
+ } else {
+ push(@Src_files, $_);
+ }
+
+ } elsif ($Dashdashes_seen == 1) { # where we ignore unknown options
+ push(@Src_files,$_) if ! /^-/;
+ }
+ }
+}
+
+sub grab_arg_arg {
+ local($option) = @_;
+ local($rest_of_arg);
+
+ ($rest_of_arg = $option) =~ s/^-.//;
+
+ if ($rest_of_arg) {
+ return($rest_of_arg);
+ } elsif ($#ARGV >= 0) {
+ local($temp) = $ARGV[0]; shift(@ARGV);
+ return($temp);
+ } else {
+ die "$Pgm: no argument following $option option\n";
+ }
+}
+
+sub slurp_file { # follows an example in the `open' item in perl man page
+ local($fname,$fhandle) = @_;
+ local($depend); # tmp
+ $fhandle++; # a string increment
+
+ $fname = &tidy_dir_names($fname);
+
+ unless (open($fhandle, "$(CPP) $Include_dirs @Defines $fname |")) {
+ die "$Pgm: Can't open $fname: $!\n";
+ }
+ line: while (<$fhandle>) {
+ next line if ! /^#/;
+ next line if /^#(ident|pragma)/;
+ chop; # rm trailing newline
+
+ $_ = &tidy_dir_names($_);
+
+ # strip junk off the front and back
+ $_ =~ s/^#\s+\d+\s+//;
+ $_ =~ s/[ 0-9]*$//;
+
+ # a little bit of ad-hoc fiddling now:
+ # don't bother w/ dependencies on /usr/include stuff
+ # don't bother if it looks like a GCC built-in hdr file
+ # don't bother with "literate" .h files (.lh); we'll just
+ # depend on the de-litified versions (which have better info)
+ # don't let a file depend on itself
+ next line if /^\/usr\/include/;
+ next line if /\/gcc-lib\/[^\/\n]+\/[\.0-9]+\/include\//;
+ next line if /\.lh$/;
+ next line if $_ eq $fname;
+
+ print STDERR "$fname :: $_\n" if $Verbose;
+
+ # ToDo: some sanity checks that we still have something reasonable?
+
+ $depend = "$of : $_\n";
+ next line if $Depend_seen{$depend}; # already seen this one...
+
+ # OK, it's a new one.
+ push (@Depend_lines, $depend);
+ $Depend_seen{$depend} = 1;
+ }
+ close($fhandle);
+}
+
+sub tidy_dir_names { # rm various pernicious dir-name combinations...
+ local($str) = @_;
+
+ $str =~ s|/[^/.][^/]*/\.\.||g; # nuke: /<dir>/..
+ $str =~ s|/\.[^.][^/]*/\.\.||g; # nuke: /./.. (and others)
+ $str =~ s|"||g;
+ $str =~ s| \./| |;
+ $str;
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.man b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.man
new file mode 100644
index 0000000000..999fa12822
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.man
@@ -0,0 +1,15 @@
+.TH MKDIRHIER 1 "Release 4" "X Version 11"
+.SH NAME
+mkdirhier \- makes a directory hierarchy
+.SH SYNOPSIS
+.B mkdirhier
+directory ...
+.SH DESCRIPTION
+The
+.I mkdirhier
+command creates the specified directories. Unlike
+.I mkdir
+if any of the parent directories of the specified directory
+do not exist, it creates them as well.
+.SH "SEE ALSO"
+mkdir(1)
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.sh b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.sh
new file mode 100644
index 0000000000..739535e118
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkdirhier.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+#
+# create a heirarchy of directories
+#
+
+for f in $*; do
+ parts=`echo $f | sed 's,\(.\)/\(.\),\1 \2,g' | sed 's,/$,,'`;
+ path="";
+ for p in $parts; do
+ if [ x"$path" = x ]; then
+ dir=$p;
+ else
+ dir=$path/$p;
+ fi;
+ if [ ! -d $dir ]; then
+ echo mkdir $dir;
+ mkdir $dir;
+ chmod a+rx $dir;
+ fi;
+ path=$dir;
+ done;
+done
+
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkshadowfile.sh b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkshadowfile.sh
new file mode 100644
index 0000000000..a00ede08e0
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/mkshadowfile.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+#
+# create a heirarchy of directories (mkdir that makes everything)
+#
+
+USAGE="Usage: $0 master-src-dir-root shadow-src-dir-root filename-from-master-root"
+
+for f in $*; do
+ parts=`echo $f | sed 's,\(.\)/\(.\),\1 \2,g' | sed 's,/$,,'`;
+ path="";
+ for p in $parts; do
+ if [ x"$path" = x ]; then
+ dir=$p;
+ else
+ dir=$path/$p;
+ fi;
+ if [ ! -d $dir ]; then
+ echo mkdir $dir;
+ mkdir $dir;
+ chmod a+rx $dir;
+ fi;
+ path=$dir;
+ done;
+done
+exit 0
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/moan-if-old.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/moan-if-old.prl
new file mode 100644
index 0000000000..9b7c0b98bc
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/moan-if-old.prl
@@ -0,0 +1,49 @@
+# "moan" if files in this directory tree appear to be out-of-date
+# with respect to a given "master directory".
+#
+# a utility to use with link trees!
+#
+# usage:
+# % moan-if-old /src/ghc-master-copy
+
+$Verbose = 1;
+$Usage = "usage: moan-if-old master-dir\n";
+
+if ($#ARGV != 0) {
+ die $Usage;
+} else {
+ $Master_dir = $ARGV[0];
+ die "no such dir: $Master_dir\n$Usage" if ! -d $Master_dir;
+}
+
+open(F,"find . -type f -print |") || die "Cannot open find ($!)";
+while (<F>) {
+ chop;
+
+ if (! -f "$Master_dir/$_" && ! &junk_file($_) ) {
+ print STDERR "$_ : not in master directory\n";
+
+ } elsif (-f "$Master_dir/$_") {
+
+ $f1 = "$Master_dir/$_";
+ $f2 = $_;
+
+ @m_dope = stat($f1);
+ @s_dope = stat($f2);
+ if ($m_dope[9] > $s_dope[9]) { # those are modification times...
+ print STDERR "$f1 ($m_dope[9]) > $f2 ($s_dope[9])\n" if $Verbose;
+ print STDERR "$_ : older\n";
+ }
+ }
+}
+close(F);
+
+sub junk_file {
+ local($_) = @_;
+
+ if ( /~$/ || /\.bak$/ || /-(PREV|OLD|SAVE|NEW)$/ ) {
+ return(1);
+ } else {
+ return(0);
+ }
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/perltags.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/perltags.prl
new file mode 100644
index 0000000000..d7bf6129cb
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/perltags.prl
@@ -0,0 +1,69 @@
+# perl tags, in perl.
+# @(#)ptags 1.2 4/11/91, no copyright. Bugfixes to lm@eng.sun.com.
+
+#In the hack-of-the-hour catagory, a tags file generator for perl. Differences
+#from ctags:
+#
+# 1) Puts a tag in for the filename
+# 2) Puts in multiple tags for the same symbol (I have a hacked version
+# of vi that groks this).
+
+# tag file <vi expresion to find it>
+# catch /u/lm/tmp/eintr.c /^catch() {}$/
+
+if ($#ARGV == -1) {
+ unshift(@ARGV, "-");
+}
+open(STDOUT, ">> TAGS") || die "can't create TAGS"; # partain: NB: APPEND
+while ($_ = shift) {
+ next unless -f $_;
+ print STDERR "$_\n" if $v;
+ do file($_);
+}
+exit;
+
+sub file
+{
+ local($name) = $_[0];
+
+ open(F, $name) || return;
+ $entries = '';
+ $lcnt = 1;
+ $ccnt = 0;
+
+ while (<F>) {
+ # skip the word sub in comments
+ next unless /^[^#]*\bsub\b/;
+ # skip the word sub in a string (one line only, I'm lazy)
+ next if /"[^"]*sub/;
+# print "$name: $. $_" if $d;
+ # demand that "sub" is first on the line (partain)
+ # (the initial > is for some literate perl scripts...)
+ next if ! /^>?\s*sub\s+/;
+ chop;
+ # rm comments
+ s/#.*$//;
+ # and here's the entry...
+ $entries .= "$_\x7f$lcnt,$ccnt\n";
+ $lcnt++;
+ $ccnt += length($_);
+ }
+ # print tag for filename
+ print "\f\n$name,",length($entries),"\n";
+ print $entries;
+}
+
+###I've always used this. Don't recall whom I got it from...
+##
+##--tom
+##
+###!/usr/local/bin/perl
+#open(OUTPUT, "| sort >> TAGS");
+#while (<>) {
+# if (/\bsub\s+(\w+')?(\S+)/) {
+# $func = $2;
+# chop;
+# s,[\\\[\]/.*],\\$&,g;
+# print OUTPUT "$func\t", $ARGV, "\t/^$_\$/\n";
+# }
+#}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/runstdtest.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/runstdtest.prl
new file mode 100644
index 0000000000..48e6cc28a8
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/runstdtest.prl
@@ -0,0 +1,184 @@
+#! /usr/local/bin/perl
+#
+# Given:
+# * a program to run (1st arg)
+# * some "command-line opts" ( -O<opt1> -O<opt2> ... )
+# [default: anything on the cmd line this script doesn't recognise ]
+# the first opt not starting w/ "-" is taken to be an input
+# file and (if it exists) is grepped for "what's going on here"
+# comments (^--!!!).
+# * a file to feed to stdin ( -i<file> ) [default: /dev/null ]
+# * a "time" command to use (-t <cmd>).
+#
+# * alternatively, a "-script <script>" argument says: run the
+# named Bourne-shell script to do the test. It's passed the
+# pgm-to-run as the one-and-only arg.
+#
+# Run the program with those options and that input, and check:
+# if we get...
+#
+# * an expected exit status ( -x <val> ) [ default 0 ]
+# * expected output on stdout ( -o1 <file> ) [ default /dev/null ]
+# * expected output on stderr ( -o2 <file> ) [ default /dev/null ]
+#
+# (if the expected-output files' names end in .Z, then
+# they are uncompressed before doing the comparison)
+#
+# (This is supposed to be a "prettier" replacement for runstdtest.)
+#
+($Pgm = $0) =~ s|.*/||;
+$Verbose = 0;
+$Status = 0;
+@PgmArgs = ();
+$PgmExitStatus = 0;
+$PgmStdinFile = '/dev/null';
+$PgmStdoutFile = '/dev/null';
+$PgmStderrFile = '/dev/null';
+$AltScript = '';
+$TimeCmd = '';
+
+die "$Pgm: program to run not given as first argument\n" if $#ARGV < 0;
+$ToRun = $ARGV[0]; shift(@ARGV);
+# avoid picking up same-named thing from somewhere else on $PATH...
+$ToRun = "./$ToRun" if $ToRun !~ /^\//;
+
+arg: while ($_ = $ARGV[0]) {
+ shift(@ARGV);
+
+ /^-v$/ && do { $Verbose = 1; next arg; };
+ /^-O(.*)/ && do { push(@PgmArgs, &grab_arg_arg('-O',$1)); next arg; };
+ /^-i(.*)/ && do { $PgmStdinFile = &grab_arg_arg('-i',$1);
+ $Status++,
+ print STDERR "$Pgm: bogus -i input file: $PgmStdinFile\n"
+ if ! -f $PgmStdinFile;
+ next arg; };
+ /^-x(.*)/ && do { $PgmExitStatus = &grab_arg_arg('-x',$1);
+ $Status++ ,
+ print STDERR "$Pgm: bogus -x expected exit status: $PgmExitStatus\n"
+ if $PgmExitStatus !~ /^\d+$/;
+ next arg; };
+ /^-o1(.*)/ && do { $PgmStdoutFile = &grab_arg_arg('-o1',$1);
+ $Status++ ,
+ print STDERR "$Pgm: bogus -o1 expected-output file: $PgmStdoutFile\n"
+ if ! -f $PgmStdoutFile;
+ next arg; };
+ /^-o2(.*)/ && do { $PgmStderrFile = &grab_arg_arg('-o2',$1);
+ $Status++,
+ print STDERR "$Pgm: bogus -o2 expected-stderr file: $PgmStderrFile\n"
+ if ! -f $PgmStderrFile;
+ next arg; };
+ /^-script(.*)/ && do { $AltScript = &grab_arg_arg('-script',$1);
+ next arg; };
+ /^-t(.*)/ && do { $TimeCmd = &grab_arg_arg('-t', $1); next arg; };
+
+ # anything else is taken to be a pgm arg
+ push(@PgmArgs, $_);
+}
+exit 1 if $Status;
+
+# tidy up the pgm args:
+# (1) look for the "first input file"
+# and grep it for "interesting" comments (--!!! )
+# (2) quote any args w/ whitespace in them.
+$grep_done = 0;
+foreach $a ( @PgmArgs ) {
+ if (! $grep_done && $a !~ /^-/ && -f $a) {
+ print `egrep "^--!!!" $a`;
+ $grep_done = 1;
+ }
+ if ($a =~ /\s/ || $a =~ /'/) {
+ $a =~ s/'/\\'/g; # backslash the quotes;
+ $a = "\"$a\""; # quote the arg
+ }
+}
+
+if ($AltScript ne '') {
+ local($to_do);
+ $to_do = `cat $AltScript`;
+ # glue in pgm to run...
+ $* = 1;
+ $to_do =~ s/^\$1 /$ToRun /;
+ &run_something($to_do);
+ exit 0;
+# exec "$AltScript $ToRun";
+# print STDERR "Failed to exec!!! $AltScript $ToRun\n";
+# exit 1;
+}
+
+# OK, so we're gonna do the normal thing...
+
+$Script = <<EOSCRIPT;
+#! /bin/sh
+myexit=0
+diffsShown=0
+$TimeCmd /bin/sh -c \'$ToRun @PgmArgs < $PgmStdinFile 1> $(TMPDIR)/runtest$$.1 2> $(TMPDIR)/runtest$$.2\'
+progexit=\$?
+if [ \$progexit -ne $PgmExitStatus ]; then
+ echo $ToRun @PgmArgs \\< $PgmStdinFile
+ echo expected exit status $PgmExitStatus not seen \\; got \$progexit
+ myexit=1
+else
+ if cmp -s $PgmStdoutFile $(TMPDIR)/runtest$$.1 ; then
+ echo -n "" # no-op
+ else
+ echo $ToRun @PgmArgs \\< $PgmStdinFile
+ echo expected stdout not matched by reality
+ diff -c1 $PgmStdoutFile $(TMPDIR)/runtest$$.1
+ myexit=1
+ diffsShown=1
+ fi
+fi
+if cmp -s $PgmStderrFile $(TMPDIR)/runtest$$.2 ; then
+ echo -n "" # no-op
+else
+ echo $ToRun @PgmArgs \\< $PgmStdinFile
+ echo expected stderr not matched by reality
+ diff -c1 $PgmStderrFile $(TMPDIR)/runtest$$.2
+ myexit=1
+ diffsShown=1
+fi
+$(RM) core $(TMPDIR)/runtest$$.1 $(TMPDIR)/runtest$$.2
+exit \$myexit
+EOSCRIPT
+
+&run_something($Script);
+# print $Script if $Verbose;
+# open(SH, "| /bin/sh") || die "Can't open shell pipe\n";
+# print SH $Script;
+# close(SH);
+
+exit 0;
+
+sub grab_arg_arg {
+ local($option, $rest_of_arg) = @_;
+
+ if ($rest_of_arg) {
+ return($rest_of_arg);
+ } elsif ($#ARGV >= 0) {
+ local($temp) = $ARGV[0]; shift(@ARGV);
+ return($temp);
+ } else {
+ print STDERR "$Pgm: no argument following $option option\n";
+ $Status++;
+ }
+}
+
+sub run_something {
+ local($str_to_do) = @_;
+
+ print STDERR "$str_to_do\n" if $Verbose;
+
+ local($return_val) = 0;
+ system($str_to_do);
+ $return_val = $?;
+
+ if ($return_val != 0) {
+#ToDo: this return-value mangling is wrong
+# local($die_msg) = "$Pgm: execution of the $tidy_name had trouble";
+# $die_msg .= " (program not found)" if $return_val == 255;
+# $die_msg .= " ($!)" if $Verbose && $! != 0;
+# $die_msg .= "\n";
+
+ exit (($return_val == 0) ? 0 : 1);
+ }
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/scripts/zap-if-same.prl b/web/glasgow/lit2x-0.16/grasp-utils/scripts/zap-if-same.prl
new file mode 100644
index 0000000000..1bdb69ca99
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/scripts/zap-if-same.prl
@@ -0,0 +1,50 @@
+# "zap" files in a directory tree if they're the same as somewhere else
+#
+# zap normally means "rm", but "-s" means to put a symlink in place instead.
+#
+# usage:
+# # delete all files in this dir that are same as in master copy...
+# % zap-if-same /src/ghc-master-copy
+# # use lndir to put in mere links...
+# % lndir /src/ghc-master-copy
+#
+# a similar effect can be had with just...
+# % zap-if-same -s /src/ghc-master-copy
+
+$Usage = "usage: zap-if-same [-s] master-dir\n";
+
+$Action = 'rm';
+
+if ($#ARGV >= 0 && $ARGV[0] eq '-s') {
+ $Action = 'link';
+ shift;
+}
+
+if ($#ARGV != 0) {
+ die $Usage;
+} else {
+ $Master_dir = $ARGV[0];
+ die "no such dir: $Master_dir\n$Usage" if ! -d $Master_dir;
+}
+
+open(F,"find . -type f -print |") || die "Cannot open find ($!)";
+while (<F>) {
+ chop;
+
+ if ( -f "$Master_dir/$_" && &same_contents($_) ) { # ToDo: & not same file?
+ print STDERR "$_ ...\n";
+ unlink $_;
+ if ($Action eq 'link') {
+ symlink("$Master_dir/$_", $_);
+ }
+ }
+}
+close(F);
+
+sub same_contents {
+ local($f) = @_;
+
+ local($return_val) = 0;
+ $return_val = system("cmp -s $Master_dir/$f $f") >> 8;
+ ($return_val == 0) ? 1 : 0;
+}
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/verbatim/Jmakefile b/web/glasgow/lit2x-0.16/grasp-utils/verbatim/Jmakefile
new file mode 100644
index 0000000000..3a2b000b98
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/verbatim/Jmakefile
@@ -0,0 +1,4 @@
+BuildPgmFromCFiles(verbatim,verbatim.o,-ll,)
+InstallBinaryTarget(verbatim,$(INSTBINDIR))
+
+CDependTarget( $(SRCS_C) )
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.c b/web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.c
new file mode 100644
index 0000000000..9d82abe2d9
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.c
@@ -0,0 +1,533 @@
+# include "stdio.h"
+# define U(x) x
+# define NLSTATE yyprevious=YYNEWLINE
+# define BEGIN yybgin = yysvec + 1 +
+# define INITIAL 0
+# define YYLERR yysvec
+# define YYSTATE (yyestate-yysvec-1)
+# define YYOPTIM 1
+# define YYLMAX BUFSIZ
+# define output(c) putc(c,yyout)
+# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
+# define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;}
+# define yymore() (yymorfg=1)
+# define ECHO fprintf(yyout, "%s",yytext)
+# define REJECT { nstr = yyreject(); goto yyfussy;}
+int yyleng; extern char yytext[];
+int yymorfg;
+extern char *yysptr, yysbuf[];
+int yytchar;
+FILE *yyin = {stdin}, *yyout = {stdout};
+extern int yylineno;
+struct yysvf {
+ struct yywork *yystoff;
+ struct yysvf *yyother;
+ int *yystops;};
+struct yysvf *yyestate;
+extern struct yysvf yysvec[], *yybgin;
+ /* This Lex script acts as a filter to pre-process Latex files.
+ It surrounds groups of lines beginning with a ">" sign, and
+ preceded and followed by a blank line, with \begin{verbatim}
+ and \end{verbatim}. The ">" may be preceded by a digit or digit
+ range (eg 4>, 2-5>, 3->); in this case the digits are removed.
+ They are meant to be used for filtering out versions.
+ It takes words surrounded with @ signs (thus @letrec@) and makes them
+ come out in typewriter font, regardless of the current mode.
+ */
+# define NORM 2
+# define VERB 4
+# define MIRANDA 6
+# define VERBATIM 8
+# define VERBATIMSIM 10
+#define PUSH states[top++] =
+#define POP BEGIN states[--top]
+# define YYNEWLINE 10
+yylex(){
+int nstr; extern int yyprevious;
+ int states[256];
+ int top;
+ BEGIN NORM;
+ top = 0;
+while((nstr = yylook()) >= 0)
+yyfussy: switch(nstr){
+case 0:
+if(yywrap()) return(0); break;
+case 1:
+ { printf ("@"); }
+break;
+case 2:
+ { printf ("\\mbox{\\tt "); PUSH NORM; BEGIN VERB; }
+break;
+case 3:
+ { printf ("}"); POP; }
+break;
+case 4:
+ { printf ("}\\\\{}\n\\mbox{\\tt "); }
+break;
+case 5:
+ { printf ("\\ "); }
+break;
+case 6:
+ { printf ("@"); }
+break;
+case 7:
+ { printf ("{\\char'43}"); }
+break;
+case 8:
+ { printf ("{\\char'44}"); }
+break;
+case 9:
+ { printf ("{\\char'45}"); }
+break;
+case 10:
+ { printf ("{\\char'46}"); }
+break;
+case 11:
+ { printf ("{\\char'176}"); }
+break;
+case 12:
+ { printf ("{\\char'137}"); }
+break;
+case 13:
+ { printf ("{\\char'136}"); }
+break;
+case 14:
+ { printf ("{\\char'134}"); }
+break;
+case 15:
+ { printf ("{\\char'173}"); }
+break;
+case 16:
+ { printf ("{\\char'175}"); }
+break;
+case 17:
+ { printf( "\\begin{verbatim}\n" );
+ PUSH NORM; BEGIN VERBATIMSIM; }
+break;
+case 18:
+{ printf( "\\end{verbatim}\n" ); POP; }
+break;
+case 19:
+{ printf( "\\begin{verbatim}" );
+ PUSH NORM; BEGIN VERBATIM; }
+break;
+case 20:
+{ printf( "\\end{verbatim}" ); POP; }
+break;
+case 21:
+{ printf ("\\begin{verbatim}\n>" );
+ PUSH NORM; BEGIN MIRANDA; }
+break;
+case 22:
+{ printf( "\n>" ); }
+break;
+case 23:
+ { printf ("\\end{verbatim}\n"); POP; }
+break;
+case -1:
+break;
+default:
+fprintf(yyout,"bad switch yylook %d",nstr);
+} return(0); }
+/* end of yylex */
+int yyvstop[] = {
+0,
+
+2,
+0,
+
+2,
+0,
+
+4,
+0,
+
+5,
+0,
+
+7,
+0,
+
+8,
+0,
+
+9,
+0,
+
+10,
+0,
+
+3,
+0,
+
+14,
+0,
+
+13,
+0,
+
+12,
+0,
+
+15,
+0,
+
+16,
+0,
+
+11,
+0,
+
+23,
+0,
+
+1,
+0,
+
+21,
+0,
+
+17,
+0,
+
+6,
+0,
+
+22,
+0,
+
+18,
+0,
+
+20,
+0,
+
+19,
+0,
+0};
+# define YYTYPE char
+struct yywork { YYTYPE verify, advance; } yycrank[] = {
+0,0, 0,0, 0,0, 0,0,
+0,0, 0,0, 0,0, 0,0,
+0,0, 0,0, 0,0, 0,0,
+4,15, 5,17, 7,30, 8,31,
+33,43, 0,0, 0,0, 0,0,
+0,0, 0,0, 0,0, 0,0,
+0,0, 0,0, 16,38, 0,0,
+0,0, 0,0, 0,0, 0,0,
+0,0, 0,0, 0,0, 5,18,
+0,0, 0,0, 5,19, 5,20,
+5,21, 5,22, 0,0, 0,0,
+0,0, 0,0, 0,0, 0,0,
+36,45, 40,46, 0,0, 45,45,
+45,45, 45,45, 45,45, 45,45,
+45,45, 45,45, 45,45, 45,45,
+45,45, 0,0, 0,0, 0,0,
+0,0, 3,13, 4,16, 5,23,
+12,33, 13,34, 15,36, 15,36,
+15,36, 15,36, 15,36, 15,36,
+15,36, 15,36, 15,36, 15,36,
+16,34, 23,39, 0,0, 0,0,
+15,37, 0,0, 0,0, 0,0,
+0,0, 0,0, 0,0, 0,0,
+0,0, 3,14, 4,14, 5,24,
+9,32, 5,25, 5,26, 0,0,
+0,0, 14,35, 30,40, 30,40,
+30,40, 30,40, 30,40, 30,40,
+30,40, 30,40, 30,40, 30,40,
+32,42, 35,44, 42,47, 44,48,
+30,41, 47,49, 48,50, 53,55,
+56,58, 57,59, 59,61, 60,62,
+50,52, 62,64, 5,27, 63,65,
+5,28, 5,29, 46,46, 46,46,
+46,46, 46,46, 46,46, 46,46,
+46,46, 46,46, 46,46, 46,46,
+49,51, 51,53, 52,54, 54,56,
+55,57, 58,60, 61,63, 64,66,
+65,67, 66,68, 67,69, 68,70,
+70,71, 0,0, 0,0, 0,0,
+0,0};
+struct yysvf yysvec[] = {
+0, 0, 0,
+yycrank+0, 0, 0,
+yycrank+0, 0, 0,
+yycrank+1, 0, 0,
+yycrank+2, 0, 0,
+yycrank+3, 0, 0,
+yycrank+0, yysvec+5, 0,
+yycrank+4, 0, 0,
+yycrank+5, 0, 0,
+yycrank+4, 0, 0,
+yycrank+0, yysvec+9, 0,
+yycrank+0, 0, 0,
+yycrank+4, 0, 0,
+yycrank+5, 0, yyvstop+1,
+yycrank+3, 0, 0,
+yycrank+22, 0, 0,
+yycrank+16, 0, yyvstop+3,
+yycrank+0, 0, yyvstop+5,
+yycrank+0, 0, yyvstop+7,
+yycrank+0, 0, yyvstop+9,
+yycrank+0, 0, yyvstop+11,
+yycrank+0, 0, yyvstop+13,
+yycrank+0, 0, yyvstop+15,
+yycrank+17, 0, yyvstop+17,
+yycrank+0, 0, yyvstop+19,
+yycrank+0, 0, yyvstop+21,
+yycrank+0, 0, yyvstop+23,
+yycrank+0, 0, yyvstop+25,
+yycrank+0, 0, yyvstop+27,
+yycrank+0, 0, yyvstop+29,
+yycrank+54, 0, 0,
+yycrank+0, yysvec+30, yyvstop+31,
+yycrank+11, 0, 0,
+yycrank+6, 0, 0,
+yycrank+0, 0, yyvstop+33,
+yycrank+12, 0, 0,
+yycrank+3, yysvec+15, 0,
+yycrank+0, 0, yyvstop+35,
+yycrank+0, 0, yyvstop+37,
+yycrank+0, 0, yyvstop+39,
+yycrank+4, yysvec+30, 0,
+yycrank+0, 0, yyvstop+41,
+yycrank+4, 0, 0,
+yycrank+0, 0, yyvstop+43,
+yycrank+12, 0, 0,
+yycrank+3, yysvec+15, 0,
+yycrank+82, yysvec+30, 0,
+yycrank+17, 0, 0,
+yycrank+13, 0, 0,
+yycrank+17, 0, 0,
+yycrank+14, 0, 0,
+yycrank+23, 0, 0,
+yycrank+19, 0, 0,
+yycrank+18, 0, 0,
+yycrank+25, 0, 0,
+yycrank+30, 0, 0,
+yycrank+19, 0, 0,
+yycrank+23, 0, 0,
+yycrank+31, 0, 0,
+yycrank+25, 0, 0,
+yycrank+25, 0, 0,
+yycrank+30, 0, 0,
+yycrank+28, 0, 0,
+yycrank+22, 0, 0,
+yycrank+31, 0, 0,
+yycrank+39, 0, 0,
+yycrank+44, 0, 0,
+yycrank+25, 0, 0,
+yycrank+42, 0, 0,
+yycrank+0, 0, yyvstop+45,
+yycrank+27, 0, 0,
+yycrank+0, 0, yyvstop+47,
+0, 0, 0};
+struct yywork *yytop = yycrank+152;
+struct yysvf *yybgin = yysvec+1;
+char yymatch[] = {
+00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,
+'0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 ,
+0};
+char yyextra[] = {
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0};
+#ifndef lint
+static char ncform_sccsid[] = "@(#)ncform 1.6 88/02/08 SMI"; /* from S5R2 1.2 */
+#endif
+
+int yylineno =1;
+# define YYU(x) x
+# define NLSTATE yyprevious=YYNEWLINE
+char yytext[YYLMAX];
+struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp;
+char yysbuf[YYLMAX];
+char *yysptr = yysbuf;
+int *yyfnd;
+extern struct yysvf *yyestate;
+int yyprevious = YYNEWLINE;
+yylook(){
+ register struct yysvf *yystate, **lsp;
+ register struct yywork *yyt;
+ struct yysvf *yyz;
+ int yych, yyfirst;
+ struct yywork *yyr;
+# ifdef LEXDEBUG
+ int debug;
+# endif
+ char *yylastch;
+ /* start off machines */
+# ifdef LEXDEBUG
+ debug = 0;
+# endif
+ yyfirst=1;
+ if (!yymorfg)
+ yylastch = yytext;
+ else {
+ yymorfg=0;
+ yylastch = yytext+yyleng;
+ }
+ for(;;){
+ lsp = yylstate;
+ yyestate = yystate = yybgin;
+ if (yyprevious==YYNEWLINE) yystate++;
+ for (;;){
+# ifdef LEXDEBUG
+ if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1);
+# endif
+ yyt = yystate->yystoff;
+ if(yyt == yycrank && !yyfirst){ /* may not be any transitions */
+ yyz = yystate->yyother;
+ if(yyz == 0)break;
+ if(yyz->yystoff == yycrank)break;
+ }
+ *yylastch++ = yych = input();
+ yyfirst=0;
+ tryagain:
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"char ");
+ allprint(yych);
+ putchar('\n');
+ }
+# endif
+ yyr = yyt;
+ if ( (int)yyt > (int)yycrank){
+ yyt = yyr + yych;
+ if (yyt <= yytop && yyt->verify+yysvec == yystate){
+ if(yyt->advance+yysvec == YYLERR) /* error transitions */
+ {unput(*--yylastch);break;}
+ *lsp++ = yystate = yyt->advance+yysvec;
+ goto contin;
+ }
+ }
+# ifdef YYOPTIM
+ else if((int)yyt < (int)yycrank) { /* r < yycrank */
+ yyt = yyr = yycrank+(yycrank-yyt);
+# ifdef LEXDEBUG
+ if(debug)fprintf(yyout,"compressed state\n");
+# endif
+ yyt = yyt + yych;
+ if(yyt <= yytop && yyt->verify+yysvec == yystate){
+ if(yyt->advance+yysvec == YYLERR) /* error transitions */
+ {unput(*--yylastch);break;}
+ *lsp++ = yystate = yyt->advance+yysvec;
+ goto contin;
+ }
+ yyt = yyr + YYU(yymatch[yych]);
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"try fall back character ");
+ allprint(YYU(yymatch[yych]));
+ putchar('\n');
+ }
+# endif
+ if(yyt <= yytop && yyt->verify+yysvec == yystate){
+ if(yyt->advance+yysvec == YYLERR) /* error transition */
+ {unput(*--yylastch);break;}
+ *lsp++ = yystate = yyt->advance+yysvec;
+ goto contin;
+ }
+ }
+ if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
+# ifdef LEXDEBUG
+ if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
+# endif
+ goto tryagain;
+ }
+# endif
+ else
+ {unput(*--yylastch);break;}
+ contin:
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"state %d char ",yystate-yysvec-1);
+ allprint(yych);
+ putchar('\n');
+ }
+# endif
+ ;
+ }
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
+ allprint(yych);
+ putchar('\n');
+ }
+# endif
+ while (lsp-- > yylstate){
+ *yylastch-- = 0;
+ if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
+ yyolsp = lsp;
+ if(yyextra[*yyfnd]){ /* must backup */
+ while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
+ lsp--;
+ unput(*yylastch--);
+ }
+ }
+ yyprevious = YYU(*yylastch);
+ yylsp = lsp;
+ yyleng = yylastch-yytext+1;
+ yytext[yyleng] = 0;
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"\nmatch ");
+ sprint(yytext);
+ fprintf(yyout," action %d\n",*yyfnd);
+ }
+# endif
+ return(*yyfnd++);
+ }
+ unput(*yylastch);
+ }
+ if (yytext[0] == 0 /* && feof(yyin) */)
+ {
+ yysptr=yysbuf;
+ return(0);
+ }
+ yyprevious = yytext[0] = input();
+ if (yyprevious>0)
+ output(yyprevious);
+ yylastch=yytext;
+# ifdef LEXDEBUG
+ if(debug)putchar('\n');
+# endif
+ }
+ }
+yyback(p, m)
+ int *p;
+{
+if (p==0) return(0);
+while (*p)
+ {
+ if (*p++ == m)
+ return(1);
+ }
+return(0);
+}
+ /* the following are only used in the lex library */
+yyinput(){
+ return(input());
+ }
+yyoutput(c)
+ int c; {
+ output(c);
+ }
+yyunput(c)
+ int c; {
+ unput(c);
+ }
diff --git a/web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.lex b/web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.lex
new file mode 100644
index 0000000000..0263a26620
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/grasp-utils/verbatim/verbatim.lex
@@ -0,0 +1,57 @@
+
+ /* This Lex script acts as a filter to pre-process Latex files.
+
+ It surrounds groups of lines beginning with a ">" sign, and
+ preceded and followed by a blank line, with \begin{verbatim}
+ and \end{verbatim}. The ">" may be preceded by a digit or digit
+ range (eg 4>, 2-5>, 3->); in this case the digits are removed.
+ They are meant to be used for filtering out versions.
+
+ It takes words surrounded with @ signs (thus @letrec@) and makes them
+ come out in typewriter font, regardless of the current mode.
+ */
+
+%START NORM VERB MIRANDA VERBATIM VERBATIMSIM
+sp [ \t]*
+nl {sp}\n{sp}
+miranda ([0-9]+(\-([0-9]+)?)?)?>
+%{
+#define PUSH states[top++] =
+#define POP BEGIN states[--top]
+%}
+%%
+ int states[256];
+ int top;
+ BEGIN NORM;
+ top = 0;
+<NORM>@@ { printf ("@"); }
+<NORM>@ { printf ("\\mbox{\\tt "); PUSH NORM; BEGIN VERB; }
+<VERB>@ { printf ("}"); POP; }
+<VERB>\n { printf ("}\\\\{}\n\\mbox{\\tt "); }
+<VERB>" " { printf ("\\ "); }
+<VERB>@@ { printf ("@"); }
+<VERB>\# { printf ("{\\char'43}"); }
+<VERB>\$ { printf ("{\\char'44}"); }
+<VERB>\% { printf ("{\\char'45}"); }
+<VERB>\& { printf ("{\\char'46}"); }
+<VERB>\~ { printf ("{\\char'176}"); }
+<VERB>\_ { printf ("{\\char'137}"); }
+<VERB>\^ { printf ("{\\char'136}"); }
+<VERB>\\ { printf ("{\\char'134}"); }
+<VERB>\{ { printf ("{\\char'173}"); }
+<VERB>\} { printf ("{\\char'175}"); }
+
+<NORM>^@\n { printf( "\\begin{verbatim}\n" );
+ PUSH NORM; BEGIN VERBATIMSIM; }
+<VERBATIMSIM>^@\n { printf( "\\end{verbatim}\n" ); POP; }
+
+<NORM>\\"begin{verbatim}" { printf( "\\begin{verbatim}" );
+ PUSH NORM; BEGIN VERBATIM; }
+<VERBATIM>\\"end{verbatim}" { printf( "\\end{verbatim}" ); POP; }
+
+<NORM>^\n{miranda} { printf ("\\begin{verbatim}\n>" );
+ PUSH NORM; BEGIN MIRANDA; }
+<MIRANDA>\n{miranda} { printf( "\n>" ); }
+<MIRANDA>^\n { printf ("\\end{verbatim}\n"); POP; }
+
+