xref: /titanic_54/usr/src/cmd/eqn/lex.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
2*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
3*7c478bd9Sstevel@tonic-gate 
4*7c478bd9Sstevel@tonic-gate 
5*7c478bd9Sstevel@tonic-gate /*
6*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
7*7c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
8*7c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
9*7c478bd9Sstevel@tonic-gate  */
10*7c478bd9Sstevel@tonic-gate 
11*7c478bd9Sstevel@tonic-gate /*
12*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc.
13*7c478bd9Sstevel@tonic-gate  * All Rights Reserved.
14*7c478bd9Sstevel@tonic-gate  */
15*7c478bd9Sstevel@tonic-gate 
16*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.1	*/
17*7c478bd9Sstevel@tonic-gate 
18*7c478bd9Sstevel@tonic-gate #include "e.h"
19*7c478bd9Sstevel@tonic-gate #include "e.def"
20*7c478bd9Sstevel@tonic-gate #include <locale.h>
21*7c478bd9Sstevel@tonic-gate 
22*7c478bd9Sstevel@tonic-gate #define	SSIZE	400
23*7c478bd9Sstevel@tonic-gate char	token[SSIZE];
24*7c478bd9Sstevel@tonic-gate int	sp;
25*7c478bd9Sstevel@tonic-gate #define	putbak(c)	*ip++ = c;
26*7c478bd9Sstevel@tonic-gate #define	PUSHBACK	300	/* maximum pushback characters */
27*7c478bd9Sstevel@tonic-gate char	ibuf[PUSHBACK+SSIZE];	/* pushback buffer for definitions, etc. */
28*7c478bd9Sstevel@tonic-gate char	*ip	= ibuf;
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate gtc() {
31*7c478bd9Sstevel@tonic-gate   loop:
32*7c478bd9Sstevel@tonic-gate 	if (ip > ibuf)
33*7c478bd9Sstevel@tonic-gate 		return(*--ip);	/* already present */
34*7c478bd9Sstevel@tonic-gate 	lastchar = getc(curfile);
35*7c478bd9Sstevel@tonic-gate 	if (lastchar=='\n')
36*7c478bd9Sstevel@tonic-gate 		linect++;
37*7c478bd9Sstevel@tonic-gate 	if (lastchar != EOF)
38*7c478bd9Sstevel@tonic-gate 		return(lastchar);
39*7c478bd9Sstevel@tonic-gate 	if (++ifile > svargc) {
40*7c478bd9Sstevel@tonic-gate 		return(EOF);
41*7c478bd9Sstevel@tonic-gate 	}
42*7c478bd9Sstevel@tonic-gate 	fclose(curfile);
43*7c478bd9Sstevel@tonic-gate 	linect = 1;
44*7c478bd9Sstevel@tonic-gate 	if (openinfile() == 0)
45*7c478bd9Sstevel@tonic-gate 		goto loop;
46*7c478bd9Sstevel@tonic-gate 	return(EOF);
47*7c478bd9Sstevel@tonic-gate }
48*7c478bd9Sstevel@tonic-gate /*
49*7c478bd9Sstevel@tonic-gate  *	open file indexed by ifile in svargv, return non zero if fail
50*7c478bd9Sstevel@tonic-gate  */
51*7c478bd9Sstevel@tonic-gate openinfile()
52*7c478bd9Sstevel@tonic-gate {
53*7c478bd9Sstevel@tonic-gate 	if (strcmp(svargv[ifile], "-") == 0){
54*7c478bd9Sstevel@tonic-gate 		curfile = stdin;
55*7c478bd9Sstevel@tonic-gate 		return(0);
56*7c478bd9Sstevel@tonic-gate 	} else if ((curfile=fopen(svargv[ifile], "r")) != NULL){
57*7c478bd9Sstevel@tonic-gate 		return(0);
58*7c478bd9Sstevel@tonic-gate 	}
59*7c478bd9Sstevel@tonic-gate 	error(FATAL, gettext("can't open file %s"), svargv[ifile]);
60*7c478bd9Sstevel@tonic-gate 	return(1);
61*7c478bd9Sstevel@tonic-gate }
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate pbstr(str)
64*7c478bd9Sstevel@tonic-gate register char *str;
65*7c478bd9Sstevel@tonic-gate {
66*7c478bd9Sstevel@tonic-gate 	register char *p;
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate 	p = str;
69*7c478bd9Sstevel@tonic-gate 	while (*p++);
70*7c478bd9Sstevel@tonic-gate 	--p;
71*7c478bd9Sstevel@tonic-gate 	if (ip >= &ibuf[PUSHBACK])
72*7c478bd9Sstevel@tonic-gate 		error( FATAL, gettext("pushback overflow"));
73*7c478bd9Sstevel@tonic-gate 	while (p > str)
74*7c478bd9Sstevel@tonic-gate 		putbak(*--p);
75*7c478bd9Sstevel@tonic-gate }
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate yylex() {
78*7c478bd9Sstevel@tonic-gate 	register int c;
79*7c478bd9Sstevel@tonic-gate 	tbl *tp, *lookup();
80*7c478bd9Sstevel@tonic-gate 	extern tbl **keytbl, **deftbl;
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate   beg:
83*7c478bd9Sstevel@tonic-gate 	while ((c=gtc())==' ' || c=='\n')
84*7c478bd9Sstevel@tonic-gate 		;
85*7c478bd9Sstevel@tonic-gate 	yylval=c;
86*7c478bd9Sstevel@tonic-gate 	switch(c) {
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate 	case EOF:
89*7c478bd9Sstevel@tonic-gate 		return(EOF);
90*7c478bd9Sstevel@tonic-gate 	case '~':
91*7c478bd9Sstevel@tonic-gate 		return(SPACE);
92*7c478bd9Sstevel@tonic-gate 	case '^':
93*7c478bd9Sstevel@tonic-gate 		return(THIN);
94*7c478bd9Sstevel@tonic-gate 	case '\t':
95*7c478bd9Sstevel@tonic-gate 		return(TAB);
96*7c478bd9Sstevel@tonic-gate 	case '{':
97*7c478bd9Sstevel@tonic-gate 		return('{');
98*7c478bd9Sstevel@tonic-gate 	case '}':
99*7c478bd9Sstevel@tonic-gate 		return('}');
100*7c478bd9Sstevel@tonic-gate 	case '"':
101*7c478bd9Sstevel@tonic-gate 		for (sp=0; (c=gtc())!='"' && c != '\n'; ) {
102*7c478bd9Sstevel@tonic-gate 			if (c == '\\')
103*7c478bd9Sstevel@tonic-gate 				if ((c = gtc()) != '"')
104*7c478bd9Sstevel@tonic-gate 					token[sp++] = '\\';
105*7c478bd9Sstevel@tonic-gate 			token[sp++] = c;
106*7c478bd9Sstevel@tonic-gate 			if (sp>=SSIZE)
107*7c478bd9Sstevel@tonic-gate 				error(FATAL, gettext("quoted string %.20s... too long"), token);
108*7c478bd9Sstevel@tonic-gate 		}
109*7c478bd9Sstevel@tonic-gate 		token[sp]='\0';
110*7c478bd9Sstevel@tonic-gate 		yylval = (int) &token[0];
111*7c478bd9Sstevel@tonic-gate 		if (c == '\n')
112*7c478bd9Sstevel@tonic-gate 			error(!FATAL, gettext("missing \" in %.20s"), token);
113*7c478bd9Sstevel@tonic-gate 		return(QTEXT);
114*7c478bd9Sstevel@tonic-gate 	}
115*7c478bd9Sstevel@tonic-gate 	if (c==righteq)
116*7c478bd9Sstevel@tonic-gate 		return(EOF);
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 	putbak(c);
119*7c478bd9Sstevel@tonic-gate 	getstr(token, SSIZE);
120*7c478bd9Sstevel@tonic-gate 	if (dbg)printf(".\tlex token = |%s|\n", token);
121*7c478bd9Sstevel@tonic-gate 	if ((tp = lookup(&deftbl, token, NULL)) != NULL) {
122*7c478bd9Sstevel@tonic-gate 		putbak(' ');
123*7c478bd9Sstevel@tonic-gate 		pbstr(tp->defn);
124*7c478bd9Sstevel@tonic-gate 		putbak(' ');
125*7c478bd9Sstevel@tonic-gate 		if (dbg)
126*7c478bd9Sstevel@tonic-gate 			printf(".\tfound %s|=%s|\n", token, tp->defn);
127*7c478bd9Sstevel@tonic-gate 	}
128*7c478bd9Sstevel@tonic-gate 	else if ((tp = lookup(&keytbl, token, NULL)) == NULL) {
129*7c478bd9Sstevel@tonic-gate 		if(dbg)printf(".\t%s is not a keyword\n", token);
130*7c478bd9Sstevel@tonic-gate 		return(CONTIG);
131*7c478bd9Sstevel@tonic-gate 	}
132*7c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *) DEFINE || tp->defn == (char *) NDEFINE || tp->defn == (char *) TDEFINE)
133*7c478bd9Sstevel@tonic-gate 		define(tp->defn);
134*7c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *) DELIM)
135*7c478bd9Sstevel@tonic-gate 		delim();
136*7c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *) GSIZE)
137*7c478bd9Sstevel@tonic-gate 		globsize();
138*7c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *) GFONT)
139*7c478bd9Sstevel@tonic-gate 		globfont();
140*7c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *) INCLUDE)
141*7c478bd9Sstevel@tonic-gate 		include();
142*7c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *) SPACE)
143*7c478bd9Sstevel@tonic-gate 		space();
144*7c478bd9Sstevel@tonic-gate 	else {
145*7c478bd9Sstevel@tonic-gate 		return((int) tp->defn);
146*7c478bd9Sstevel@tonic-gate 	}
147*7c478bd9Sstevel@tonic-gate 	goto beg;
148*7c478bd9Sstevel@tonic-gate }
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate getstr(s, n) char *s; register int n; {
151*7c478bd9Sstevel@tonic-gate 	register int c;
152*7c478bd9Sstevel@tonic-gate 	register char *p;
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 	p = s;
155*7c478bd9Sstevel@tonic-gate 	while ((c = gtc()) == ' ' || c == '\n')
156*7c478bd9Sstevel@tonic-gate 		;
157*7c478bd9Sstevel@tonic-gate 	if (c == EOF) {
158*7c478bd9Sstevel@tonic-gate 		*s = 0;
159*7c478bd9Sstevel@tonic-gate 		return;
160*7c478bd9Sstevel@tonic-gate 	}
161*7c478bd9Sstevel@tonic-gate 	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
162*7c478bd9Sstevel@tonic-gate 	  && c != '"' && c != '~' && c != '^' && c != righteq) {
163*7c478bd9Sstevel@tonic-gate 		if (c == '\\')
164*7c478bd9Sstevel@tonic-gate 			if ((c = gtc()) != '"')
165*7c478bd9Sstevel@tonic-gate 				*p++ = '\\';
166*7c478bd9Sstevel@tonic-gate 		*p++ = c;
167*7c478bd9Sstevel@tonic-gate 		if (--n <= 0)
168*7c478bd9Sstevel@tonic-gate 			error(FATAL, gettext("token %.20s... too long"), s);
169*7c478bd9Sstevel@tonic-gate 		c = gtc();
170*7c478bd9Sstevel@tonic-gate 	}
171*7c478bd9Sstevel@tonic-gate 	if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq)
172*7c478bd9Sstevel@tonic-gate 		putbak(c);
173*7c478bd9Sstevel@tonic-gate 	*p = '\0';
174*7c478bd9Sstevel@tonic-gate 	yylval = (int) s;
175*7c478bd9Sstevel@tonic-gate }
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate cstr(s, quote, maxs) char *s; int quote; {
178*7c478bd9Sstevel@tonic-gate 	int del, c, i;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 	s[0] = 0;
181*7c478bd9Sstevel@tonic-gate 	while((del=gtc()) == ' ' || del == '\t');
182*7c478bd9Sstevel@tonic-gate 	if (quote)
183*7c478bd9Sstevel@tonic-gate 		for (i=0; (c=gtc()) != del && c != EOF;) {
184*7c478bd9Sstevel@tonic-gate 			s[i++] = c;
185*7c478bd9Sstevel@tonic-gate 			if (i >= maxs)
186*7c478bd9Sstevel@tonic-gate 				return(1);	/* disaster */
187*7c478bd9Sstevel@tonic-gate 		}
188*7c478bd9Sstevel@tonic-gate 	else {
189*7c478bd9Sstevel@tonic-gate 		if (del == '\n')
190*7c478bd9Sstevel@tonic-gate 			return (1);
191*7c478bd9Sstevel@tonic-gate 		s[0] = del;
192*7c478bd9Sstevel@tonic-gate 		for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
193*7c478bd9Sstevel@tonic-gate 			s[i++]=c;
194*7c478bd9Sstevel@tonic-gate 			if (i >= maxs)
195*7c478bd9Sstevel@tonic-gate 				return(1);	/* disaster */
196*7c478bd9Sstevel@tonic-gate 		}
197*7c478bd9Sstevel@tonic-gate 	}
198*7c478bd9Sstevel@tonic-gate 	s[i] = '\0';
199*7c478bd9Sstevel@tonic-gate 	if (c == EOF)
200*7c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("Unexpected end of input at %.20s"), s);
201*7c478bd9Sstevel@tonic-gate 	return(0);
202*7c478bd9Sstevel@tonic-gate }
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate define(type) int type; {
205*7c478bd9Sstevel@tonic-gate 	char *strsave(), *p1, *p2;
206*7c478bd9Sstevel@tonic-gate 	tbl *lookup();
207*7c478bd9Sstevel@tonic-gate 	extern tbl **deftbl;
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 	getstr(token, SSIZE);	/* get name */
210*7c478bd9Sstevel@tonic-gate 	if (type != DEFINE) {
211*7c478bd9Sstevel@tonic-gate 		cstr(token, 1, SSIZE);	/* skip the definition too */
212*7c478bd9Sstevel@tonic-gate 		return;
213*7c478bd9Sstevel@tonic-gate 	}
214*7c478bd9Sstevel@tonic-gate 	p1 = strsave(token);
215*7c478bd9Sstevel@tonic-gate 	if (cstr(token, 1, SSIZE))
216*7c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("Unterminated definition at %.20s"), token);
217*7c478bd9Sstevel@tonic-gate 	p2 = strsave(token);
218*7c478bd9Sstevel@tonic-gate 	lookup(&deftbl, p1, p2);
219*7c478bd9Sstevel@tonic-gate 	if (dbg)printf(".\tname %s defined as %s\n", p1, p2);
220*7c478bd9Sstevel@tonic-gate }
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate char    *spaceval   = NULL;
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate space() /* collect line of form "space amt" to replace \x in output */
225*7c478bd9Sstevel@tonic-gate {
226*7c478bd9Sstevel@tonic-gate 	char *strsave();
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 	getstr(token, SSIZE);
229*7c478bd9Sstevel@tonic-gate 	spaceval = strsave(token);
230*7c478bd9Sstevel@tonic-gate 	if (dbg) printf(".\tsetting space to %s\n", token);
231*7c478bd9Sstevel@tonic-gate }
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate char *strsave(s)
235*7c478bd9Sstevel@tonic-gate char *s;
236*7c478bd9Sstevel@tonic-gate {
237*7c478bd9Sstevel@tonic-gate 	char *malloc();
238*7c478bd9Sstevel@tonic-gate 	register char *q;
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 	q = malloc(strlen(s)+1);
241*7c478bd9Sstevel@tonic-gate 	if (q == NULL)
242*7c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("out of space in strsave on %s"), s);
243*7c478bd9Sstevel@tonic-gate 	strcpy(q, s);
244*7c478bd9Sstevel@tonic-gate 	return(q);
245*7c478bd9Sstevel@tonic-gate }
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate include() {
248*7c478bd9Sstevel@tonic-gate 	error(!FATAL, gettext("Include not yet implemented"));
249*7c478bd9Sstevel@tonic-gate }
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate delim() {
252*7c478bd9Sstevel@tonic-gate 	yyval = eqnreg = 0;
253*7c478bd9Sstevel@tonic-gate 	if (cstr(token, 0, SSIZE))
254*7c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("Bizarre delimiters at %.20s"), token);
255*7c478bd9Sstevel@tonic-gate 	lefteq = token[0];
256*7c478bd9Sstevel@tonic-gate 	righteq = token[1];
257*7c478bd9Sstevel@tonic-gate 	if (lefteq == 'o' && righteq == 'f')
258*7c478bd9Sstevel@tonic-gate 		lefteq = righteq = '\0';
259*7c478bd9Sstevel@tonic-gate }
260