* 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 */
/* regular expression routines */
char *expmatch(); /* match a string to an expression */
char *STRNCMP(); /* a different kindof strncmp */
char *convexp(); /* convert expression to internal form */
boolean incomm
; /* in a comment of the primary type */
boolean instr
; /* in a string constant */
boolean inchr
; /* in a string constant */
boolean nokeyw
= FALSE
; /* no keywords being flagged */
boolean index
= FALSE
; /* form an index */
boolean filter
= FALSE
; /* act as a filter (like eqn) */
boolean pass
= FALSE
; /* when acting as a filter, pass indicates
* whether we are currently processing
boolean prccont
; /* continue last procedure */
int comtype
; /* type of comment */
int psptr
; /* the stack index of the current procedure */
char pstack
[PSMAX
][PNAMELEN
+1]; /* the procedure name stack */
int plstack
[PSMAX
]; /* the procedure nesting level stack */
int blklevel
; /* current nesting level */
char *defsfile
= "/usr/lib/vgrindefs"; /* name of language definitions file */
* The language specific globals
char *language
= "c"; /* the language indicator */
char *l_keywds
[BUFSIZ
/2]; /* keyword table address */
char *l_prcbeg
; /* regular expr for procedure begin */
char *l_combeg
; /* string introducing a comment */
char *l_comend
; /* string ending a comment */
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_strbeg
; /* delimiter for string constant */
char *l_strend
; /* delimiter for string constant */
char *l_chrbeg
; /* delimiter for character constant */
char *l_chrend
; /* delimiter for character constant */
char l_escape
; /* character used to escape characters */
boolean l_toplex
; /* procedures only defined at top lex level */
* global variables also used by expmatch
boolean _escaped
; /* if last character was an escape */
char *_start
; /* start of the current string */
boolean l_onecase
; /* upper and lower case are equivalent */
#define ps(x) printf("%s", x)
char strings
[2 * BUFSIZ
];
if (!strcmp(argv
[0], "-h")) {
printf("'ds =H %s\n", argv
[1]);
/* act as a filter like eqn */
if (!strcmp(argv
[0], "-f")) {
/* take input from the standard place */
if (!strcmp(argv
[0], "-")) {
if (!strcmp(argv
[0], "-x")) {
/* indicate no keywords */
if (!strcmp(argv
[0], "-n")) {
/* specify the font size */
if (!strncmp(argv
[0], "-s", 2)) {
i
= i
* 10 + (*cp
++ - '0');
printf("'ps %d\n'vs %d\n", i
, i
+1);
/* specify the language */
if (!strncmp(argv
[0], "-l", 2)) {
/* specify the language description file */
if (!strncmp(argv
[0], "-d", 2)) {
/* open the file for input */
if (freopen(argv
[0], "r", stdin
) == NULL
) {
printf("'ta 4i 4.25i 5.5iR\n'in .5i\n");
* get the language definition from the defs file
i
= tgetent (defs
, language
, defsfile
);
fprintf (stderr
, "no entry for language %s\n", language
);
fprintf (stderr
, "cannot find vgrindefs file %s\n", defsfile
);
if (tgetstr ("kw", &cp
) == NIL
)
while (*cp
== ' ' || *cp
=='\t')
while (*cp
!= ' ' && *cp
!= '\t' && *cp
)
l_prcbeg
= convexp (tgetstr ("pb", &cp
));
l_combeg
= convexp (tgetstr ("cb", &cp
));
l_comend
= convexp (tgetstr ("ce", &cp
));
l_acmbeg
= convexp (tgetstr ("ab", &cp
));
l_acmend
= convexp (tgetstr ("ae", &cp
));
l_strbeg
= convexp (tgetstr ("sb", &cp
));
l_strend
= convexp (tgetstr ("se", &cp
));
l_blkbeg
= convexp (tgetstr ("bb", &cp
));
l_blkend
= convexp (tgetstr ("be", &cp
));
l_chrbeg
= convexp (tgetstr ("lb", &cp
));
l_chrend
= convexp (tgetstr ("le", &cp
));
l_onecase
= tgetflag ("oc");
l_toplex
= tgetflag ("tl");
/* initialize the program */
for (psptr
=0; psptr
<PSMAX
; psptr
++) {
printf(".ds =F %s\n", fname
);
fstat(fileno(stdin
), &stbuf
);
cp
= ctime(&stbuf
.st_mtime
);
printf(".ds =M %s %s\n", cp
+4, cp
+20);
while (fgets(buf
, sizeof buf
, stdin
) != NULL
) {
if (!strncmp (buf
+1, "vS", 2))
if (!strncmp (buf
+1, "vE", 2))
if (prccont
&& (psptr
>= 0)) {
printf ("com %o str %o chr %o ptr %d\n", incomm
, instr
, inchr
, psptr
);
#define isidchr(c) (isalnum(c) || (c) == '_')
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 */
if (nokeyw
|| incomm
|| instr
)
strncpy (pstack
[psptr
], pname
, PNAMELEN
);
pstack
[psptr
][PNAMELEN
] = NULL
;
plstack
[psptr
] = blklevel
;
/* 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
< strptr
|| strptr
== NIL
)
&& (comptr
< acmptr
|| acmptr
== NIL
)
&& (comptr
< chrptr
|| chrptr
== NIL
)
&& (comptr
< blksptr
|| blksptr
== NIL
)
&& (comptr
< blkeptr
|| blkeptr
== NIL
)) {
putKcp (s
, comptr
-1, FALSE
);
/* start of a comment? */
if ((acmptr
< strptr
|| strptr
== NIL
)
&& (acmptr
< chrptr
|| chrptr
== NIL
)
&& (acmptr
< blksptr
|| blksptr
== NIL
)
&& (acmptr
< blkeptr
|| blkeptr
== NIL
)) {
putKcp (s
, acmptr
-1, FALSE
);
if ((strptr
< chrptr
|| chrptr
== NIL
)
&& (strptr
< blksptr
|| blksptr
== NIL
)
&& (strptr
< blkeptr
|| blkeptr
== NIL
)) {
putKcp (s
, strptr
-1, FALSE
);
/* start of a character string? */
if ((chrptr
< blksptr
|| blksptr
== NIL
)
&& (chrptr
< blkeptr
|| blkeptr
== NIL
)) {
putKcp (s
, chrptr
-1, FALSE
);
/* end of a lexical block */
if (blkeptr
< blksptr
|| blksptr
== NIL
) {
putKcp (s
, blkeptr
- 1, FALSE
);
if (psptr
>= 0 && plstack
[psptr
] >= blklevel
) {
/* end of current procedure */
blklevel
= plstack
[psptr
];
/* see if we should print the last proc name */
/* start of a lexical block */
putKcp (s
, blksptr
- 1, FALSE
);
/* check for end of comment */
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
);
putKcp (s
, acmptr
-1, TRUE
);
putKcp (s
, s
+ strlen(s
) -1);
/* check for end of string */
if ((strptr
= expmatch (s
, l_strend
, dummy
)) != NIL
) {
putKcp (s
, strptr
-1, TRUE
);
putKcp (s
, s
+strlen(s
)-1, TRUE
);
/* check for end of character string */
if ((chrptr
= expmatch (s
, l_chrend
, dummy
)) != NIL
) {
putKcp (s
, chrptr
-1, TRUE
);
putKcp (s
, s
+strlen(s
)-1, TRUE
);
putKcp (s
, s
+ strlen(s
) -1, FALSE
);
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 */
if (*start
== ' ' || *start
== '\t') {
while (*start
== ' ' || *start
== '\t')
/* take care of nice tab stops */
i
= tabs(_start
, start
) - margin
/ 8;
printf("\\h'|%dn'", i
* 10 + 1 - margin
% 8);
if ((*start
== '#' || isidchr(*start
))
&& (start
== _start
|| !isidchr(start
[-1]))) {
return (width(s
, os
) / 8);
ps("\\fI\\h'\\w' 'u-\\w'/'u'/\\fP");
* look for a process beginning on this line
if (!l_toplex
|| blklevel
== 0)
if (expmatch (s
, l_prcbeg
, pname
) != NIL
) {
/* iskw - check to see if the next word is a keyword
register char **ss
= l_keywds
;
while (++cp
, isidchr(*cp
))
if (!STRNCMP(s
,cp
,i
) && !isidchr(cp
[i
]))