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