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