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