xref: /csrg-svn/usr.bin/vgrind/vfontedpr.c (revision 1878)
11841Sroot #include <ctype.h>
21841Sroot #include <stdio.h>
31841Sroot #include <sys/types.h>
41841Sroot #include <sys/stat.h>
51841Sroot 
61841Sroot /*
71841Sroot  * Vfontedpr.
81841Sroot  *
91841Sroot  * Bill Joy, Apr. 1979.
10*1878Sroot  * (made somewhat table driven - Dave Presotto 11/17/80)
111862Sroot  *
12*1878Sroot  * To add a new language:
13*1878Sroot  *	1) add a new keyword table
14*1878Sroot  *	2) add a new entry to "struct langdef ld[]" to
15*1878Sroot  *	   describe comments, strings, etc.
16*1878Sroot  *	3) add two routines to recognize start and end of
17*1878Sroot  *	   procedures
18*1878Sroot  *
191841Sroot  */
201862Sroot #define NOLANG -1		/* indicates no language chosen */
211862Sroot #define C 0
221862Sroot #define PASCAL 1
231862Sroot #define MODEL 2
241862Sroot #define NLANG 3			/* total number of languages */
251862Sroot 
261862Sroot #define STRLEN 10		/* length of strings introducing things */
271862Sroot #define PNAMELEN 40		/* length of a function/procedure name */
281862Sroot 
291862Sroot /* routines used by the different languages */
301862Sroot 
311862Sroot int	cprbegin();
321862Sroot int	cprend();
33*1878Sroot int	iprbegin();
34*1878Sroot int	iprend();
351862Sroot int	pprbegin();
361862Sroot int	pprend();
371862Sroot int	mprbegin();
381862Sroot int	mprend();
391862Sroot 
401862Sroot /* keywords for the model language */
411862Sroot 
421862Sroot char	*mkw[] = {
431862Sroot 	"abs",
441862Sroot 	"and",
451862Sroot 	"array",
461862Sroot 	"beginproc",
471862Sroot 	"boolean",
481862Sroot 	"by",
491862Sroot 	"case",
501862Sroot 	"cdnl",
511862Sroot 	"char",
521862Sroot 	"copied",
531862Sroot 	"dispose",
541862Sroot 	"div",
551862Sroot 	"do",
561862Sroot 	"dynamic",
571862Sroot 	"else",
581862Sroot 	"elsif",
591862Sroot 	"end",
601862Sroot 	"endproc",
611862Sroot 	"entry",
621862Sroot 	"external",
631862Sroot 	"f",
641862Sroot 	"FALSE",
651862Sroot 	"false",
661862Sroot 	"fi",
671862Sroot 	"file",
681862Sroot 	"for",
691862Sroot 	"formal",
701862Sroot 	"fortran",
711862Sroot 	"global",
721862Sroot 	"if",
731862Sroot 	"in",
741862Sroot 	"include",
751862Sroot 	"inline",
761862Sroot 	"is",
771862Sroot 	"lbnd",
781862Sroot 	"max",
791862Sroot 	"min",
801862Sroot 	"mod",
811862Sroot 	"new",
821862Sroot 	"NIL",
831862Sroot 	"nil",
841862Sroot 	"noresult",
851862Sroot 	"not",
861862Sroot 	"notin",
871862Sroot 	"od",
881862Sroot 	"of",
891862Sroot 	"or",
901862Sroot 	"procedure",
911862Sroot 	"public",
921862Sroot 	"read",
931862Sroot 	"readln",
941862Sroot 	"readonly",
951862Sroot 	"record",
961862Sroot 	"recursive",
971862Sroot 	"rem",
981862Sroot 	"rep",
991862Sroot 	"repeat",
1001862Sroot 	"result",
1011862Sroot 	"return",
1021862Sroot 	"set",
1031862Sroot 	"space",
1041862Sroot 	"string",
1051862Sroot 	"subscript",
1061862Sroot 	"such",
1071862Sroot 	"then",
1081862Sroot 	"TRUE",
1091862Sroot 	"true",
1101862Sroot 	"type",
1111862Sroot 	"ubnd",
1121862Sroot 	"union",
1131862Sroot 	"until",
1141862Sroot 	"varies",
1151862Sroot 	"while",
1161862Sroot 	"width",
1171862Sroot 	"write",
1181862Sroot 	"writeln",
1191862Sroot 	0,
1201862Sroot };
1211862Sroot 
1221862Sroot /* keywords for the pascal language */
1231862Sroot 
1241862Sroot char	*pkw[] = {
1251862Sroot 	"and",
1261862Sroot 	"array",
1271862Sroot 	"assert",
1281862Sroot 	"begin",
1291862Sroot 	"case",
1301862Sroot 	"const",
1311862Sroot 	"div",
1321862Sroot 	"do",
1331862Sroot 	"downto",
1341862Sroot 	"else",
1351862Sroot 	"end",
1361862Sroot 	"file",
1371862Sroot 	"for",
1381862Sroot 	"forward",
1391862Sroot 	"function",
1401862Sroot 	"goto",
1411862Sroot 	"if",
1421862Sroot 	"in",
1431862Sroot 	"label",
1441862Sroot 	"mod",
1451862Sroot 	"nil",
1461862Sroot 	"not",
1471862Sroot 	"of",
1481862Sroot 	"or",
1491862Sroot 	"packed",
1501862Sroot 	"procedure",
1511862Sroot 	"program",
1521862Sroot 	"record",
1531862Sroot 	"repeat",
1541862Sroot 	"set",
1551862Sroot 	"then",
1561862Sroot 	"to",
1571862Sroot 	"type",
1581862Sroot 	"until",
1591862Sroot 	"var",
1601862Sroot 	"while",
1611862Sroot 	"with",
1621862Sroot 	"oct",
1631862Sroot 	"hex",
1641862Sroot 	"external",
1651862Sroot 	0,
1661862Sroot };
1671862Sroot 
1681862Sroot /* keywords for the C language */
1691862Sroot 
1701862Sroot char	*ckw[] = {
1711862Sroot 	"asm",
1721862Sroot 	"auto",
1731862Sroot 	"break",
1741862Sroot 	"case",
1751862Sroot 	"char",
1761862Sroot 	"continue",
1771862Sroot 	"default",
1781862Sroot 	"do",
1791862Sroot 	"double",
1801862Sroot 	"else",
1811862Sroot 	"enum",
1821862Sroot 	"extern",
1831862Sroot 	"float",
1841862Sroot 	"for",
1851862Sroot 	"fortran",
1861862Sroot 	"goto",
1871862Sroot 	"if",
1881862Sroot 	"int",
1891862Sroot 	"long",
1901862Sroot 	"register",
1911862Sroot 	"return",
1921862Sroot 	"short",
1931862Sroot 	"sizeof",
1941862Sroot 	"static",
1951862Sroot 	"struct",
1961862Sroot 	"switch",
1971862Sroot 	"typedef",
1981862Sroot 	"union",
1991862Sroot 	"unsigned",
2001862Sroot 	"while",
2011862Sroot 	"#define",
2021862Sroot 	"#else",
2031862Sroot 	"#endif",
2041862Sroot 	"#if",
2051862Sroot 	"#ifdef",
2061862Sroot 	"#ifndef",
2071862Sroot 	"#include",
2081862Sroot 	"#undef",
2091862Sroot 	"#",
2101862Sroot 	"define",
2111862Sroot 	"else",
2121862Sroot 	"endif",
2131862Sroot 	"if",
2141862Sroot 	"ifdef",
2151862Sroot 	"ifndef",
2161862Sroot 	"include",
2171862Sroot 	"undef",
2181862Sroot 	0,
2191862Sroot };
2201862Sroot 
221*1878Sroot /* keywords for the ISP language */
222*1878Sroot 
223*1878Sroot char	*ikw[] = {
224*1878Sroot 	"and",
225*1878Sroot 	"begin",
226*1878Sroot 	"decode",
227*1878Sroot 	"define",
228*1878Sroot 	"end",
229*1878Sroot 	"eql",
230*1878Sroot 	"eqv",
231*1878Sroot 	"geq",
232*1878Sroot 	"gtr",
233*1878Sroot 	"if",
234*1878Sroot 	"leave",
235*1878Sroot 	"leq",
236*1878Sroot 	"lss",
237*1878Sroot 	"mod",
238*1878Sroot 	"neq",
239*1878Sroot 	"next",
240*1878Sroot 	"not",
241*1878Sroot 	"or",
242*1878Sroot 	"otherwise",
243*1878Sroot 	"repeat",
244*1878Sroot 	"restart",
245*1878Sroot 	"resume",
246*1878Sroot 	"sr0",
247*1878Sroot 	"sr1",
248*1878Sroot 	"srd",
249*1878Sroot 	"srr",
250*1878Sroot 	"sl0",
251*1878Sroot 	"sl1",
252*1878Sroot 	"sld",
253*1878Sroot 	"slr",
254*1878Sroot 	"tst",
255*1878Sroot 	"xor",
256*1878Sroot 	0,
257*1878Sroot };
258*1878Sroot 
2591862Sroot /*
2601862Sroot  * the following structure defines a language
2611862Sroot  */
2621862Sroot 
2631862Sroot struct langdef {
2641862Sroot 	char	*option;	/* its option switch */
2651862Sroot 	char	**kwd;		/* address of its keyword table */
2661862Sroot 	int	(*isproc)();	/* test for procedure begin */
2671862Sroot 	int	(*ispend)();	/* test for procedure end */
2681862Sroot 	char	*combeg;	/* string introducing a comment */
2691862Sroot 	char	*comend;	/* string ending a comment */
2701862Sroot 	char	*comout;	/* string output in place of combeg string */
271*1878Sroot 	char	*acmbeg;	/* alternate comment start */
272*1878Sroot 	char	*acmend;	/* alternate comment end */
273*1878Sroot 	char	*acmout;	/* alternate comment start preface */
2741862Sroot 	char    strdel;		/* delimiter for string constant */
2751862Sroot 	char	chrdel;		/* delimiter for character constant */
2761862Sroot 	int	onelncom;	/* comments do not continue on next line */
2771862Sroot 	int	onelnstr;	/* string constants do not continue on next */
278*1878Sroot 	int	onecase;	/* upper and lower case are equivalent */
2791862Sroot };
2801862Sroot 
2811862Sroot struct langdef ld[] = {
2821862Sroot 	/* the C language */
2831862Sroot 	"-c",
284*1878Sroot 	ckw,		/* kwd */
285*1878Sroot 	cprbegin,	/* isproc */
286*1878Sroot 	cprend,		/* ispend */
287*1878Sroot 	"/*",		/* combeg */
288*1878Sroot 	"*/",		/* comend */
289*1878Sroot 	"\\*(/*",	/* comout */
290*1878Sroot 	0,		/* acmbeg */
291*1878Sroot 	0,		/* acmend */
292*1878Sroot 	0,		/* acmout */
293*1878Sroot 	'"',		/* strdel */
294*1878Sroot 	'\'',		/* chrdel */
295*1878Sroot 	0,		/* onelncom */
296*1878Sroot 	0,		/* onelnstr */
297*1878Sroot 	0,		/* onecase */
2981862Sroot 
299*1878Sroot 	/* the ISP language */
300*1878Sroot 	"-i",
301*1878Sroot 	ikw,		/* kwd */
302*1878Sroot 	iprbegin,	/* isproc */
303*1878Sroot 	iprend,		/* ispend */
304*1878Sroot 	"!",		/* combeg */
305*1878Sroot 	0,		/* comend */
306*1878Sroot 	"!",		/* comout */
307*1878Sroot 	0,		/* acmbeg */
308*1878Sroot 	0,		/* acmend */
309*1878Sroot 	0,		/* acmout */
310*1878Sroot 	0,		/* strdel */
311*1878Sroot 	0,		/* chrdel */
312*1878Sroot 	1,		/* onelncom */
313*1878Sroot 	1,		/* onelnstr */
314*1878Sroot 	1,		/* onecase */
315*1878Sroot 
3161862Sroot 	/* the pascal language */
3171862Sroot 	"-p",
318*1878Sroot 	pkw,		/* kwd */
319*1878Sroot 	pprbegin,	/* isproc */
320*1878Sroot 	pprend,		/* ispend */
321*1878Sroot 	"{",		/* combeg */
322*1878Sroot 	"}",		/* comend */
323*1878Sroot 	"{",		/* comout */
324*1878Sroot 	"(*",		/* acmbeg */
325*1878Sroot 	"*)",		/* acmend */
326*1878Sroot 	"(*",		/* acmout */
327*1878Sroot 	'\'',		/* strdel */
328*1878Sroot 	0,		/* chrdel */
329*1878Sroot 	0,		/* onelncom */
330*1878Sroot 	0,		/* onelnstr */
331*1878Sroot 	0,		/* onecase */
3321862Sroot 
3331862Sroot 	/* the model language */
3341862Sroot 	"-m",
335*1878Sroot 	mkw,		/* kwd */
336*1878Sroot 	mprbegin,	/* isproc */
337*1878Sroot 	mprend,		/* ispend */
338*1878Sroot 	"$",		/* combeg */
339*1878Sroot 	"$",		/* comend */
340*1878Sroot 	"$",		/* comout */
341*1878Sroot 	0,		/* acmbeg */
342*1878Sroot 	0,		/* acmend */
343*1878Sroot 	0,		/* acmout */
344*1878Sroot 	'"',		/* strdel */
345*1878Sroot 	'\'',		/* chrdel */
346*1878Sroot 	1,		/* onelncom */
347*1878Sroot 	0,		/* onelnstr */
348*1878Sroot 	0,		/* onecase */
3491862Sroot };
3501862Sroot 
3511841Sroot char	*ctime();
352*1878Sroot int	incomm;			/* in a comment of the primary type */
353*1878Sroot int	inacomm;		/* in the alternate type of comment */
354*1878Sroot int	instr;			/* in a string constant */
3551841Sroot int	nokeyw;
3561841Sroot int	index;
3571841Sroot int	margin;
358*1878Sroot 
3591862Sroot char	*comcol;		/* character position comment starts in */
3601862Sroot int	language = NOLANG;	/* the language indicator */
3611862Sroot char	**keywds;		/* keyword table address */
3621862Sroot int	(*isprbeg)();		/* test for beginning of procedure */
3631862Sroot int	(*isprend)();		/* test for end of procedure */
3641862Sroot char	*cstart;		/* start of comment string */
3651862Sroot char	*cstop;			/* end of comment string */
3661862Sroot char	*cout;			/* string to substitute for cstart */
3671862Sroot int	lcstart;		/* length of comment string starter */
3681862Sroot int	lcstop;			/* length of comment string terminator */
369*1878Sroot char	*acstart;		/* start of comment string */
370*1878Sroot char	*acstop;		/* end of comment string */
371*1878Sroot char	*acout;			/* string to substitute for cstart */
372*1878Sroot int	lacstart;		/* length of comment string starter */
373*1878Sroot int	lacstop;		/* length of comment string terminator */
3741862Sroot char	sdelim;			/* string constant delimiter */
3751862Sroot char	cdelim;			/* character constant delimiter */
3761862Sroot int	com1line;		/* one line comments */
3771862Sroot int	str1line;		/* one line strings */
378*1878Sroot int	upeqlow;		/* upper and lower case equivalent */
3791862Sroot char	pname[PNAMELEN];
3801841Sroot 
3811862Sroot #define	ps(x)	printf("%s", x)
3821862Sroot 
3831841Sroot main(argc, argv)
3841841Sroot 	int argc;
3851841Sroot 	char *argv[];
3861841Sroot {
3871841Sroot 	int lineno;
3881841Sroot 	char *fname = "";
3891841Sroot 	struct stat stbuf;
3901841Sroot 	char buf[BUFSIZ];
3911841Sroot 	int needbp = 0;
3921841Sroot 
3931841Sroot 	argc--, argv++;
3941841Sroot 	do {
3951841Sroot 		char *cp;
3961862Sroot 		int i;
3971841Sroot 
3981841Sroot 		if (argc > 0) {
3991841Sroot 			if (!strcmp(argv[0], "-h")) {
4001841Sroot 				if (argc == 1) {
4011841Sroot 					printf("'ds =H\n");
4021841Sroot 					argc = 0;
4031841Sroot 					goto rest;
4041841Sroot 				}
4051841Sroot 				printf("'ds =H %s\n", argv[1]);
4061841Sroot 				argc -= 2;
4071841Sroot 				argv += 2;
4081841Sroot 				if (argc > 0)
4091841Sroot 					continue;
4101841Sroot 				goto rest;
4111841Sroot 			}
4121841Sroot 			if (!strcmp(argv[0], "-x")) {
4131841Sroot 				index++;
4141841Sroot 				argv[0] = "-n";
4151841Sroot 			}
4161841Sroot 			if (!strcmp(argv[0], "-n")) {
4171841Sroot 				nokeyw++;
4181841Sroot 				argc--, argv++;
4191841Sroot 				continue;
4201841Sroot 			}
421*1878Sroot 			if (!strncmp(argv[0], "-s", 2)) {
422*1878Sroot 				i = 0;
423*1878Sroot 				cp = argv[0] + 2;
424*1878Sroot 				while (*cp)
425*1878Sroot 					i = i * 10 + (*cp++ - '0');
426*1878Sroot 				printf("'ps %d\n'vs %d\n", i, i+1);
427*1878Sroot 				argc--, argv++;
428*1878Sroot 				continue;
429*1878Sroot 			}
4301862Sroot 			for (i = 0; i < NLANG; i++)
4311862Sroot 				if (!strcmp(argv[0], ld[i].option)) {
4321862Sroot 					language = i;
4331862Sroot 					break;
4341862Sroot 				}
4351862Sroot 			if (i != NLANG) {
4361862Sroot 				argc--, argv++;
4371862Sroot 				continue;
4381862Sroot 			}
4391841Sroot 			if (freopen(argv[0], "r", stdin) == NULL) {
4401841Sroot 				perror(argv[0]);
4411841Sroot 				exit(1);
4421841Sroot 			}
4431841Sroot 			if (index)
4441841Sroot 				printf("'ta 4i 4.25i 5.5iR\n'in .5i\n");
4451841Sroot 			fname = argv[0];
4461841Sroot 			argc--, argv++;
4471841Sroot 		}
4481841Sroot rest:
4491862Sroot 		if (language == NOLANG)
4501862Sroot 			language = C;		/* C is the default */
4511862Sroot 
4521862Sroot 		/* initialize for the appropriate language */
453*1878Sroot 		/* This is done because subscripting is too */
454*1878Sroot 		/* damned slow to be done every reference */
4551862Sroot 
4561862Sroot 		keywds = ld[language].kwd;
4571862Sroot 		isprbeg = ld[language].isproc;
4581862Sroot 		isprend = ld[language].ispend;
459*1878Sroot 
4601862Sroot 		cstart = ld[language].combeg;
4611862Sroot 		cstop = ld[language].comend;
4621862Sroot 		cout = ld[language].comout;
4631862Sroot 		lcstart = strlen (cstart);
4641862Sroot 		lcstop = strlen (cstop);
465*1878Sroot 
466*1878Sroot 		acstart = ld[language].acmbeg;
467*1878Sroot 		acstop = ld[language].acmend;
468*1878Sroot 		acout = ld[language].acmout;
469*1878Sroot 		lacstart = strlen (acstart);
470*1878Sroot 		lacstop = strlen (acstop);
471*1878Sroot 
4721862Sroot 		sdelim = ld[language].strdel;
4731862Sroot 		cdelim = ld[language].chrdel;
4741862Sroot 		com1line = ld[language].onelncom;
4751862Sroot 		str1line = ld[language].onelnstr;
476*1878Sroot 		upeqlow = ld[language].onecase;
4771862Sroot 		pname[0] = 0;
4781862Sroot 
4791862Sroot 		/* initialize the program */
4801862Sroot 
4811841Sroot 		incomm = 0;
482*1878Sroot 		inacomm = 0;
4831841Sroot 		instr = 0;
484*1878Sroot 		ps("'-F\n");
4851841Sroot 		printf(".ds =F %s\n", fname);
4861841Sroot 		fstat(fileno(stdin), &stbuf);
4871841Sroot 		cp = ctime(&stbuf.st_mtime);
4881841Sroot 		cp[16] = '\0';
4891841Sroot 		cp[24] = '\0';
4901841Sroot 		printf(".ds =M %s %s\n", cp+4, cp+20);
4911841Sroot 		if (needbp) {
4921841Sroot 			needbp = 0;
4931841Sroot 			printf(".()\n");
4941841Sroot 			printf(".bp\n");
4951841Sroot 		}
4961841Sroot 		while (fgets(buf, sizeof buf, stdin) != NULL) {
497*1878Sroot 			if (buf[0] == '\f') {
4981841Sroot 				printf(".bp\n");
4991841Sroot 				continue;
5001841Sroot 			}
501*1878Sroot 			if (com1line && (incomm || inacomm)) {
5021862Sroot 				incomm = 0;
503*1878Sroot 				inacomm = 0;
5041862Sroot 				ps("\\c\n'-C\n");
5051862Sroot 			}
5061862Sroot 			if (str1line)
5071862Sroot 				instr = 0;
5081862Sroot 			comcol = NULL;
5091841Sroot 			putScp(buf);
5101841Sroot 			if (buf[strlen(buf) - 2] != '\\')
5111841Sroot 				instr = 0;
5121841Sroot 			margin = 0;
5131841Sroot 		}
5141841Sroot 		needbp = 1;
5151841Sroot 	} while (argc > 0);
5161841Sroot 	exit(0);
5171841Sroot }
5181841Sroot 
5191841Sroot #define isidchr(c) (isalnum(c) || (c) == '_')
5201841Sroot 
5211841Sroot putScp(os)
5221841Sroot 	char *os;
5231841Sroot {
5241841Sroot 	register char *s = os;
5251841Sroot 	register int i;
5261841Sroot 	int xfld = 0;
5271841Sroot 
528*1878Sroot 	if (nokeyw || incomm || inacomm || instr)
5291841Sroot 		goto skip;
5301862Sroot 	if ((*isprbeg)(s)) {
5311841Sroot 		ps("'FN ");
5321862Sroot 		ps(pname);
5331841Sroot 		ps("\n");
5341862Sroot 	} else if ((*isprend)(s))
5351841Sroot 		ps("'-F\n");
5361841Sroot skip:
5371841Sroot 	while (*s) {
5381841Sroot 		if (index) {
5391841Sroot 			if (*s == ' ' || *s == '\t') {
5401841Sroot 				if (xfld == 0)
5411841Sroot 					printf("");
5421841Sroot 				printf("\t");
5431841Sroot 				xfld = 1;
5441841Sroot 				while (*s == ' ' || *s == '\t')
5451841Sroot 					s++;
5461841Sroot 				continue;
5471841Sroot 			}
5481841Sroot 		}
549*1878Sroot 
550*1878Sroot 		/*
551*1878Sroot 		 *  for the following "really" hacked code, I
552*1878Sroot 		 *  apologize. Creeping featurism got me. DLP
553*1878Sroot 		 */
554*1878Sroot 
555*1878Sroot 		/* check for the start of a string */
556*1878Sroot 		if (!nokeyw && !(incomm || inacomm) && *s == sdelim) {
5571841Sroot 			if (instr) {
5581841Sroot 				if (s[-1] != '\\')
5591841Sroot 					instr = 0;
5601841Sroot 			} else
5611862Sroot 				if (s[-1] != cdelim)
5621841Sroot 					instr = 1;
5631841Sroot 		}
564*1878Sroot 
565*1878Sroot 		/* check for the end of a comment */
566*1878Sroot 		if (incomm && lcstop != 0 && comcol != s-1 && s - os >= lcstop
567*1878Sroot 		    && !strncmp(cstop, s - lcstop, lcstop)) {
5681841Sroot 			incomm = 0;
5691841Sroot 			ps("\\c\n'-C\n");
570*1878Sroot 
571*1878Sroot 		/* check for the end of a comment of the alternate type */
572*1878Sroot 		} else if (inacomm && lacstop != 0 && comcol != s-1
573*1878Sroot 		    && s - os >= lacstop
574*1878Sroot 		    && !strncmp(acstop, s - lacstop, lacstop)) {
575*1878Sroot 			inacomm = 0;
576*1878Sroot 			ps("\\c\n'-C\n");
577*1878Sroot 
578*1878Sroot 		/* check for the start of a comment */
579*1878Sroot 		} else if (!instr && !nokeyw && !(incomm || inacomm)
580*1878Sroot 		    && lcstart != 0
581*1878Sroot 		    && !strncmp(cstart, s, lcstart)) {
5821862Sroot 			comcol = s;
5831841Sroot 			incomm = 1;
5841841Sroot 			if (s != os)
5851841Sroot 				ps("\\c");
5861841Sroot 			ps("\\c\n'+C\n");
5871841Sroot 			margin = width(os, s);
5881862Sroot 			ps(cout);
5891862Sroot 			s += lcstart;
5901841Sroot 			continue;
591*1878Sroot 
592*1878Sroot 		/* check for the start of a comment of the alternate type */
593*1878Sroot 		} else if (!instr && !nokeyw && !(incomm || inacomm)
594*1878Sroot 		    && lacstart != 0
595*1878Sroot 		    && !strncmp(acstart, s, lacstart)) {
596*1878Sroot 			comcol = s;
597*1878Sroot 			inacomm = 1;
598*1878Sroot 			if (s != os)
599*1878Sroot 				ps("\\c");
600*1878Sroot 			ps("\\c\n'+C\n");
601*1878Sroot 			margin = width(os, s);
602*1878Sroot 			ps(acout);
603*1878Sroot 			s += lacstart;
604*1878Sroot 			continue;
6051841Sroot 		}
606*1878Sroot 
607*1878Sroot 		/* take care of nice tab stops */
6081841Sroot 		if (*s == '\t') {
6091841Sroot 			while (*s == '\t')
6101841Sroot 				s++;
6111841Sroot 			i = tabs(os, s) - margin / 8;
6121841Sroot 			printf("\\h'|%dn'", i * 10 + 1 - margin % 8);
6131841Sroot 			continue;
6141841Sroot 		}
6151841Sroot /*
6161841Sroot 		if (*s == '-' && s[1] == '>') {
6171841Sroot 			s += 2;
6181841Sroot 			ps("\\(->");
6191841Sroot 			continue;
6201841Sroot 		}
6211841Sroot */
622*1878Sroot 		if (!incomm && !nokeyw && !instr && (*s == '#' || isalpha(*s))
623*1878Sroot 		    && (s == os || !isidchr(s[-1]))) {
6241841Sroot 			i = iskw(s);
6251841Sroot 			if (i > 0) {
6261841Sroot 				ps("\\*(+K");
6271841Sroot 				do
6281841Sroot 					putcp(*s++);
6291841Sroot 				while (--i > 0);
6301841Sroot 				ps("\\*(-K");
6311841Sroot 				continue;
6321841Sroot 			}
6331841Sroot 		}
6341841Sroot 		putcp(*s++);
6351841Sroot 	}
6361841Sroot }
6371841Sroot 
6381841Sroot tabs(s, os)
6391841Sroot 	char *s, *os;
6401841Sroot {
6411841Sroot 
6421841Sroot 	return (width(s, os) / 8);
6431841Sroot }
6441841Sroot 
6451841Sroot width(s, os)
6461841Sroot 	register char *s, *os;
6471841Sroot {
6481841Sroot 	register int i = 0;
6491841Sroot 
6501841Sroot 	while (s < os) {
6511841Sroot 		if (*s == '\t') {
6521841Sroot 			i = (i + 8) &~ 7;
6531841Sroot 			s++;
6541841Sroot 			continue;
6551841Sroot 		}
6561841Sroot 		if (*s < ' ')
6571841Sroot 			i += 2;
6581841Sroot 		else
6591841Sroot 			i++;
6601841Sroot 		s++;
6611841Sroot 	}
6621841Sroot 	return (i);
6631841Sroot }
6641841Sroot 
6651841Sroot putcp(c)
6661841Sroot 	register int c;
6671841Sroot {
6681841Sroot 
6691841Sroot 	switch(c) {
6701841Sroot 
6711841Sroot 	case '{':
6721841Sroot 		ps("\\*(+K{\\*(-K");
6731841Sroot 		break;
6741841Sroot 
6751841Sroot 	case '}':
6761841Sroot 		ps("\\*(+K}\\*(-K");
6771841Sroot 		break;
6781841Sroot 
6791841Sroot 	case '\\':
6801841Sroot 		ps("\\e");
6811841Sroot 		break;
6821841Sroot 
6831841Sroot 	case '_':
6841841Sroot 		ps("\\*_");
6851841Sroot 		break;
6861841Sroot 
6871841Sroot 	case '-':
6881841Sroot 		ps("\\*-");
6891841Sroot 		break;
6901841Sroot 
6911841Sroot 	case '`':
6921841Sroot 		ps("\\`");
6931841Sroot 		break;
6941841Sroot 
6951841Sroot 	case '\'':
6961841Sroot 		ps("\\'");
6971841Sroot 		break;
6981841Sroot 
6991841Sroot 	case '.':
7001841Sroot 		ps("\\&.");
7011841Sroot 		break;
7021841Sroot 
7031841Sroot 	default:
7041841Sroot 		if (c < 040)
7051841Sroot 			putchar('^'), c |= '@';
7061841Sroot 	case '\t':
7071841Sroot 	case '\n':
7081841Sroot 		putchar(c);
7091841Sroot 	}
7101841Sroot }
7111841Sroot 
712*1878Sroot 
713*1878Sroot /*  STRNCMP -	like strncmp except that we convert the
714*1878Sroot  *	 	first string to lower case before comparing.
715*1878Sroot  */
716*1878Sroot #define makelower(c) (isupper((c)) ? tolower((c)) : (c))
717*1878Sroot 
718*1878Sroot STRNCMP(s1, s2, len)
719*1878Sroot 	register char *s1,*s2;
720*1878Sroot 	register int len;
721*1878Sroot {
722*1878Sroot 	do
723*1878Sroot 	    if (*s2 - makelower(*s1))
724*1878Sroot 		    return (*s2 - makelower(*s1));
725*1878Sroot 	    else {
726*1878Sroot 		    s2++;
727*1878Sroot 		    s1++;
728*1878Sroot 	    }
729*1878Sroot 	while (--len);
730*1878Sroot 	return(0);
731*1878Sroot }
732*1878Sroot 
733*1878Sroot /*  iskw -	check to see if the next word is a keyword
734*1878Sroot  */
735*1878Sroot 
7361841Sroot iskw(s)
7371841Sroot 	register char *s;
7381841Sroot {
7391862Sroot 	register char **ss = keywds;
7401841Sroot 	register int i = 1;
7411841Sroot 	register char *cp = s;
7421841Sroot 
7431841Sroot 	while (++cp, isidchr(*cp))
7441841Sroot 		i++;
7451841Sroot 	while (cp = *ss++)
746*1878Sroot 		if (!(upeqlow?STRNCMP(s,cp,i):strncmp(s,cp,i))
747*1878Sroot 		    && !isidchr(cp[i]))
7481841Sroot 			return (i);
7491841Sroot 	return (0);
7501841Sroot }
7511862Sroot 
7521862Sroot cprbegin(s)
7531862Sroot 	register char *s;
7541862Sroot {
7551862Sroot 	register char *p;
7561862Sroot 
7571862Sroot 	p = pname;
758*1878Sroot 
759*1878Sroot 	/*
760*1878Sroot 	 * some people like to start the names of routines that return
761*1878Sroot 	 * a pointer with a '*'.
762*1878Sroot 	 */
763*1878Sroot 	if (*s == '*')
764*1878Sroot 		s++;
765*1878Sroot 
7661862Sroot 	if ((*s == '_' || isalpha(*s)) && s[strlen(s) - 2] == ')') {
7671862Sroot 		while (isidchr(*s))
7681862Sroot 			*p++ = *s++;
7691862Sroot 		*p = 0;
7701862Sroot 		return (1);
7711862Sroot 	}
7721862Sroot 	return (0);
7731862Sroot }
7741862Sroot 
7751862Sroot cprend(s)
7761862Sroot 	register char *s;
7771862Sroot {
7781862Sroot 	if (!strcmp(s, "}\n"))
7791862Sroot 		return (1);
7801862Sroot 	else
7811862Sroot 		return (0);
7821862Sroot }
7831862Sroot 
784*1878Sroot iprbegin(s)
785*1878Sroot 	register char *s;
786*1878Sroot {
787*1878Sroot 	return(0);
788*1878Sroot }
789*1878Sroot 
790*1878Sroot iprend(s)
791*1878Sroot 	register char *s;
792*1878Sroot {
793*1878Sroot 	return(0);
794*1878Sroot }
795*1878Sroot 
7961862Sroot pprbegin(s)
7971862Sroot 	register char *s;
7981862Sroot {
7991862Sroot 	register char *p;
8001862Sroot 
8011862Sroot 	p = pname;
8021862Sroot 	while ((*s == ' ') || (*s == '\t'))
8031862Sroot 		s++;
8041862Sroot 	if (strncmp(s, "procedure", 9) == 0)
8051862Sroot 		s += 9;
8061862Sroot 	else if (strncmp(s, "function", 8) ==0)
8071862Sroot 		s += 8;
8081862Sroot 	else
8091862Sroot 		return (0);
8101862Sroot 	while ((*s == ' ') || (*s == '\t'))
8111862Sroot 		s++;
8121862Sroot 	while ((*s != ' ') && (*s != '\t') && (*s != '(') && (*s != ';'))
8131862Sroot 		*p++ = *s++;
8141862Sroot 	*p = 0;
8151862Sroot 	return (1);
8161862Sroot }
8171862Sroot 
8181862Sroot pprend(s)
8191862Sroot 	register char *s;
8201862Sroot {
8211862Sroot 	if (strncmp (s, "end", 3) == 0)
8221862Sroot 		return (1);
8231862Sroot 	else
8241862Sroot 		return (0);
8251862Sroot }
8261862Sroot 
8271862Sroot mprbegin(s)
8281862Sroot 	register char *s;
8291862Sroot {
8301862Sroot 	register char *p;
8311862Sroot 
8321862Sroot 	p = pname;
8331862Sroot 	if (strcmp(&s[strlen(s) - 10], "beginproc\n") == 0) {
8341862Sroot 
8351862Sroot 		while ((*s == ' ') || (*s == '\t'))
8361862Sroot 			s++;
8371862Sroot 
8381862Sroot 		while (*s != ' ')
8391862Sroot 			*p++ = *s++;
8401862Sroot 		*p = 0;
8411862Sroot 		return (1);
8421862Sroot 	} else
8431862Sroot 		return (0);
8441862Sroot }
8451862Sroot 
8461862Sroot mprend(s)
8471862Sroot 	register char *s;
8481862Sroot {
8491862Sroot 	if (!strcmp(&s[strlen(s) - 9], "endproc;\n"))
8501862Sroot 		return (1);
8511862Sroot 	else
8521862Sroot 		return (0);
8531862Sroot }
854