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