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
gtc()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 */
openinfile()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
pbstr(str)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
yylex()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
getstr(s,n)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
cstr(s,quote,maxs)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
define(type)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
strsave(s)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
include()223 include() {
224 error(!FATAL, "Include not yet implemented");
225 }
226
delim()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