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