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