1 #include "e.h" 2 #include "y.tab.h" 3 #include <ctype.h> 4 5 #define SSIZE 1000 6 char token[SSIZE]; 7 int sp; 8 9 void space(void); 10 void dodef(tbl *); 11 void define(int); 12 void ifdef(void); 13 void include(void); 14 void delim(void); 15 16 yylex(void) 17 { 18 register int c; 19 tbl *tp; 20 21 begin: 22 while ((c = input()) == ' ' || c == '\n' || c == '\t') 23 ; 24 yylval = c; 25 switch (c) { 26 case EOF: 27 ERROR "unexpected end of input inside equation" WARNING; 28 return(EOF); 29 case '~': 30 return(SPACE); 31 case '^': 32 return(THIN); 33 /* case '\t': 34 return(TAB); 35 */ 36 case '{': 37 return('{'); 38 case '}': 39 return('}'); 40 case '"': 41 for (sp = 0; (c=input())!='"' && c != '\n'; ) { 42 if (c == '\\') 43 if ((c = input()) != '"') 44 token[sp++] = '\\'; 45 token[sp++] = c; 46 if (sp >= SSIZE) 47 ERROR "quoted string %.20s... too long", token FATAL; 48 } 49 token[sp] = '\0'; 50 yylval = (int) &token[0]; 51 if (c == '\n') 52 ERROR "missing \" in %.20s", token WARNING; 53 return(QTEXT); 54 } 55 if (!display && c == righteq) 56 return(EOF); 57 58 unput(c); 59 getstr(token, SSIZE); 60 dprintf(".\tlex token = |%s|\n", token); 61 if ((tp = lookup(deftbl, token)) != NULL) { /* defined term */ 62 c = input(); 63 unput(c); 64 if (c == '(') /* macro with args */ 65 dodef(tp); 66 else { /* no args */ 67 unput(' '); 68 pbstr(tp->cval); 69 dprintf(".\tfound %s|=%s|\n", token, tp->cval); 70 } 71 goto begin; 72 } 73 74 if ((tp = lookup(keytbl, token)) == NULL) /* not a keyword */ 75 return CONTIG; 76 77 switch (tp->ival) { /* some kind of keyword */ 78 case DEFINE: case TDEFINE: case NDEFINE: 79 define(tp->ival); 80 break; 81 case IFDEF: 82 ifdef(); 83 break; 84 case DELIM: 85 delim(); 86 break; 87 case GSIZE: 88 globsize(); 89 break; 90 case GFONT: 91 globfont(); 92 break; 93 case INCLUDE: 94 include(); 95 break; 96 case SPACE: 97 space(); 98 break; 99 case DOTEQ: 100 /* .EQ inside equation -- should warn if at bottom level */ 101 break; 102 case DOTEN: 103 if (curfile == infile) 104 return EOF; 105 /* else ignore nested .EN */ 106 break; 107 default: 108 return tp->ival; 109 } 110 goto begin; 111 } 112 113 void getstr(char *s, int n) 114 { 115 register int c; 116 register char *p; 117 118 p = s; 119 while ((c = input()) == ' ' || c == '\n') 120 ; 121 if (c == EOF) { 122 *s = 0; 123 return; 124 } 125 while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' 126 && c != '"' && c != '~' && c != '^') { 127 if (!display && c == righteq) 128 break; 129 if (c == '(' && p > s) { /* might be defined(...) */ 130 *p = '\0'; 131 if (lookup(deftbl, s) != NULL) 132 break; 133 } 134 if (c == '\\') 135 if ((c = input()) != '"') 136 *p++ = '\\'; 137 *p++ = c; 138 if (--n <= 0) 139 ERROR "token %.20s... too long", s FATAL; 140 c = input(); 141 } 142 unput(c); 143 *p = '\0'; 144 yylval = (int) s; 145 } 146 147 cstr(char *s, int quote, int maxs) 148 { 149 int del, c, i; 150 151 s[0] = 0; 152 while ((del=input()) == ' ' || del == '\t') 153 ; 154 if (quote) 155 for (i=0; (c=input()) != del && c != EOF;) { 156 s[i++] = c; 157 if (i >= maxs) 158 return(1); /* disaster */ 159 } 160 else { 161 if (del == '\n') 162 return(1); 163 s[0] = del; 164 for (i=1; (c=input())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) { 165 s[i++] = c; 166 if (i >= maxs) 167 return(1); /* disaster */ 168 } 169 } 170 s[i] = '\0'; 171 if (c == EOF) 172 ERROR "Unexpected end of input at %.20s", s FATAL; 173 return(0); 174 } 175 176 void define(int type) 177 { 178 char *p1, *p2; 179 extern int ftune(char *, char *); 180 181 getstr(token, SSIZE); /* get name */ 182 if (type != DEFINE) { 183 cstr(token, 1, SSIZE); /* skip the definition too */ 184 return; 185 } 186 p1 = strsave(token); 187 if (cstr(token, 1, SSIZE)) 188 ERROR "Unterminated definition at %.20s", token FATAL; 189 if (lookup(ftunetbl, p1) != NULL) { /* double tuning param */ 190 dprintf(".\ttune %s %s\n", p1, token); 191 ftune(p1, token); 192 } else { 193 p2 = strsave(token); 194 install(deftbl, p1, p2, 0); 195 dprintf(".\tname %s defined as %s\n", p1, p2); 196 } 197 } 198 199 void ifdef(void) /* do body if name is defined */ 200 { 201 char name[100], *p; 202 203 getstr(name, sizeof(name)); /* get name */ 204 cstr(token, 1, SSIZE); /* and body */ 205 if (lookup(deftbl, name) != NULL) { /* found it */ 206 p = strsave(token); 207 pushsrc(Free, p); 208 pushsrc(String, p); 209 } 210 } 211 212 char *spaceval = NULL; 213 214 void space(void) /* collect line of form "space amt" to replace \x in output */ 215 { 216 getstr(token, SSIZE); 217 spaceval = strsave(token); 218 dprintf(".\tsetting spaceval to %s\n", token); 219 } 220 221 char *strsave(char *s) 222 { 223 register char *q; 224 225 q = malloc(strlen(s)+1); 226 if (q == NULL) 227 ERROR "out of space in strsave on %s", s FATAL; 228 strcpy(q, s); 229 return(q); 230 } 231 232 void include(void) 233 { 234 char name[100]; 235 FILE *fin; 236 int c; 237 extern int errno; 238 239 while ((c = input()) == ' ') 240 ; 241 unput(c); 242 cstr(name, c == '"', sizeof(name)); /* gets it quoted or not */ 243 if ((fin = fopen(name, "r")) == NULL) 244 ERROR "can't open file %s", name FATAL; 245 errno = 0; 246 curfile++; 247 curfile->fin = fin; 248 curfile->fname = strsave(name); 249 curfile->lineno = 0; 250 printf(".lf 1 %s\n", curfile->fname); 251 pushsrc(File, curfile->fname); 252 } 253 254 void delim(void) 255 { 256 yyval = eqnreg = 0; 257 if (cstr(token, 0, SSIZE)) 258 ERROR "Bizarre delimiters" FATAL; 259 lefteq = token[0]; 260 righteq = token[1]; 261 if (!isprint(lefteq) || !isprint(righteq)) 262 ERROR "Bizarre delimiters" FATAL; 263 if (lefteq == 'o' && righteq == 'f') 264 lefteq = righteq = '\0'; 265 } 266