1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 7 /* All Rights Reserved */ 8 9 /* 10 * Copyright (c) 1980 Regents of the University of California. 11 * All rights reserved. The Berkeley software License Agreement 12 * specifies the terms and conditions for redistribution. 13 */ 14 15 #include "e.h" 16 #include "e.def" 17 #include <locale.h> 18 19 #define SSIZE 400 20 char token[SSIZE]; 21 int sp; 22 #define putbak(c) *ip++ = c; 23 #define PUSHBACK 300 /* maximum pushback characters */ 24 char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */ 25 char *ip = ibuf; 26 27 extern tbl *keytbl[]; 28 extern tbl *deftbl[]; 29 30 void define(int); 31 void delim(void); 32 void getstr(char *, int); 33 void include(void); 34 int openinfile(void); 35 void pbstr(char *); 36 void space(void); 37 38 int 39 gtc(void) 40 { 41 loop: 42 if (ip > ibuf) 43 return (*--ip); /* already present */ 44 lastchar = getc(curfile); 45 if (lastchar == '\n') 46 linect++; 47 if (lastchar != EOF) 48 return (lastchar); 49 if (++ifile > svargc) { 50 return (EOF); 51 } 52 (void) fclose(curfile); 53 linect = 1; 54 if (openinfile() == 0) 55 goto loop; 56 return (EOF); 57 } 58 /* 59 * open file indexed by ifile in svargv, return non zero if fail 60 */ 61 int 62 openinfile(void) 63 { 64 if (strcmp(svargv[ifile], "-") == 0) { 65 curfile = stdin; 66 return (0); 67 } else if ((curfile = fopen(svargv[ifile], "r")) != NULL) { 68 return (0); 69 } 70 error(FATAL, gettext("can't open file %s"), svargv[ifile]); 71 return (1); 72 } 73 74 void 75 pbstr(char *str) 76 { 77 char *p; 78 79 p = str; 80 while (*p++) 81 ; 82 --p; 83 if (ip >= &ibuf[PUSHBACK]) 84 error(FATAL, gettext("pushback overflow")); 85 while (p > str) 86 putbak(*--p); 87 } 88 89 int 90 yylex(void) 91 { 92 int c; 93 tbl *tp, *lookup(); 94 95 beg: 96 while ((c = gtc()) == ' ' || c == '\n') 97 ; 98 yylval = c; 99 switch (c) { 100 101 case EOF: 102 return (EOF); 103 case '~': 104 return (SPACE); 105 case '^': 106 return (THIN); 107 case '\t': 108 return (TAB); 109 case '{': 110 return ('{'); 111 case '}': 112 return ('}'); 113 case '"': 114 for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) { 115 if (c == '\\') 116 if ((c = gtc()) != '"') 117 token[sp++] = '\\'; 118 token[sp++] = c; 119 if (sp >= SSIZE) 120 error(FATAL, gettext( 121 "quoted string %.20s... too long"), token); 122 } 123 token[sp] = '\0'; 124 yylval = (int)&token[0]; 125 if (c == '\n') 126 error(!FATAL, gettext("missing \" in %.20s"), token); 127 return (QTEXT); 128 } 129 if (c == righteq) 130 return (EOF); 131 132 putbak(c); 133 getstr(token, SSIZE); 134 if (dbg) printf(".\tlex token = |%s|\n", token); 135 if ((tp = lookup(deftbl, token, NULL)) != NULL) { 136 putbak(' '); 137 pbstr(tp->defn); 138 putbak(' '); 139 if (dbg) 140 printf(".\tfound %s|=%s|\n", token, tp->defn); 141 } else if ((tp = lookup(keytbl, token, NULL)) == NULL) { 142 if (dbg) printf(".\t%s is not a keyword\n", token); 143 return (CONTIG); 144 } else if (tp->defn == (char *)DEFINE || 145 tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE) 146 define((int)tp->defn); 147 else if (tp->defn == (char *)DELIM) 148 delim(); 149 else if (tp->defn == (char *)GSIZE) 150 globsize(); 151 else if (tp->defn == (char *)GFONT) 152 globfont(); 153 else if (tp->defn == (char *)INCLUDE) 154 include(); 155 else if (tp->defn == (char *)SPACE) 156 space(); 157 else { 158 return ((int)tp->defn); 159 } 160 goto beg; 161 } 162 163 void 164 getstr(char *s, int n) 165 { 166 int c; 167 char *p; 168 169 p = s; 170 while ((c = gtc()) == ' ' || c == '\n') 171 ; 172 if (c == EOF) { 173 *s = 0; 174 return; 175 } 176 while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' && 177 c != '"' && c != '~' && c != '^' && c != righteq) { 178 if (c == '\\') 179 if ((c = gtc()) != '"') 180 *p++ = '\\'; 181 *p++ = c; 182 if (--n <= 0) 183 error(FATAL, gettext("token %.20s... too long"), s); 184 c = gtc(); 185 } 186 if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' || 187 c == '\t' || c == righteq) 188 putbak(c); 189 *p = '\0'; 190 yylval = (int)s; 191 } 192 193 int 194 cstr(char *s, int quote, int maxs) 195 { 196 int del, c, i; 197 198 s[0] = 0; 199 while ((del = gtc()) == ' ' || del == '\t') 200 ; 201 if (quote) { 202 for (i = 0; (c = gtc()) != del && c != EOF; ) { 203 s[i++] = c; 204 if (i >= maxs) 205 return (1); /* disaster */ 206 } 207 } else { 208 if (del == '\n') 209 return (1); 210 s[0] = del; 211 for (i = 1; (c = gtc()) != ' ' && c != '\t' && 212 c != '\n' && c != EOF; /* empty */) { 213 s[i++] = c; 214 if (i >= maxs) 215 return (1); /* disaster */ 216 } 217 } 218 s[i] = '\0'; 219 if (c == EOF) 220 error(FATAL, gettext("Unexpected end of input at %.20s"), s); 221 return (0); 222 } 223 224 void 225 define(int type) 226 { 227 char *strsave(), *p1, *p2; 228 tbl *lookup(); 229 230 getstr(token, SSIZE); /* get name */ 231 if (type != DEFINE) { 232 (void) cstr(token, 1, SSIZE); /* skip the definition too */ 233 return; 234 } 235 p1 = strsave(token); 236 if (cstr(token, 1, SSIZE)) 237 error(FATAL, gettext( 238 "Unterminated definition at %.20s"), token); 239 p2 = strsave(token); 240 lookup(deftbl, p1, p2); 241 if (dbg) printf(".\tname %s defined as %s\n", p1, p2); 242 } 243 244 char *spaceval = NULL; 245 246 void 247 space(void) /* collect line of form "space amt" to replace \x in output */ 248 { 249 char *strsave(); 250 251 getstr(token, SSIZE); 252 spaceval = strsave(token); 253 if (dbg) printf(".\tsetting space to %s\n", token); 254 } 255 256 257 char * 258 strsave(char *s) 259 { 260 char *malloc(); 261 char *q; 262 263 q = malloc(strlen(s)+1); 264 if (q == NULL) 265 error(FATAL, gettext("out of space in strsave on %s"), s); 266 strcpy(q, s); 267 return (q); 268 } 269 270 void 271 include(void) 272 { 273 error(!FATAL, gettext("Include not yet implemented")); 274 } 275 276 void 277 delim(void) 278 { 279 yyval = eqnreg = 0; 280 if (cstr(token, 0, SSIZE)) 281 error(FATAL, gettext("Bizarre delimiters at %.20s"), token); 282 lefteq = token[0]; 283 righteq = token[1]; 284 if (lefteq == 'o' && righteq == 'f') 285 lefteq = righteq = '\0'; 286 } 287