xref: /onnv-gate/usr/src/cmd/eqn/lex.c (revision 364:f36290b8cb0b)
1*364Sceastha /*
2*364Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3*364Sceastha  * Use is subject to license terms.
4*364Sceastha  */
5*364Sceastha 
60Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
70Sstevel@tonic-gate /*	  All Rights Reserved  	*/
80Sstevel@tonic-gate 
90Sstevel@tonic-gate /*
100Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
110Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
120Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
130Sstevel@tonic-gate  */
14*364Sceastha 
15*364Sceastha #pragma ident	"%Z%%M%	%I%	%E% SMI"
160Sstevel@tonic-gate 
170Sstevel@tonic-gate #include "e.h"
180Sstevel@tonic-gate #include "e.def"
190Sstevel@tonic-gate #include <locale.h>
200Sstevel@tonic-gate 
210Sstevel@tonic-gate #define	SSIZE	400
220Sstevel@tonic-gate char	token[SSIZE];
230Sstevel@tonic-gate int	sp;
240Sstevel@tonic-gate #define	putbak(c)	*ip++ = c;
250Sstevel@tonic-gate #define	PUSHBACK	300	/* maximum pushback characters */
260Sstevel@tonic-gate char	ibuf[PUSHBACK+SSIZE];	/* pushback buffer for definitions, etc. */
270Sstevel@tonic-gate char	*ip	= ibuf;
280Sstevel@tonic-gate 
29*364Sceastha void define(int);
30*364Sceastha void delim(void);
31*364Sceastha void getstr(char *, int);
32*364Sceastha void include(void);
33*364Sceastha int openinfile(void);
34*364Sceastha void pbstr(char *);
35*364Sceastha void space(void);
36*364Sceastha 
37*364Sceastha int
38*364Sceastha gtc(void)
39*364Sceastha {
40*364Sceastha loop:
410Sstevel@tonic-gate 	if (ip > ibuf)
42*364Sceastha 		return (*--ip);	/* already present */
430Sstevel@tonic-gate 	lastchar = getc(curfile);
44*364Sceastha 	if (lastchar == '\n')
450Sstevel@tonic-gate 		linect++;
460Sstevel@tonic-gate 	if (lastchar != EOF)
47*364Sceastha 		return (lastchar);
480Sstevel@tonic-gate 	if (++ifile > svargc) {
49*364Sceastha 		return (EOF);
500Sstevel@tonic-gate 	}
51*364Sceastha 	(void) fclose(curfile);
520Sstevel@tonic-gate 	linect = 1;
530Sstevel@tonic-gate 	if (openinfile() == 0)
540Sstevel@tonic-gate 		goto loop;
55*364Sceastha 	return (EOF);
560Sstevel@tonic-gate }
570Sstevel@tonic-gate /*
580Sstevel@tonic-gate  *	open file indexed by ifile in svargv, return non zero if fail
590Sstevel@tonic-gate  */
60*364Sceastha int
61*364Sceastha openinfile(void)
620Sstevel@tonic-gate {
63*364Sceastha 	if (strcmp(svargv[ifile], "-") == 0) {
640Sstevel@tonic-gate 		curfile = stdin;
65*364Sceastha 		return (0);
66*364Sceastha 	} else if ((curfile = fopen(svargv[ifile], "r")) != NULL) {
67*364Sceastha 		return (0);
680Sstevel@tonic-gate 	}
690Sstevel@tonic-gate 	error(FATAL, gettext("can't open file %s"), svargv[ifile]);
70*364Sceastha 	return (1);
710Sstevel@tonic-gate }
720Sstevel@tonic-gate 
73*364Sceastha void
74*364Sceastha pbstr(char *str)
750Sstevel@tonic-gate {
76*364Sceastha 	char *p;
770Sstevel@tonic-gate 
780Sstevel@tonic-gate 	p = str;
79*364Sceastha 	while (*p++)
80*364Sceastha 		;
810Sstevel@tonic-gate 	--p;
820Sstevel@tonic-gate 	if (ip >= &ibuf[PUSHBACK])
83*364Sceastha 		error(FATAL, gettext("pushback overflow"));
840Sstevel@tonic-gate 	while (p > str)
850Sstevel@tonic-gate 		putbak(*--p);
860Sstevel@tonic-gate }
870Sstevel@tonic-gate 
88*364Sceastha int
89*364Sceastha yylex(void)
90*364Sceastha {
91*364Sceastha 	int c;
920Sstevel@tonic-gate 	tbl *tp, *lookup();
930Sstevel@tonic-gate 	extern tbl **keytbl, **deftbl;
940Sstevel@tonic-gate 
95*364Sceastha beg:
96*364Sceastha 	while ((c = gtc()) == ' ' || c == '\n')
970Sstevel@tonic-gate 		;
98*364Sceastha 	yylval = c;
99*364Sceastha 	switch (c) {
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	case EOF:
102*364Sceastha 		return (EOF);
1030Sstevel@tonic-gate 	case '~':
104*364Sceastha 		return (SPACE);
1050Sstevel@tonic-gate 	case '^':
106*364Sceastha 		return (THIN);
1070Sstevel@tonic-gate 	case '\t':
108*364Sceastha 		return (TAB);
1090Sstevel@tonic-gate 	case '{':
110*364Sceastha 		return ('{');
1110Sstevel@tonic-gate 	case '}':
112*364Sceastha 		return ('}');
1130Sstevel@tonic-gate 	case '"':
114*364Sceastha 		for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) {
1150Sstevel@tonic-gate 			if (c == '\\')
1160Sstevel@tonic-gate 				if ((c = gtc()) != '"')
1170Sstevel@tonic-gate 					token[sp++] = '\\';
1180Sstevel@tonic-gate 			token[sp++] = c;
119*364Sceastha 			if (sp >= SSIZE)
120*364Sceastha 				error(FATAL, gettext(
121*364Sceastha 				    "quoted string %.20s... too long"), token);
1220Sstevel@tonic-gate 		}
123*364Sceastha 		token[sp] = '\0';
124*364Sceastha 		yylval = (int)&token[0];
1250Sstevel@tonic-gate 		if (c == '\n')
1260Sstevel@tonic-gate 			error(!FATAL, gettext("missing \" in %.20s"), token);
127*364Sceastha 		return (QTEXT);
1280Sstevel@tonic-gate 	}
129*364Sceastha 	if (c == righteq)
130*364Sceastha 		return (EOF);
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	putbak(c);
1330Sstevel@tonic-gate 	getstr(token, SSIZE);
134*364Sceastha 	if (dbg) printf(".\tlex token = |%s|\n", token);
135*364Sceastha 	if ((tp = lookup(deftbl, token, NULL)) != NULL) {
1360Sstevel@tonic-gate 		putbak(' ');
1370Sstevel@tonic-gate 		pbstr(tp->defn);
1380Sstevel@tonic-gate 		putbak(' ');
1390Sstevel@tonic-gate 		if (dbg)
1400Sstevel@tonic-gate 			printf(".\tfound %s|=%s|\n", token, tp->defn);
141*364Sceastha 	} else if ((tp = lookup(keytbl, token, NULL)) == NULL) {
142*364Sceastha 		if (dbg) printf(".\t%s is not a keyword\n", token);
143*364Sceastha 		return (CONTIG);
144*364Sceastha 	} else if (tp->defn == (char *)DEFINE ||
145*364Sceastha 	    tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE)
146*364Sceastha 		define((int)tp->defn);
147*364Sceastha 	else if (tp->defn == (char *)DELIM)
1480Sstevel@tonic-gate 		delim();
149*364Sceastha 	else if (tp->defn == (char *)GSIZE)
1500Sstevel@tonic-gate 		globsize();
151*364Sceastha 	else if (tp->defn == (char *)GFONT)
1520Sstevel@tonic-gate 		globfont();
153*364Sceastha 	else if (tp->defn == (char *)INCLUDE)
1540Sstevel@tonic-gate 		include();
155*364Sceastha 	else if (tp->defn == (char *)SPACE)
1560Sstevel@tonic-gate 		space();
1570Sstevel@tonic-gate 	else {
158*364Sceastha 		return ((int)tp->defn);
1590Sstevel@tonic-gate 	}
1600Sstevel@tonic-gate 	goto beg;
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate 
163*364Sceastha void
164*364Sceastha getstr(char *s, int n)
165*364Sceastha {
166*364Sceastha 	int c;
167*364Sceastha 	char *p;
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	p = s;
1700Sstevel@tonic-gate 	while ((c = gtc()) == ' ' || c == '\n')
1710Sstevel@tonic-gate 		;
1720Sstevel@tonic-gate 	if (c == EOF) {
1730Sstevel@tonic-gate 		*s = 0;
1740Sstevel@tonic-gate 		return;
1750Sstevel@tonic-gate 	}
176*364Sceastha 	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' &&
177*364Sceastha 	    c != '"' && c != '~' && c != '^' && c != righteq) {
1780Sstevel@tonic-gate 		if (c == '\\')
1790Sstevel@tonic-gate 			if ((c = gtc()) != '"')
1800Sstevel@tonic-gate 				*p++ = '\\';
1810Sstevel@tonic-gate 		*p++ = c;
1820Sstevel@tonic-gate 		if (--n <= 0)
1830Sstevel@tonic-gate 			error(FATAL, gettext("token %.20s... too long"), s);
1840Sstevel@tonic-gate 		c = gtc();
1850Sstevel@tonic-gate 	}
186*364Sceastha 	if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' ||
187*364Sceastha 	    c == '\t' || c == righteq)
1880Sstevel@tonic-gate 		putbak(c);
1890Sstevel@tonic-gate 	*p = '\0';
190*364Sceastha 	yylval = (int)s;
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate 
193*364Sceastha int
194*364Sceastha cstr(char *s, int quote, int maxs)
195*364Sceastha {
1960Sstevel@tonic-gate 	int del, c, i;
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 	s[0] = 0;
199*364Sceastha 	while ((del = gtc()) == ' ' || del == '\t')
200*364Sceastha 		;
201*364Sceastha 	if (quote) {
202*364Sceastha 		for (i = 0; (c = gtc()) != del && c != EOF; ) {
2030Sstevel@tonic-gate 			s[i++] = c;
2040Sstevel@tonic-gate 			if (i >= maxs)
205*364Sceastha 				return (1);	/* disaster */
2060Sstevel@tonic-gate 		}
207*364Sceastha 	} else {
2080Sstevel@tonic-gate 		if (del == '\n')
2090Sstevel@tonic-gate 			return (1);
2100Sstevel@tonic-gate 		s[0] = del;
211*364Sceastha 		for (i = 1; (c = gtc()) != ' ' && c != '\t' &&
212*364Sceastha 		    c != '\n' && c != EOF; /* empty */) {
213*364Sceastha 			s[i++] = c;
2140Sstevel@tonic-gate 			if (i >= maxs)
215*364Sceastha 				return (1);	/* disaster */
2160Sstevel@tonic-gate 		}
2170Sstevel@tonic-gate 	}
2180Sstevel@tonic-gate 	s[i] = '\0';
2190Sstevel@tonic-gate 	if (c == EOF)
2200Sstevel@tonic-gate 		error(FATAL, gettext("Unexpected end of input at %.20s"), s);
221*364Sceastha 	return (0);
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate 
224*364Sceastha void
225*364Sceastha define(int type)
226*364Sceastha {
2270Sstevel@tonic-gate 	char *strsave(), *p1, *p2;
2280Sstevel@tonic-gate 	tbl *lookup();
2290Sstevel@tonic-gate 	extern tbl **deftbl;
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 	getstr(token, SSIZE);	/* get name */
2320Sstevel@tonic-gate 	if (type != DEFINE) {
233*364Sceastha 		(void) cstr(token, 1, SSIZE);	/* skip the definition too */
2340Sstevel@tonic-gate 		return;
2350Sstevel@tonic-gate 	}
2360Sstevel@tonic-gate 	p1 = strsave(token);
2370Sstevel@tonic-gate 	if (cstr(token, 1, SSIZE))
238*364Sceastha 		error(FATAL, gettext(
239*364Sceastha 		    "Unterminated definition at %.20s"), token);
2400Sstevel@tonic-gate 	p2 = strsave(token);
241*364Sceastha 	lookup(deftbl, p1, p2);
242*364Sceastha 	if (dbg) printf(".\tname %s defined as %s\n", p1, p2);
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate char    *spaceval   = NULL;
2460Sstevel@tonic-gate 
247*364Sceastha void
248*364Sceastha space(void) /* collect line of form "space amt" to replace \x in output */
2490Sstevel@tonic-gate {
2500Sstevel@tonic-gate 	char *strsave();
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	getstr(token, SSIZE);
2530Sstevel@tonic-gate 	spaceval = strsave(token);
2540Sstevel@tonic-gate 	if (dbg) printf(".\tsetting space to %s\n", token);
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 
258*364Sceastha char *
259*364Sceastha strsave(char *s)
2600Sstevel@tonic-gate {
2610Sstevel@tonic-gate 	char *malloc();
262*364Sceastha 	char *q;
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 	q = malloc(strlen(s)+1);
2650Sstevel@tonic-gate 	if (q == NULL)
2660Sstevel@tonic-gate 		error(FATAL, gettext("out of space in strsave on %s"), s);
2670Sstevel@tonic-gate 	strcpy(q, s);
268*364Sceastha 	return (q);
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate 
271*364Sceastha void
272*364Sceastha include(void)
273*364Sceastha {
2740Sstevel@tonic-gate 	error(!FATAL, gettext("Include not yet implemented"));
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate 
277*364Sceastha void
278*364Sceastha delim(void)
279*364Sceastha {
2800Sstevel@tonic-gate 	yyval = eqnreg = 0;
2810Sstevel@tonic-gate 	if (cstr(token, 0, SSIZE))
2820Sstevel@tonic-gate 		error(FATAL, gettext("Bizarre delimiters at %.20s"), token);
2830Sstevel@tonic-gate 	lefteq = token[0];
2840Sstevel@tonic-gate 	righteq = token[1];
2850Sstevel@tonic-gate 	if (lefteq == 'o' && righteq == 'f')
2860Sstevel@tonic-gate 		lefteq = righteq = '\0';
2870Sstevel@tonic-gate }
288