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