summaryrefslogtreecommitdiffstats
path: root/usr.bin/vgrind
diff options
context:
space:
mode:
authorrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
committerrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
commitf9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch)
treeadd7e996bac5289cdc55e6935750c352505560a9 /usr.bin/vgrind
parentbe22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff)
downloadFreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip
FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/vgrind')
-rw-r--r--usr.bin/vgrind/Makefile21
-rw-r--r--usr.bin/vgrind/RETEST/Makefile10
-rw-r--r--usr.bin/vgrind/RETEST/retest.c105
-rw-r--r--usr.bin/vgrind/extern.h65
-rw-r--r--usr.bin/vgrind/pathnames.h36
-rw-r--r--usr.bin/vgrind/regexp.c593
-rw-r--r--usr.bin/vgrind/tmac.vgrind68
-rw-r--r--usr.bin/vgrind/vfontedpr.c705
-rw-r--r--usr.bin/vgrind/vgrind.1224
-rw-r--r--usr.bin/vgrind/vgrind.sh143
-rw-r--r--usr.bin/vgrind/vgrindefs.5158
-rw-r--r--usr.bin/vgrind/vgrindefs.c326
-rw-r--r--usr.bin/vgrind/vgrindefs.src146
13 files changed, 2600 insertions, 0 deletions
diff --git a/usr.bin/vgrind/Makefile b/usr.bin/vgrind/Makefile
new file mode 100644
index 0000000..0bd4f00
--- /dev/null
+++ b/usr.bin/vgrind/Makefile
@@ -0,0 +1,21 @@
+# @(#)Makefile 8.1 (Berkeley) 6/9/93
+
+PROG= vfontedpr
+SRCS= regexp.c vfontedpr.c
+MAN1= vgrind.0
+MAN5= vgrindefs.0
+BINDIR= /usr/libexec
+CLEANFILES+=vgrindefs.src.db
+
+beforeinstall:
+ cap_mkdb -f vgrindefs.src ${.CURDIR}/vgrindefs.src
+ install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ ${.CURDIR}/vgrind.sh ${DESTDIR}/usr/bin/vgrind
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/vgrindefs.src \
+ ${DESTDIR}/usr/share/misc/vgrindefs
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ vgrindefs.src.db ${DESTDIR}/usr/share/misc/vgrindefs.db
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/tmac.vgrind \
+ ${DESTDIR}/usr/share/tmac
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/vgrind/RETEST/Makefile b/usr.bin/vgrind/RETEST/Makefile
new file mode 100644
index 0000000..1e50c81
--- /dev/null
+++ b/usr.bin/vgrind/RETEST/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= retest
+SRCS= regexp.c retest.c
+.PATH: ${.CURDIR}/..
+NOMAN= noman
+
+install:
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/vgrind/RETEST/retest.c b/usr.bin/vgrind/RETEST/retest.c
new file mode 100644
index 0000000..ce953cb
--- /dev/null
+++ b/usr.bin/vgrind/RETEST/retest.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1980, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)retest.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <ctype.h>
+
+int l_onecase = 0;
+char * _start;
+char * _escaped;
+char * convexp();
+char * expmatch();
+main()
+{
+ char reg[132];
+ char *ireg;
+ char str[132];
+ char *match;
+ char matstr[132];
+ char c;
+
+ while (1) {
+ printf ("\nexpr: ");
+ scanf ("%s", reg);
+ ireg = convexp(reg);
+ match = ireg;
+ while(*match) {
+ switch (*match) {
+
+ case '\\':
+ case '(':
+ case ')':
+ case '|':
+ printf ("%c", *match);
+ break;
+
+ default:
+ if (isalnum(*match))
+ printf("%c", *match);
+ else
+ printf ("<%03o>", *match);
+ break;
+ }
+ match++;
+ }
+ printf("\n");
+ getchar();
+ while(1) {
+ printf ("string: ");
+ match = str;
+ while ((c = getchar()) != '\n')
+ *match++ = c;
+ *match = 0;
+ if (str[0] == '#')
+ break;
+ matstr[0] = 0;
+ _start = str;
+ _escaped = 0;
+ match = expmatch (str, ireg, matstr);
+ if (match == 0)
+ printf ("FAILED\n");
+ else
+ printf ("match\nmatstr = %s\n", matstr);
+ }
+
+ }
+}
diff --git a/usr.bin/vgrind/extern.h b/usr.bin/vgrind/extern.h
new file mode 100644
index 0000000..0526d56
--- /dev/null
+++ b/usr.bin/vgrind/extern.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.1 (Berkeley) 6/6/93
+ */
+
+typedef int boolean;
+
+extern boolean _escaped; /* if last character was an escape */
+extern char *_start; /* start of the current string */
+extern char *l_acmbeg; /* string introducing a comment */
+extern char *l_acmend; /* string ending a comment */
+extern char *l_blkbeg; /* string begining of a block */
+extern char *l_blkend; /* string ending a block */
+extern char *l_chrbeg; /* delimiter for character constant */
+extern char *l_chrend; /* delimiter for character constant */
+extern char *l_combeg; /* string introducing a comment */
+extern char *l_comend; /* string ending a comment */
+extern char l_escape; /* character used to escape characters */
+extern char *l_keywds[]; /* keyword table address */
+extern boolean l_onecase; /* upper and lower case are equivalent */
+extern char *l_prcbeg; /* regular expr for procedure begin */
+extern char *l_strbeg; /* delimiter for string constant */
+extern char *l_strend; /* delimiter for string constant */
+extern boolean l_toplex; /* procedures only defined at top lex level */
+extern char *language; /* the language indicator */
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int STRNCMP __P((char *, char *, int));
+extern char *convexp __P((char *));
+extern char *expmatch __P((char *, char *, char *));
+__END_DECLS
+
diff --git a/usr.bin/vgrind/pathnames.h b/usr.bin/vgrind/pathnames.h
new file mode 100644
index 0000000..157f91f
--- /dev/null
+++ b/usr.bin/vgrind/pathnames.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define _PATH_VGRINDEFS "/usr/share/misc/vgrindefs"
diff --git a/usr.bin/vgrind/regexp.c b/usr.bin/vgrind/regexp.c
new file mode 100644
index 0000000..978af65
--- /dev/null
+++ b/usr.bin/vgrind/regexp.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1980, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)regexp.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "extern.h"
+
+#define FALSE 0
+#define TRUE !(FALSE)
+#define NIL 0
+
+static void expconv __P((void));
+
+boolean _escaped; /* true if we are currently _escaped */
+char *_start; /* start of string */
+boolean l_onecase; /* true if upper and lower equivalent */
+
+#define makelower(c) (isupper((c)) ? tolower((c)) : (c))
+
+/* STRNCMP - like strncmp except that we convert the
+ * first string to lower case before comparing
+ * if l_onecase is set.
+ */
+
+int
+STRNCMP(s1, s2, len)
+ register char *s1,*s2;
+ register int len;
+{
+ if (l_onecase) {
+ do
+ if (*s2 - makelower(*s1))
+ return (*s2 - makelower(*s1));
+ else {
+ s2++;
+ s1++;
+ }
+ while (--len);
+ } else {
+ do
+ if (*s2 - *s1)
+ return (*s2 - *s1);
+ else {
+ s2++;
+ s1++;
+ }
+ while (--len);
+ }
+ return(0);
+}
+
+/* The following routine converts an irregular expression to
+ * internal format.
+ *
+ * Either meta symbols (\a \d or \p) or character strings or
+ * operations ( alternation or perenthesizing ) can be
+ * specified. Each starts with a descriptor byte. The descriptor
+ * byte has STR set for strings, META set for meta symbols
+ * and OPER set for operations.
+ * The descriptor byte can also have the OPT bit set if the object
+ * defined is optional. Also ALT can be set to indicate an alternation.
+ *
+ * For metasymbols the byte following the descriptor byte identities
+ * the meta symbol (containing an ascii 'a', 'd', 'p', '|', or '('). For
+ * strings the byte after the descriptor is a character count for
+ * the string:
+ *
+ * meta symbols := descriptor
+ * symbol
+ *
+ * strings := descriptor
+ * character count
+ * the string
+ *
+ * operatins := descriptor
+ * symbol
+ * character count
+ */
+
+/*
+ * handy macros for accessing parts of match blocks
+ */
+#define MSYM(A) (*(A+1)) /* symbol in a meta symbol block */
+#define MNEXT(A) (A+2) /* character following a metasymbol block */
+
+#define OSYM(A) (*(A+1)) /* symbol in an operation block */
+#define OCNT(A) (*(A+2)) /* character count */
+#define ONEXT(A) (A+3) /* next character after the operation */
+#define OPTR(A) (A+*(A+2)) /* place pointed to by the operator */
+
+#define SCNT(A) (*(A+1)) /* byte count of a string */
+#define SSTR(A) (A+2) /* address of the string */
+#define SNEXT(A) (A+2+*(A+1)) /* character following the string */
+
+/*
+ * bit flags in the descriptor
+ */
+#define OPT 1
+#define STR 2
+#define META 4
+#define ALT 8
+#define OPER 16
+
+static char *ccre; /* pointer to current position in converted exp*/
+static char *ure; /* pointer current position in unconverted exp */
+
+char *
+convexp(re)
+ char *re; /* unconverted irregular expression */
+{
+ register char *cre; /* pointer to converted regular expression */
+
+ /* allocate room for the converted expression */
+ if (re == NIL)
+ return (NIL);
+ if (*re == '\0')
+ return (NIL);
+ cre = malloc (4 * strlen(re) + 3);
+ ccre = cre;
+ ure = re;
+
+ /* start the conversion with a \a */
+ *cre = META | OPT;
+ MSYM(cre) = 'a';
+ ccre = MNEXT(cre);
+
+ /* start the conversion (its recursive) */
+ expconv ();
+ *ccre = 0;
+ return (cre);
+}
+
+static void
+expconv()
+{
+ register char *cs; /* pointer to current symbol in converted exp */
+ register char c; /* character being processed */
+ register char *acs; /* pinter to last alternate */
+ register int temp;
+
+ /* let the conversion begin */
+ acs = NIL;
+ cs = NIL;
+ while (*ure != NIL) {
+ switch (c = *ure++) {
+
+ case '\\':
+ switch (c = *ure++) {
+
+ /* escaped characters are just characters */
+ default:
+ if (cs == NIL || (*cs & STR) == 0) {
+ cs = ccre;
+ *cs = STR;
+ SCNT(cs) = 1;
+ ccre += 2;
+ } else
+ SCNT(cs)++;
+ *ccre++ = c;
+ break;
+
+ /* normal(?) metacharacters */
+ case 'a':
+ case 'd':
+ case 'e':
+ case 'p':
+ if (acs != NIL && acs != cs) {
+ do {
+ temp = OCNT(acs);
+ OCNT(acs) = ccre - acs;
+ acs -= temp;
+ } while (temp != 0);
+ acs = NIL;
+ }
+ cs = ccre;
+ *cs = META;
+ MSYM(cs) = c;
+ ccre = MNEXT(cs);
+ break;
+ }
+ break;
+
+ /* just put the symbol in */
+ case '^':
+ case '$':
+ if (acs != NIL && acs != cs) {
+ do {
+ temp = OCNT(acs);
+ OCNT(acs) = ccre - acs;
+ acs -= temp;
+ } while (temp != 0);
+ acs = NIL;
+ }
+ cs = ccre;
+ *cs = META;
+ MSYM(cs) = c;
+ ccre = MNEXT(cs);
+ break;
+
+ /* mark the last match sequence as optional */
+ case '?':
+ if (cs)
+ *cs = *cs | OPT;
+ break;
+
+ /* recurse and define a subexpression */
+ case '(':
+ if (acs != NIL && acs != cs) {
+ do {
+ temp = OCNT(acs);
+ OCNT(acs) = ccre - acs;
+ acs -= temp;
+ } while (temp != 0);
+ acs = NIL;
+ }
+ cs = ccre;
+ *cs = OPER;
+ OSYM(cs) = '(';
+ ccre = ONEXT(cs);
+ expconv ();
+ OCNT(cs) = ccre - cs; /* offset to next symbol */
+ break;
+
+ /* reurn from a recursion */
+ case ')':
+ if (acs != NIL) {
+ do {
+ temp = OCNT(acs);
+ OCNT(acs) = ccre - acs;
+ acs -= temp;
+ } while (temp != 0);
+ acs = NIL;
+ }
+ cs = ccre;
+ *cs = META;
+ MSYM(cs) = c;
+ ccre = MNEXT(cs);
+ return;
+
+ /* mark the last match sequence as having an alternate */
+ /* the third byte will contain an offset to jump over the */
+ /* alternate match in case the first did not fail */
+ case '|':
+ if (acs != NIL && acs != cs)
+ OCNT(ccre) = ccre - acs; /* make a back pointer */
+ else
+ OCNT(ccre) = 0;
+ *cs |= ALT;
+ cs = ccre;
+ *cs = OPER;
+ OSYM(cs) = '|';
+ ccre = ONEXT(cs);
+ acs = cs; /* remember that the pointer is to be filles */
+ break;
+
+ /* if its not a metasymbol just build a scharacter string */
+ default:
+ if (cs == NIL || (*cs & STR) == 0) {
+ cs = ccre;
+ *cs = STR;
+ SCNT(cs) = 1;
+ ccre = SSTR(cs);
+ } else
+ SCNT(cs)++;
+ *ccre++ = c;
+ break;
+ }
+ }
+ if (acs != NIL) {
+ do {
+ temp = OCNT(acs);
+ OCNT(acs) = ccre - acs;
+ acs -= temp;
+ } while (temp != 0);
+ acs = NIL;
+ }
+ return;
+}
+/* end of convertre */
+
+
+/*
+ * The following routine recognises an irregular expresion
+ * with the following special characters:
+ *
+ * \? - means last match was optional
+ * \a - matches any number of characters
+ * \d - matches any number of spaces and tabs
+ * \p - matches any number of alphanumeric
+ * characters. The
+ * characters matched will be copied into
+ * the area pointed to by 'name'.
+ * \| - alternation
+ * \( \) - grouping used mostly for alternation and
+ * optionality
+ *
+ * The irregular expression must be translated to internal form
+ * prior to calling this routine
+ *
+ * The value returned is the pointer to the first non \a
+ * character matched.
+ */
+
+char *
+expmatch (s, re, mstring)
+ register char *s; /* string to check for a match in */
+ register char *re; /* a converted irregular expression */
+ register char *mstring; /* where to put whatever matches a \p */
+{
+ register char *cs; /* the current symbol */
+ register char *ptr,*s1; /* temporary pointer */
+ boolean matched; /* a temporary boolean */
+
+ /* initial conditions */
+ if (re == NIL)
+ return (NIL);
+ cs = re;
+ matched = FALSE;
+
+ /* loop till expression string is exhausted (or at least pretty tired) */
+ while (*cs) {
+ switch (*cs & (OPER | STR | META)) {
+
+ /* try to match a string */
+ case STR:
+ matched = !STRNCMP (s, SSTR(cs), SCNT(cs));
+ if (matched) {
+
+ /* hoorah it matches */
+ s += SCNT(cs);
+ cs = SNEXT(cs);
+ } else if (*cs & ALT) {
+
+ /* alternation, skip to next expression */
+ cs = SNEXT(cs);
+ } else if (*cs & OPT) {
+
+ /* the match is optional */
+ cs = SNEXT(cs);
+ matched = 1; /* indicate a successful match */
+ } else {
+
+ /* no match, error return */
+ return (NIL);
+ }
+ break;
+
+ /* an operator, do something fancy */
+ case OPER:
+ switch (OSYM(cs)) {
+
+ /* this is an alternation */
+ case '|':
+ if (matched)
+
+ /* last thing in the alternation was a match, skip ahead */
+ cs = OPTR(cs);
+ else
+
+ /* no match, keep trying */
+ cs = ONEXT(cs);
+ break;
+
+ /* this is a grouping, recurse */
+ case '(':
+ ptr = expmatch (s, ONEXT(cs), mstring);
+ if (ptr != NIL) {
+
+ /* the subexpression matched */
+ matched = 1;
+ s = ptr;
+ } else if (*cs & ALT) {
+
+ /* alternation, skip to next expression */
+ matched = 0;
+ } else if (*cs & OPT) {
+
+ /* the match is optional */
+ matched = 1; /* indicate a successful match */
+ } else {
+
+ /* no match, error return */
+ return (NIL);
+ }
+ cs = OPTR(cs);
+ break;
+ }
+ break;
+
+ /* try to match a metasymbol */
+ case META:
+ switch (MSYM(cs)) {
+
+ /* try to match anything and remember what was matched */
+ case 'p':
+ /*
+ * This is really the same as trying the match the
+ * remaining parts of the expression to any subset
+ * of the string.
+ */
+ s1 = s;
+ do {
+ ptr = expmatch (s1, MNEXT(cs), mstring);
+ if (ptr != NIL && s1 != s) {
+
+ /* we have a match, remember the match */
+ strncpy (mstring, s, s1 - s);
+ mstring[s1 - s] = '\0';
+ return (ptr);
+ } else if (ptr != NIL && (*cs & OPT)) {
+
+ /* it was aoptional so no match is ok */
+ return (ptr);
+ } else if (ptr != NIL) {
+
+ /* not optional and we still matched */
+ return (NIL);
+ }
+ if (!isalnum(*s1) && *s1 != '_')
+ return (NIL);
+ if (*s1 == '\\')
+ _escaped = _escaped ? FALSE : TRUE;
+ else
+ _escaped = FALSE;
+ } while (*s1++);
+ return (NIL);
+
+ /* try to match anything */
+ case 'a':
+ /*
+ * This is really the same as trying the match the
+ * remaining parts of the expression to any subset
+ * of the string.
+ */
+ s1 = s;
+ do {
+ ptr = expmatch (s1, MNEXT(cs), mstring);
+ if (ptr != NIL && s1 != s) {
+
+ /* we have a match */
+ return (ptr);
+ } else if (ptr != NIL && (*cs & OPT)) {
+
+ /* it was aoptional so no match is ok */
+ return (ptr);
+ } else if (ptr != NIL) {
+
+ /* not optional and we still matched */
+ return (NIL);
+ }
+ if (*s1 == '\\')
+ _escaped = _escaped ? FALSE : TRUE;
+ else
+ _escaped = FALSE;
+ } while (*s1++);
+ return (NIL);
+
+ /* fail if we are currently _escaped */
+ case 'e':
+ if (_escaped)
+ return(NIL);
+ cs = MNEXT(cs);
+ break;
+
+ /* match any number of tabs and spaces */
+ case 'd':
+ ptr = s;
+ while (*s == ' ' || *s == '\t')
+ s++;
+ if (s != ptr || s == _start) {
+
+ /* match, be happy */
+ matched = 1;
+ cs = MNEXT(cs);
+ } else if (*s == '\n' || *s == '\0') {
+
+ /* match, be happy */
+ matched = 1;
+ cs = MNEXT(cs);
+ } else if (*cs & ALT) {
+
+ /* try the next part */
+ matched = 0;
+ cs = MNEXT(cs);
+ } else if (*cs & OPT) {
+
+ /* doesn't matter */
+ matched = 1;
+ cs = MNEXT(cs);
+ } else
+
+ /* no match, error return */
+ return (NIL);
+ break;
+
+ /* check for end of line */
+ case '$':
+ if (*s == '\0' || *s == '\n') {
+
+ /* match, be happy */
+ s++;
+ matched = 1;
+ cs = MNEXT(cs);
+ } else if (*cs & ALT) {
+
+ /* try the next part */
+ matched = 0;
+ cs = MNEXT(cs);
+ } else if (*cs & OPT) {
+
+ /* doesn't matter */
+ matched = 1;
+ cs = MNEXT(cs);
+ } else
+
+ /* no match, error return */
+ return (NIL);
+ break;
+
+ /* check for start of line */
+ case '^':
+ if (s == _start) {
+
+ /* match, be happy */
+ matched = 1;
+ cs = MNEXT(cs);
+ } else if (*cs & ALT) {
+
+ /* try the next part */
+ matched = 0;
+ cs = MNEXT(cs);
+ } else if (*cs & OPT) {
+
+ /* doesn't matter */
+ matched = 1;
+ cs = MNEXT(cs);
+ } else
+
+ /* no match, error return */
+ return (NIL);
+ break;
+
+ /* end of a subexpression, return success */
+ case ')':
+ return (s);
+ }
+ break;
+ }
+ }
+ return (s);
+}
diff --git a/usr.bin/vgrind/tmac.vgrind b/usr.bin/vgrind/tmac.vgrind
new file mode 100644
index 0000000..d9d8af2
--- /dev/null
+++ b/usr.bin/vgrind/tmac.vgrind
@@ -0,0 +1,68 @@
+'ss 23
+'ds _ \d\(mi\u
+'ps 9p
+'vs 10p
+'ds - \(mi
+'ds / \\h'\\w' 'u-\\w'/'u'/
+'ds /* \\h'\\w' 'u-\\w'/'u'/*
+'bd B 3
+'bd S B 3
+'nr cm 0
+'nf
+'de vH
+'ev 2
+'if t 'if !\nv 'tl '\-\-''\-\-'
+'ft 1
+'sp .35i
+'tl '\s14\f3\\*(=F\fP\s0'\\*(=H'\f3\s14\\*(=F\fP\s0'
+'sp .25i
+'ft 1
+\f2\s12\h'\\n(.lu-\w'\\*(=f'u'\\*(=f\fP\s0\h'|0u'
+.sp .05i
+'ev
+'ds =G \\*(=F
+..
+'de vF
+'ev 2
+'sp .35i
+'ie o 'tl '\f2\\*(=M''Page % of \\*(=G\fP'
+'el 'tl '\f2Page % of \\*(=G''\\*(=M\fP'
+'bp
+'ev
+'ft 1
+'if \\n(cm=1 'ft 2
+..
+'de ()
+'pn 1
+..
+'de +C
+'nr cm 1
+'ft 2
+'ds +K
+'ds -K
+..
+'de -C
+'nr cm 0
+'ft 1
+'ds +K \f3
+'ds -K \fP
+..
+'+C
+'-C
+'am +C
+'ne 3
+..
+'de FN
+\f2\s14\h'\\n(.lu-\w'\\$1'u'\\$1\fP\s0\h'|0u'\c
+.if \\nx .tm \\$1 \\*(=F \\n%
+'ds =f \&...\\$1
+..
+'de FC
+.if \\nx .tm \\$1 \\*(=F \\n%
+'ds =f \&...\\$1
+..
+'de -F
+'rm =f
+..
+'ft 1
+'lg 0
diff --git a/usr.bin/vgrind/vfontedpr.c b/usr.bin/vgrind/vfontedpr.c
new file mode 100644
index 0000000..30320c6
--- /dev/null
+++ b/usr.bin/vgrind/vfontedpr.c
@@ -0,0 +1,705 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1980, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)vfontedpr.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "pathnames.h"
+#include "extern.h"
+
+#define FALSE 0
+#define TRUE !(FALSE)
+#define NIL 0
+#define STANDARD 0
+#define ALTERNATE 1
+
+/*
+ * Vfontedpr.
+ *
+ * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy)
+ *
+ */
+
+#define STRLEN 10 /* length of strings introducing things */
+#define PNAMELEN 40 /* length of a function/procedure name */
+#define PSMAX 20 /* size of procedure name stacking */
+
+static int iskw __P((char *));
+static boolean isproc __P((char *));
+static void putKcp __P((char *, char *, boolean));
+static void putScp __P((char *));
+static void putcp __P((int));
+static int tabs __P((char *, char *));
+static int width __P((char *, char *));
+
+/*
+ * The state variables
+ */
+
+static boolean filter = FALSE; /* act as a filter (like eqn) */
+static boolean inchr; /* in a string constant */
+static boolean incomm; /* in a comment of the primary type */
+static boolean idx = FALSE; /* form an index */
+static boolean instr; /* in a string constant */
+static boolean nokeyw = FALSE; /* no keywords being flagged */
+static boolean pass = FALSE; /*
+ * when acting as a filter, pass indicates
+ * whether we are currently processing
+ * input.
+ */
+
+static int blklevel; /* current nesting level */
+static int comtype; /* type of comment */
+static char *defsfile[2] = { _PATH_VGRINDEFS, 0 };
+ /* name of language definitions file */
+static int margin;
+static int plstack[PSMAX]; /* the procedure nesting level stack */
+static char pname[BUFSIZ+1];
+static boolean prccont; /* continue last procedure */
+static int psptr; /* the stack index of the current procedure */
+static char pstack[PSMAX][PNAMELEN+1]; /* the procedure name stack */
+
+/*
+ * The language specific globals
+ */
+
+char *l_acmbeg; /* string introducing a comment */
+char *l_acmend; /* string ending a comment */
+char *l_blkbeg; /* string begining of a block */
+char *l_blkend; /* string ending a block */
+char *l_chrbeg; /* delimiter for character constant */
+char *l_chrend; /* delimiter for character constant */
+char *l_combeg; /* string introducing a comment */
+char *l_comend; /* string ending a comment */
+char l_escape; /* character used to escape characters */
+char *l_keywds[BUFSIZ/2]; /* keyword table address */
+char *l_prcbeg; /* regular expr for procedure begin */
+char *l_strbeg; /* delimiter for string constant */
+char *l_strend; /* delimiter for string constant */
+boolean l_toplex; /* procedures only defined at top lex level */
+char *language = "c"; /* the language indicator */
+
+#define ps(x) printf("%s", x)
+
+void
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *fname = "";
+ struct stat stbuf;
+ char buf[BUFSIZ];
+ char *defs;
+ int needbp = 0;
+
+ argc--, argv++;
+ do {
+ char *cp;
+ int i;
+
+ if (argc > 0) {
+ if (!strcmp(argv[0], "-h")) {
+ if (argc == 1) {
+ printf("'ds =H\n");
+ argc = 0;
+ goto rest;
+ }
+ printf("'ds =H %s\n", argv[1]);
+ argc--, argv++;
+ argc--, argv++;
+ if (argc > 0)
+ continue;
+ goto rest;
+ }
+
+ /* act as a filter like eqn */
+ if (!strcmp(argv[0], "-f")) {
+ filter++;
+ argv[0] = argv[argc-1];
+ argv[argc-1] = "-";
+ continue;
+ }
+
+ /* take input from the standard place */
+ if (!strcmp(argv[0], "-")) {
+ argc = 0;
+ goto rest;
+ }
+
+ /* build an index */
+ if (!strcmp(argv[0], "-x")) {
+ idx++;
+ argv[0] = "-n";
+ }
+
+ /* indicate no keywords */
+ if (!strcmp(argv[0], "-n")) {
+ nokeyw++;
+ argc--, argv++;
+ continue;
+ }
+
+ /* specify the font size */
+ if (!strncmp(argv[0], "-s", 2)) {
+ i = 0;
+ cp = argv[0] + 2;
+ while (*cp)
+ i = i * 10 + (*cp++ - '0');
+ printf("'ps %d\n'vs %d\n", i, i+1);
+ argc--, argv++;
+ continue;
+ }
+
+ /* specify the language */
+ if (!strncmp(argv[0], "-l", 2)) {
+ language = argv[0]+2;
+ argc--, argv++;
+ continue;
+ }
+
+ /* specify the language description file */
+ if (!strncmp(argv[0], "-d", 2)) {
+ defsfile[0] = argv[1];
+ argc--, argv++;
+ argc--, argv++;
+ continue;
+ }
+
+ /* open the file for input */
+ if (freopen(argv[0], "r", stdin) == NULL) {
+ perror(argv[0]);
+ exit(1);
+ }
+ if (idx)
+ printf("'ta 4i 4.25i 5.5iR\n'in .5i\n");
+ fname = argv[0];
+ argc--, argv++;
+ }
+ rest:
+
+ /*
+ * get the language definition from the defs file
+ */
+ i = cgetent(&defs, defsfile, language);
+ if (i == -1) {
+ fprintf (stderr, "no entry for language %s\n", language);
+ exit (0);
+ } else if (i == -2) { fprintf(stderr,
+ "cannot find vgrindefs file %s\n", defsfile[0]);
+ exit (0);
+ } else if (i == -3) { fprintf(stderr,
+ "potential reference loop detected in vgrindefs file %s\n",
+ defsfile[0]);
+ exit(0);
+ }
+ if (cgetustr(defs, "kw", &cp) == -1)
+ nokeyw = TRUE;
+ else {
+ char **cpp;
+
+ cpp = l_keywds;
+ while (*cp) {
+ while (*cp == ' ' || *cp =='\t')
+ *cp++ = NULL;
+ if (*cp)
+ *cpp++ = cp;
+ while (*cp != ' ' && *cp != '\t' && *cp)
+ cp++;
+ }
+ *cpp = NIL;
+ }
+ cgetustr(defs, "pb", &cp);
+ l_prcbeg = convexp(cp);
+ cgetustr(defs, "cb", &cp);
+ l_combeg = convexp(cp);
+ cgetustr(defs, "ce", &cp);
+ l_comend = convexp(cp);
+ cgetustr(defs, "ab", &cp);
+ l_acmbeg = convexp(cp);
+ cgetustr(defs, "ae", &cp);
+ l_acmend = convexp(cp);
+ cgetustr(defs, "sb", &cp);
+ l_strbeg = convexp(cp);
+ cgetustr(defs, "se", &cp);
+ l_strend = convexp(cp);
+ cgetustr(defs, "bb", &cp);
+ l_blkbeg = convexp(cp);
+ cgetustr(defs, "be", &cp);
+ l_blkend = convexp(cp);
+ cgetustr(defs, "lb", &cp);
+ l_chrbeg = convexp(cp);
+ cgetustr(defs, "le", &cp);
+ l_chrend = convexp(cp);
+ l_escape = '\\';
+ l_onecase = (cgetcap(defs, "oc", ':') != NULL);
+ l_toplex = (cgetcap(defs, "tl", ':') != NULL);
+
+ /* initialize the program */
+
+ incomm = FALSE;
+ instr = FALSE;
+ inchr = FALSE;
+ _escaped = FALSE;
+ blklevel = 0;
+ for (psptr=0; psptr<PSMAX; psptr++) {
+ pstack[psptr][0] = NULL;
+ plstack[psptr] = 0;
+ }
+ psptr = -1;
+ ps("'-F\n");
+ if (!filter) {
+ printf(".ds =F %s\n", fname);
+ ps("'wh 0 vH\n");
+ ps("'wh -1i vF\n");
+ }
+ if (needbp) {
+ needbp = 0;
+ printf(".()\n");
+ printf(".bp\n");
+ }
+ if (!filter) {
+ fstat(fileno(stdin), &stbuf);
+ cp = ctime(&stbuf.st_mtime);
+ cp[16] = '\0';
+ cp[24] = '\0';
+ printf(".ds =M %s %s\n", cp+4, cp+20);
+ }
+
+ /*
+ * MAIN LOOP!!!
+ */
+ while (fgets(buf, sizeof buf, stdin) != NULL) {
+ if (buf[0] == '\f') {
+ printf(".bp\n");
+ }
+ if (buf[0] == '.') {
+ printf("%s", buf);
+ if (!strncmp (buf+1, "vS", 2))
+ pass = TRUE;
+ if (!strncmp (buf+1, "vE", 2))
+ pass = FALSE;
+ continue;
+ }
+ prccont = FALSE;
+ if (!filter || pass)
+ putScp(buf);
+ else
+ printf("%s", buf);
+ if (prccont && (psptr >= 0)) {
+ ps("'FC ");
+ ps(pstack[psptr]);
+ ps("\n");
+ }
+#ifdef DEBUG
+ printf ("com %o str %o chr %o ptr %d\n", incomm, instr, inchr, psptr);
+#endif
+ margin = 0;
+ }
+ needbp = 1;
+ } while (argc > 0);
+ exit(0);
+}
+
+#define isidchr(c) (isalnum(c) || (c) == '_')
+
+static void
+putScp(os)
+ char *os;
+{
+ register char *s = os; /* pointer to unmatched string */
+ char dummy[BUFSIZ]; /* dummy to be used by expmatch */
+ char *comptr; /* end of a comment delimiter */
+ char *acmptr; /* end of a comment delimiter */
+ char *strptr; /* end of a string delimiter */
+ char *chrptr; /* end of a character const delimiter */
+ char *blksptr; /* end of a lexical block start */
+ char *blkeptr; /* end of a lexical block end */
+
+ _start = os; /* remember the start for expmatch */
+ _escaped = FALSE;
+ if (nokeyw || incomm || instr)
+ goto skip;
+ if (isproc(s)) {
+ ps("'FN ");
+ ps(pname);
+ ps("\n");
+ if (psptr < PSMAX) {
+ ++psptr;
+ strncpy (pstack[psptr], pname, PNAMELEN);
+ pstack[psptr][PNAMELEN] = NULL;
+ plstack[psptr] = blklevel;
+ }
+ }
+skip:
+ do {
+ /* check for string, comment, blockstart, etc */
+ if (!incomm && !instr && !inchr) {
+
+ blkeptr = expmatch (s, l_blkend, dummy);
+ blksptr = expmatch (s, l_blkbeg, dummy);
+ comptr = expmatch (s, l_combeg, dummy);
+ acmptr = expmatch (s, l_acmbeg, dummy);
+ strptr = expmatch (s, l_strbeg, dummy);
+ chrptr = expmatch (s, l_chrbeg, dummy);
+
+ /* start of a comment? */
+ if (comptr != NIL)
+ if ((comptr < strptr || strptr == NIL)
+ && (comptr < acmptr || acmptr == NIL)
+ && (comptr < chrptr || chrptr == NIL)
+ && (comptr < blksptr || blksptr == NIL)
+ && (comptr < blkeptr || blkeptr == NIL)) {
+ putKcp (s, comptr-1, FALSE);
+ s = comptr;
+ incomm = TRUE;
+ comtype = STANDARD;
+ if (s != os)
+ ps ("\\c");
+ ps ("\\c\n'+C\n");
+ continue;
+ }
+
+ /* start of a comment? */
+ if (acmptr != NIL)
+ if ((acmptr < strptr || strptr == NIL)
+ && (acmptr < chrptr || chrptr == NIL)
+ && (acmptr < blksptr || blksptr == NIL)
+ && (acmptr < blkeptr || blkeptr == NIL)) {
+ putKcp (s, acmptr-1, FALSE);
+ s = acmptr;
+ incomm = TRUE;
+ comtype = ALTERNATE;
+ if (s != os)
+ ps ("\\c");
+ ps ("\\c\n'+C\n");
+ continue;
+ }
+
+ /* start of a string? */
+ if (strptr != NIL)
+ if ((strptr < chrptr || chrptr == NIL)
+ && (strptr < blksptr || blksptr == NIL)
+ && (strptr < blkeptr || blkeptr == NIL)) {
+ putKcp (s, strptr-1, FALSE);
+ s = strptr;
+ instr = TRUE;
+ continue;
+ }
+
+ /* start of a character string? */
+ if (chrptr != NIL)
+ if ((chrptr < blksptr || blksptr == NIL)
+ && (chrptr < blkeptr || blkeptr == NIL)) {
+ putKcp (s, chrptr-1, FALSE);
+ s = chrptr;
+ inchr = TRUE;
+ continue;
+ }
+
+ /* end of a lexical block */
+ if (blkeptr != NIL) {
+ if (blkeptr < blksptr || blksptr == NIL) {
+ putKcp (s, blkeptr - 1, FALSE);
+ s = blkeptr;
+ blklevel--;
+ if (psptr >= 0 && plstack[psptr] >= blklevel) {
+
+ /* end of current procedure */
+ if (s != os)
+ ps ("\\c");
+ ps ("\\c\n'-F\n");
+ blklevel = plstack[psptr];
+
+ /* see if we should print the last proc name */
+ if (--psptr >= 0)
+ prccont = TRUE;
+ else
+ psptr = -1;
+ }
+ continue;
+ }
+ }
+
+ /* start of a lexical block */
+ if (blksptr != NIL) {
+ putKcp (s, blksptr - 1, FALSE);
+ s = blksptr;
+ blklevel++;
+ continue;
+ }
+
+ /* check for end of comment */
+ } else if (incomm) {
+ comptr = expmatch (s, l_comend, dummy);
+ acmptr = expmatch (s, l_acmend, dummy);
+ if (((comtype == STANDARD) && (comptr != NIL)) ||
+ ((comtype == ALTERNATE) && (acmptr != NIL))) {
+ if (comtype == STANDARD) {
+ putKcp (s, comptr-1, TRUE);
+ s = comptr;
+ } else {
+ putKcp (s, acmptr-1, TRUE);
+ s = acmptr;
+ }
+ incomm = FALSE;
+ ps("\\c\n'-C\n");
+ continue;
+ } else {
+ putKcp (s, s + strlen(s) -1, TRUE);
+ s = s + strlen(s);
+ continue;
+ }
+
+ /* check for end of string */
+ } else if (instr) {
+ if ((strptr = expmatch (s, l_strend, dummy)) != NIL) {
+ putKcp (s, strptr-1, TRUE);
+ s = strptr;
+ instr = FALSE;
+ continue;
+ } else {
+ putKcp (s, s+strlen(s)-1, TRUE);
+ s = s + strlen(s);
+ continue;
+ }
+
+ /* check for end of character string */
+ } else if (inchr) {
+ if ((chrptr = expmatch (s, l_chrend, dummy)) != NIL) {
+ putKcp (s, chrptr-1, TRUE);
+ s = chrptr;
+ inchr = FALSE;
+ continue;
+ } else {
+ putKcp (s, s+strlen(s)-1, TRUE);
+ s = s + strlen(s);
+ continue;
+ }
+ }
+
+ /* print out the line */
+ putKcp (s, s + strlen(s) -1, FALSE);
+ s = s + strlen(s);
+ } while (*s);
+}
+
+static void
+putKcp (start, end, force)
+ char *start; /* start of string to write */
+ char *end; /* end of string to write */
+ boolean force; /* true if we should force nokeyw */
+{
+ int i;
+ int xfld = 0;
+
+ while (start <= end) {
+ if (idx) {
+ if (*start == ' ' || *start == '\t') {
+ if (xfld == 0)
+ printf("");
+ printf("\t");
+ xfld = 1;
+ while (*start == ' ' || *start == '\t')
+ start++;
+ continue;
+ }
+ }
+
+ /* take care of nice tab stops */
+ if (*start == '\t') {
+ while (*start == '\t')
+ start++;
+ i = tabs(_start, start) - margin / 8;
+ printf("\\h'|%dn'", i * 10 + 1 - margin % 8);
+ continue;
+ }
+
+ if (!nokeyw && !force)
+ if ((*start == '#' || isidchr(*start))
+ && (start == _start || !isidchr(start[-1]))) {
+ i = iskw(start);
+ if (i > 0) {
+ ps("\\*(+K");
+ do
+ putcp(*start++);
+ while (--i > 0);
+ ps("\\*(-K");
+ continue;
+ }
+ }
+
+ putcp (*start++);
+ }
+}
+
+
+static int
+tabs(s, os)
+ char *s, *os;
+{
+
+ return (width(s, os) / 8);
+}
+
+static int
+width(s, os)
+ register char *s, *os;
+{
+ register int i = 0;
+
+ while (s < os) {
+ if (*s == '\t') {
+ i = (i + 8) &~ 7;
+ s++;
+ continue;
+ }
+ if (*s < ' ')
+ i += 2;
+ else
+ i++;
+ s++;
+ }
+ return (i);
+}
+
+static void
+putcp(c)
+ register int c;
+{
+
+ switch(c) {
+
+ case 0:
+ break;
+
+ case '\f':
+ break;
+
+ case '{':
+ ps("\\*(+K{\\*(-K");
+ break;
+
+ case '}':
+ ps("\\*(+K}\\*(-K");
+ break;
+
+ case '\\':
+ ps("\\e");
+ break;
+
+ case '_':
+ ps("\\*_");
+ break;
+
+ case '-':
+ ps("\\*-");
+ break;
+
+ case '`':
+ ps("\\`");
+ break;
+
+ case '\'':
+ ps("\\'");
+ break;
+
+ case '.':
+ ps("\\&.");
+ break;
+
+ case '*':
+ ps("\\fI*\\fP");
+ break;
+
+ case '/':
+ ps("\\fI\\h'\\w' 'u-\\w'/'u'/\\fP");
+ break;
+
+ default:
+ if (c < 040)
+ putchar('^'), c |= '@';
+ case '\t':
+ case '\n':
+ putchar(c);
+ }
+}
+
+/*
+ * look for a process beginning on this line
+ */
+static boolean
+isproc(s)
+ char *s;
+{
+ pname[0] = NULL;
+ if (!l_toplex || blklevel == 0)
+ if (expmatch (s, l_prcbeg, pname) != NIL) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+
+/* iskw - check to see if the next word is a keyword
+ */
+
+static int
+iskw(s)
+ register char *s;
+{
+ register char **ss = l_keywds;
+ register int i = 1;
+ register char *cp = s;
+
+ while (++cp, isidchr(*cp))
+ i++;
+ while (cp = *ss++)
+ if (!STRNCMP(s,cp,i) && !isidchr(cp[i]))
+ return (i);
+ return (0);
+}
+
diff --git a/usr.bin/vgrind/vgrind.1 b/usr.bin/vgrind/vgrind.1
new file mode 100644
index 0000000..97ba7e2
--- /dev/null
+++ b/usr.bin/vgrind/vgrind.1
@@ -0,0 +1,224 @@
+.\" Copyright (c) 1980, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vgrind.1 8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt VGRIND 1
+.Os BSD 4
+.Sh NAME
+.Nm vgrind
+.Nd grind nice listings of programs
+.Sh SYNOPSIS
+.Nm vgrind
+.Op Fl
+.Op Fl W
+.Op Fl d Ar file
+.Op Fl f
+.Op Fl h Ar header
+.Op Fl l Ar language
+.Op Fl n
+.Op Fl sn
+.Op Fl t
+.Op Fl x
+.Ar name Ar ...
+.Sh DESCRIPTION
+.Nm Vgrind
+formats the program sources which are arguments
+in a nice style using
+.Xr troff 1
+Comments are placed in italics, keywords in bold face,
+and the name of the current function is listed down the margin of each
+page as it is encountered.
+.Pp
+.Nm Vgrind
+runs in two basic modes, filter mode (see the
+.Fl f
+option) or regular mode. In filter mode
+.Nm vgrind
+acts as a filter in a manner similar to
+.Xr tbl 1 .
+The standard input is passed directly to the standard output except
+for lines bracketed by the
+.Em troff-like
+macros:
+.Bl -tag -width Ds
+.It \&.vS
+starts processing
+.It \&.vE
+ends processing
+.El
+.Pp
+These lines are formatted as described above. The output from this
+filter can be passed to
+.Xr troff
+for output. There need be no particular ordering with
+.Xr eqn 1
+or
+.Xr tbl 1 .
+.Pp
+In regular mode
+.Nm vgrind
+accepts input files, processes them, and passes them to
+.Xr troff 1
+for output.
+.Pp
+In both modes
+.Nm vgrind
+passes any lines beginning with a decimal point without conversion.
+.Pp
+The options are:
+.Bl -tag -width Ar
+.It Fl
+forces input to be taken from standard input (default if
+.Fl f
+is specified )
+.It Fl W
+forces output to the (wide) Versatec printer rather than the (narrow)
+Varian
+.It Fl d Ar file
+specifies an alternate language definitions
+file (default is
+.Pa /usr/share/misc/vgrindefs )
+.It Fl f
+forces filter mode
+.It Fl h Ar header
+specifies a particular header to put on every output page (default is
+the file name)
+.It Fl l
+specifies the language to use. Currently known are
+.Tn PASCAL
+.Pq Fl l Ns Ar p ,
+.Tn MODEL
+.Pq Fl l Ns Ar m ,
+C
+.Pf ( Fl l Ns Ar c
+or the default),
+.Tn CSH
+.Pq Fl l Ns Ar csh ,
+.Tn SHELL
+.Pq Fl l Ns Ar sh ,
+.Tn RATFOR
+.Pq Fl l Ns Ar r ,
+.Tn MODULA2
+.Pq Fl l Ns Ar mod2 ,
+.Tn YACC
+.Pq Fl l Ns Ar yacc ,
+.Tn LISP
+.Pq Fl l Ns Ar isp ,
+and
+.Tn ICON
+.Pq Fl l Ns Ar I .
+.It Fl n
+forces no keyword bolding
+.It Fl s
+specifies a point size to use on output (exactly the same as the argument
+of a .ps)
+.It Fl t
+similar to the same option in
+.Xr troff
+causing formatted text to go to the standard output
+.It Fl x
+outputs the index file in a ``pretty'' format.
+The index file itself is produced whenever
+.Nm vgrind
+is run with a file called
+.Pa index
+in the current directory.
+The index of function
+definitions can then be run off by giving
+.Nm vgrind
+the
+.Fl x
+option and the file
+.Pa index
+as argument.
+.El
+.Sh FILES
+.Bl -tag -width /usr/share/misc/vgrindefsxx -compact
+.It Pa index
+file where source for index is created
+.It Pa /usr/share/tmac/tmac.vgrind
+macro package
+.It Pa /usr/libexec/vfontedpr
+preprocessor
+.It Pa /usr/share/misc/vgrindefs
+language descriptions
+.El
+.Sh SEE ALSO
+.Xr getcap 3 ,
+.Xr vgrindefs 5
+.Sh BUGS
+Vfontedpr assumes that a certain programming style is followed:
+.Pp
+For
+.Tn C
+\- function names can be preceded on a line only by spaces, tabs, or an
+asterisk. The parenthesized arguments must also be on the same line.
+.Pp
+For
+.Tn PASCAL
+\- function names need to appear on the same line as the keywords
+.Em function
+or
+.Em procedure .
+.Pp
+For
+.Tn MODEL
+\- function names need to appear on the same line as the keywords
+.Em is beginproc .
+.Pp
+If these conventions are not followed, the indexing and marginal function
+name comment mechanisms will fail.
+.Pp
+More generally, arbitrary formatting styles for programs mostly look bad.
+The use of spaces to align source code fails miserably; if you plan to
+.Nm vgrind
+your program you should use tabs. This is somewhat inevitable since the
+font used by
+.Nm vgrind
+is variable width.
+.Pp
+The mechanism of
+.Xr ctags 1
+in recognizing functions should be used here.
+.Pp
+Filter mode does not work in documents using the
+.Fl me
+or
+.Fl ms
+macros.
+(So what use is it anyway?)
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 3.0 .
diff --git a/usr.bin/vgrind/vgrind.sh b/usr.bin/vgrind/vgrind.sh
new file mode 100644
index 0000000..fc05461
--- /dev/null
+++ b/usr.bin/vgrind/vgrind.sh
@@ -0,0 +1,143 @@
+#!/bin/csh -f
+#
+# Copyright (c) 1980, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)vgrind.sh 8.1 (Berkeley) 6/6/93
+#
+
+set voptions=
+set options=
+set files=
+set f=''
+set head=""
+set vf=/usr/libexec/vfontedpr
+set tm=/usr/share/tmac
+top:
+if ($#argv > 0) then
+ switch ($1:q)
+
+ case -f:
+ set f='filter'
+ set options = "$options $1:q"
+ shift
+ goto top
+
+ case -t:
+ set voptions = "$voptions -t"
+ shift
+ goto top
+
+ case -o*:
+ set voptions="$voptions $1:q"
+ shift
+ goto top
+
+ case -W:
+ set voptions = "$voptions -W"
+ shift
+ goto top
+
+ case -d:
+ if ($#argv < 2) then
+ echo "vgrind: $1:q option must have argument"
+ goto done
+ else
+ set options = ($options $1:q $2)
+ shift
+ shift
+ goto top
+ endif
+
+ case -h:
+ if ($#argv < 2) then
+ echo "vgrind: $1:q option must have argument"
+ goto done
+ else
+ set head="$2"
+ shift
+ shift
+ goto top
+ endif
+
+ case -*:
+ set options = "$options $1:q"
+ shift
+ goto top
+
+ default:
+ set files = "$files $1:q"
+ shift
+ goto top
+ endsw
+endif
+if (-r index) then
+ echo > nindex
+ foreach i ($files)
+ # make up a sed delete command for filenames
+ # being careful about slashes.
+ echo "? $i ?d" | sed -e "s:/:\\/:g" -e "s:?:/:g" >> nindex
+ end
+ sed -f nindex index >xindex
+ if ($f == 'filter') then
+ if ("$head" != "") then
+ $vf $options -h "$head" $files | cat $tm/tmac.vgrind -
+ else
+ $vf $options $files | cat $tm/tmac.vgrind -
+ endif
+ else
+ if ("$head" != "") then
+ $vf $options -h "$head" $files | \
+ sh -c "psroff -rx1 $voptions -i -mvgrind 2>> xindex"
+ else
+ $vf $options $files | \
+ sh -c "psroff -rx1 $voptions -i -mvgrind 2>> xindex"
+ endif
+ endif
+ sort -df +0 -2 xindex >index
+ rm nindex xindex
+else
+ if ($f == 'filter') then
+ if ("$head" != "") then
+ $vf $options -h "$head" $files | cat $tm/tmac.vgrind -
+ else
+ $vf $options $files | cat $tm/tmac.vgrind -
+ endif
+ else
+ if ("$head" != "") then
+ $vf $options -h "$head" $files | psroff -i $voptions -mvgrind
+ else
+ $vf $options $files | psroff -i $voptions -mvgrind
+ endif
+ endif
+endif
+
+done:
diff --git a/usr.bin/vgrind/vgrindefs.5 b/usr.bin/vgrind/vgrindefs.5
new file mode 100644
index 0000000..4ac7522
--- /dev/null
+++ b/usr.bin/vgrind/vgrindefs.5
@@ -0,0 +1,158 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vgrindefs.5 8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt VGRINDEFS 5
+.Os BSD 4.2
+.Sh NAME
+.Nm vgrindefs
+.Nd language definition data base for
+.Xr vgrind 1
+.Sh SYNOPSIS
+.Nm vgrindefs
+.Sh DESCRIPTION
+The
+.Nm vgrindefs
+file
+contains all language definitions for
+.Xr vgrind 1 .
+The data base is
+very similar to
+.Xr termcap 5 .
+.Sh FIELDS
+The following table names and describes each field.
+.Pp
+.Bl -column Namexxx Tpexxx
+.Sy Name Type Description
+.It "pb str regular expression for start of a procedure"
+.It "bb str regular expression for start of a lexical block"
+.It "be str regular expression for the end of a lexical block"
+.It "cb str regular expression for the start of a comment"
+.It "ce str regular expression for the end of a comment"
+.It "sb str regular expression for the start of a string"
+.It "se str regular expression for the end of a string"
+.It "lb str regular expression for the start of a character constant"
+.It "le str regular expression for the end of a character constant"
+.It "tl bool present means procedures are only defined at the top lexical level"
+.It "oc bool present means upper and lower case are equivalent"
+.It "kw str a list of keywords separated by spaces"
+.El
+.Pp
+.Sh EXAMPLES
+The following entry, which describes the C language, is
+typical of a language entry.
+.Bd -literal
+C|c:\
+:pb=^\ed?*?\ed?\ep\ed?\e(\ea?\e):bb={:be=}:cb=/*:ce=*/:sb=":se=\ee":\e
+:lb=':le=\ee':tl:\e
+:kw=asm auto break case char continue default do double else enum\e
+extern float for fortran goto if int long register return short\e
+sizeof static struct switch typedef union unsigned while #define\e
+#else #endif #if #ifdef #ifndef #include #undef # define else endif\e
+if ifdef ifndef include undef:
+.Ed
+.Pp
+Note that the first field is just the language name (and any variants
+of it). Thus the C language could be specified to
+.Xr vgrind 1
+as "c" or "C".
+.Pp
+Entries may continue onto multiple lines by giving a \e as the last
+character of a line.
+Capabilities in
+.Nm vgrindefs
+are of two types:
+Boolean capabilities which indicate that the language has
+some particular feature
+and string
+capabilities which give a regular expression or
+keyword list.
+.Sh REGULAR EXPRESSIONS
+.Nm Vgrindefs
+uses regular expression which are very similar to those of
+.Xr ex 1
+and
+.Xr lex 1 .
+The characters `^', `$', `:' and `\e'
+are reserved characters and must be
+"quoted" with a preceding
+.Ql \e
+if they
+are to be included as normal characters.
+The metasymbols and their meanings are:
+.Bl -tag -width indent
+.It $
+the end of a line
+.It \&^
+the beginning of a line
+.It \ed
+a delimiter (space, tab, newline, start of line)
+.It \ea
+matches any string of symbols (like .* in lex)
+.It \ep
+matches any alphanumeric name. In a procedure definition (pb) the string
+that matches this symbol is used as the procedure name.
+.It ()
+grouping
+.It \&|
+alternation
+.It ?
+last item is optional
+.It \ee
+preceding any string means that the string will not match an
+input string if the input string is preceded by an escape character (\e).
+This is typically used for languages (like C) which can include the
+string delimiter in a string by escaping it.
+.El
+.Pp
+Unlike other regular expressions in the system, these match words
+and not characters. Hence something like "(tramp|steamer)flies?"
+would match "tramp", "steamer", "trampflies", or "steamerflies".
+.Sh KEYWORD LIST
+The keyword list is just a list of keywords in the language separated
+by spaces. If the "oc" boolean is specified, indicating that upper
+and lower case are equivalent, then all the keywords should be
+specified in lower case.
+.Sh FILES
+.Bl -tag -width /usr/share/misc/vgrindefs -compact
+.It Pa /usr/share/misc/vgrindefs
+File containing terminal descriptions.
+.El
+.Sh SEE ALSO
+.Xr vgrind 1 ,
+.Xr troff 1
+.Sh HISTORY
+The
+.Nm
+file format appeared in
+.Bx 4.2 .
diff --git a/usr.bin/vgrind/vgrindefs.c b/usr.bin/vgrind/vgrindefs.c
new file mode 100644
index 0000000..23f06bd
--- /dev/null
+++ b/usr.bin/vgrind/vgrindefs.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)vgrindefs.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#define BUFSIZ 1024
+#define MAXHOP 32 /* max number of tc= indirections */
+
+#include <ctype.h>
+/*
+ * grindcap - routines for dealing with the language definitions data base
+ * (code stolen almost totally from termcap)
+ *
+ * BUG: Should use a "last" pointer in tbuf, so that searching
+ * for capabilities alphabetically would not be a n**2/2
+ * process when large numbers of capabilities are given.
+ * Note: If we add a last pointer now we will screw up the
+ * tc capability. We really should compile termcap.
+ *
+ * Essentially all the work here is scanning and decoding escapes
+ * in string capabilities. We don't use stdio because the editor
+ * doesn't, and because living w/o it is not hard.
+ */
+
+static char *tbuf;
+static char *filename;
+static int hopcount; /* detect infinite loops in termcap, init 0 */
+char *tskip();
+char *tgetstr();
+char *tdecode();
+char *getenv();
+
+/*
+ * Get an entry for terminal name in buffer bp,
+ * from the termcap file. Parse is very rudimentary;
+ * we just notice escaped newlines.
+ */
+tgetent(bp, name, file)
+ char *bp, *name, *file;
+{
+ register char *cp;
+ register int c;
+ register int i = 0, cnt = 0;
+ char ibuf[BUFSIZ];
+ char *cp2;
+ int tf;
+
+ tbuf = bp;
+ tf = 0;
+ filename = file;
+ tf = open(filename, 0);
+ if (tf < 0)
+ return (-1);
+ for (;;) {
+ cp = bp;
+ for (;;) {
+ if (i == cnt) {
+ cnt = read(tf, ibuf, BUFSIZ);
+ if (cnt <= 0) {
+ close(tf);
+ return (0);
+ }
+ i = 0;
+ }
+ c = ibuf[i++];
+ if (c == '\n') {
+ if (cp > bp && cp[-1] == '\\'){
+ cp--;
+ continue;
+ }
+ break;
+ }
+ if (cp >= bp+BUFSIZ) {
+ write(2,"Vgrind entry too long\n", 23);
+ break;
+ } else
+ *cp++ = c;
+ }
+ *cp = 0;
+
+ /*
+ * The real work for the match.
+ */
+ if (tnamatch(name)) {
+ close(tf);
+ return(tnchktc());
+ }
+ }
+}
+
+/*
+ * tnchktc: check the last entry, see if it's tc=xxx. If so,
+ * recursively find xxx and append that entry (minus the names)
+ * to take the place of the tc=xxx entry. This allows termcap
+ * entries to say "like an HP2621 but doesn't turn on the labels".
+ * Note that this works because of the left to right scan.
+ */
+tnchktc()
+{
+ register char *p, *q;
+ char tcname[16]; /* name of similar terminal */
+ char tcbuf[BUFSIZ];
+ char *holdtbuf = tbuf;
+ int l;
+
+ p = tbuf + strlen(tbuf) - 2; /* before the last colon */
+ while (*--p != ':')
+ if (p<tbuf) {
+ write(2, "Bad vgrind entry\n", 18);
+ return (0);
+ }
+ p++;
+ /* p now points to beginning of last field */
+ if (p[0] != 't' || p[1] != 'c')
+ return(1);
+ strcpy(tcname,p+3);
+ q = tcname;
+ while (q && *q != ':')
+ q++;
+ *q = 0;
+ if (++hopcount > MAXHOP) {
+ write(2, "Infinite tc= loop\n", 18);
+ return (0);
+ }
+ if (tgetent(tcbuf, tcname, filename) != 1)
+ return(0);
+ for (q=tcbuf; *q != ':'; q++)
+ ;
+ l = p - holdtbuf + strlen(q);
+ if (l > BUFSIZ) {
+ write(2, "Vgrind entry too long\n", 23);
+ q[BUFSIZ - (p-tbuf)] = 0;
+ }
+ strcpy(p, q+1);
+ tbuf = holdtbuf;
+ return(1);
+}
+
+/*
+ * Tnamatch deals with name matching. The first field of the termcap
+ * entry is a sequence of names separated by |'s, so we compare
+ * against each such name. The normal : terminator after the last
+ * name (before the first field) stops us.
+ */
+tnamatch(np)
+ char *np;
+{
+ register char *Np, *Bp;
+
+ Bp = tbuf;
+ if (*Bp == '#')
+ return(0);
+ for (;;) {
+ for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
+ continue;
+ if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
+ return (1);
+ while (*Bp && *Bp != ':' && *Bp != '|')
+ Bp++;
+ if (*Bp == 0 || *Bp == ':')
+ return (0);
+ Bp++;
+ }
+}
+
+/*
+ * Skip to the next field. Notice that this is very dumb, not
+ * knowing about \: escapes or any such. If necessary, :'s can be put
+ * into the termcap file in octal.
+ */
+static char *
+tskip(bp)
+ register char *bp;
+{
+
+ while (*bp && *bp != ':')
+ bp++;
+ if (*bp == ':')
+ bp++;
+ return (bp);
+}
+
+/*
+ * Return the (numeric) option id.
+ * Numeric options look like
+ * li#80
+ * i.e. the option string is separated from the numeric value by
+ * a # character. If the option is not found we return -1.
+ * Note that we handle octal numbers beginning with 0.
+ */
+tgetnum(id)
+ char *id;
+{
+ register int i, base;
+ register char *bp = tbuf;
+
+ for (;;) {
+ bp = tskip(bp);
+ if (*bp == 0)
+ return (-1);
+ if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
+ continue;
+ if (*bp == '@')
+ return(-1);
+ if (*bp != '#')
+ continue;
+ bp++;
+ base = 10;
+ if (*bp == '0')
+ base = 8;
+ i = 0;
+ while (isdigit(*bp))
+ i *= base, i += *bp++ - '0';
+ return (i);
+ }
+}
+
+/*
+ * Handle a flag option.
+ * Flag options are given "naked", i.e. followed by a : or the end
+ * of the buffer. Return 1 if we find the option, or 0 if it is
+ * not given.
+ */
+tgetflag(id)
+ char *id;
+{
+ register char *bp = tbuf;
+
+ for (;;) {
+ bp = tskip(bp);
+ if (!*bp)
+ return (0);
+ if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
+ if (!*bp || *bp == ':')
+ return (1);
+ else if (*bp == '@')
+ return(0);
+ }
+ }
+}
+
+/*
+ * Get a string valued option.
+ * These are given as
+ * cl=^Z
+ * Much decoding is done on the strings, and the strings are
+ * placed in area, which is a ref parameter which is updated.
+ * No checking on area overflow.
+ */
+char *
+tgetstr(id, area)
+ char *id, **area;
+{
+ register char *bp = tbuf;
+
+ for (;;) {
+ bp = tskip(bp);
+ if (!*bp)
+ return (0);
+ if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
+ continue;
+ if (*bp == '@')
+ return(0);
+ if (*bp != '=')
+ continue;
+ bp++;
+ return (tdecode(bp, area));
+ }
+}
+
+/*
+ * Tdecode does the grung work to decode the
+ * string capability escapes.
+ */
+static char *
+tdecode(str, area)
+ register char *str;
+ char **area;
+{
+ register char *cp;
+ register int c;
+ int i;
+
+ cp = *area;
+ while (c = *str++) {
+ if (c == ':' && *(cp-1) != '\\')
+ break;
+ *cp++ = c;
+ }
+ *cp++ = 0;
+ str = *area;
+ *area = cp;
+ return (str);
+}
diff --git a/usr.bin/vgrind/vgrindefs.src b/usr.bin/vgrind/vgrindefs.src
new file mode 100644
index 0000000..91ef58f
--- /dev/null
+++ b/usr.bin/vgrind/vgrindefs.src
@@ -0,0 +1,146 @@
+# Copyright (c) 1987, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)vgrindefs.src 8.1 (Berkeley) 6/6/93
+#
+
+C|c:\
+ :pb=^\d?*?\d?\p\d?\(\a?\)(\d|{):bb={:be=}:cb=/*:ce=*/:sb=":se=\e":lb=':\
+ :le=\e':tl:\
+ :kw=asm auto break case char continue default do double else enum\
+ extern float for fortran goto if int long register return short\
+ sizeof static struct switch typedef union unsigned void while #define\
+ #else #endif #if #ifdef #ifndef #include #undef # define else endif\
+ if ifdef ifndef include undef:
+model|mod|m:\
+ :pb=^\d(space\d\p\drep)|(\p\dis|inline|public\dbeginproc):\
+ :bb=\dbeginproc|space|case\d:be=\dendproc|end\d|;:\
+ :cb=\$:ce=\$|$:sb=":se=":lb=':le=\a|$:\
+ :kw=abs and array beginproc boolean by case cdnl char copied dispose\
+ div do dynamic else elsif end endproc entry external FALSE false\
+ fi file for formal fortran global if iff ift\
+ in integer include inline is lbnd\
+ max min mod new NIL nil noresult not notin od of or procedure public\
+ read readln readonly record recursive rem rep repeat res\
+ result return set\
+ space string subscript such then TRUE true type ubnd union until\
+ varies while width:
+pascal|pasc|p:\
+ :pb=(^\d?procedure|function|program\d\p\d|\(|;|\:)|(=\d?record\d):\
+ :bb=\dcase|begin\d:be=\dend|forward\d|;:\
+ :cb={:ce=}:\
+ :ab=\(*:ae=*\):\
+ :sb=':se=':\
+ :kw=and array assert begin case const div do downto else end file for\
+ forward function goto if in label mod nil not of or packed procedure\
+ program record repeat set then to type until var while with oct hex\
+ external:
+ISP|isp|i:\
+ :cb=!:ce=!|$:oc:\
+ :kw=and begin decode define end eql eqv geq gtr if leave leq lss mod\
+ neq next not or otherwise repeat restart resume sr0 sr1 srd srr sl0 sl1\
+ sld slr tst xor:
+SH|sh:\
+ :bb={:be=}:cb=#:ce=$:sb=":se=\e":lb=':\
+ :le=\e':tl:\
+ :kw=break case cd continue do done \
+ elif else esac eval exec exit export \
+ fi for if in then while until \
+ read readonly set shift test trap umask wait:
+CSH|csh:\
+ :bb={:be=}:cb=#:ce=$:sb=":se=\e":lb=':\
+ :le=\e':tl:\
+ :kw=alias alloc break breaksw case cd chdir continue default\
+ echo else end endif endsw exec exit foreach \
+ glob goto history if logout nice nohup onintr repeat set\
+ setenv shift source switch then time \
+ while umask unalias unset wait while @ env \
+ argv child home ignoreeof noclobber noglob \
+ nomatch path prompt shell status verbose :
+ldl|LDL:\
+ :pb=^\p\::bb=\::be=;:cb=/*:ce=*/:sb=":se=\e":\
+ :kw=constant functions grammar reswords tokens add1 addste\
+ car cdr check colno cond cons copy defun divide empty enter\
+ eq equal findattr firstchild ge getattr getfield gt hash label\
+ lambda lastchild le leftsibling lookone lookup lt minus name ne\
+ newnode nextcom nil null parent plus precnl prevcom prog progn\
+ quote reglob return rightsibling self set setattr setfield setq\
+ stjoin sub1 t times tnull tokno ttype:
+Icon|icon|I:\
+ :pb=^\d?procedure\d\p\d?\(\a?\):\
+ :bb=(^\d?procedure\d\p\d?\(\a?\))|{:be=}|(^\d?end\d?$):\
+ :cb=#:ce=$:\
+ :sb=":se=\e":lb=':le=\e':tl:\
+ :kw=break by case create default do dynamic else end every external\
+ fail global if initial local next not of procedure record\
+ repeat return static suspend then to until using while\
+ &ascii &clock &cset &date &dateline &errout &fail &host &input\
+ &lcase &level &main &null &output &pos &random &source &subject\
+ &time &trace &ucase &version:
+ratfor|rat|r:\
+ :pb=(subroutine|function)\d\p\d?\(\a?\):\
+ :bb=(subroutine|function)\d\p\d?\(\a?\):be=^\d?end:\
+ :cb=#:ce=$:\
+ :sb=":se=\e":lb=':le=\e':oc:\
+ :kw=DRETURN DRIVER arith break case character default define do\
+ else elsedef enddef filedes for function goto if ifdef ifelse\
+ ifnotdef include incr integer linepointer next opeq pointer\
+ real repeat return select string subroutine substr until:
+modula2|mod2|m2:\
+ :pb=(^\d?(procedure|function|module)\d\p\d|\(|;|\:):\
+ :bb=\d(begin|case|for|if|loop|record|repeat|while|with)\d:\
+ :be=\dend|;:\
+ :cb={:ce=}:\
+ :ab=\(*:ae=*\):\
+ :sb=":se=":\
+ :oc:\
+ :kw=and array begin by case const\
+ definition div do else elsif end exit export\
+ for from if implementation import in\
+ loop mod module not of or pointer procedure qualified\
+ record repeat return set then to type\
+ until var while with:
+yacc|Yacc|y:\
+ :cb=/*:ce=*/:sb=":se=\e":lb=':le=\e':tl:\
+ :kw=%{ %} %% %union %token %type\
+ #else #endif #if #ifdef #ifndef #include #undef # define else endif\
+ if ifdef ifndef include undef:
+C++|c++:\
+ :pb=^\d?*?\d?\p\d?\(\a?\)(\d|{):bb={:be=}:cb=/*:ce=*/:ab=//:\
+ :ae=$:sb=":se=\e":lb=':\
+ :le=\e':tl:\
+ :kw=asm auto break case char continue default do double else enum\
+ extern float for fortran goto if int long register return short\
+ sizeof static struct switch typedef union unsigned while void #define\
+ #else #endif #if #ifdef #ifndef #include #undef # define endif\
+ ifdef ifndef include undef defined\
+ class const delete friend inline new operator overload private\
+ protected public virtual:
OpenPOWER on IntegriCloud