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 void define(int); 30 void delim(void); 31 void getstr(char *, int); 32 void include(void); 33 int openinfile(void); 34 void pbstr(char *); 35 void space(void); 36 37 int 38 gtc(void) 39 { 40 loop: 41 if (ip > ibuf) 42 return (*--ip); /* already present */ 43 lastchar = getc(curfile); 44 if (lastchar == '\n') 45 linect++; 46 if (lastchar != EOF) 47 return (lastchar); 48 if (++ifile > svargc) { 49 return (EOF); 50 } 51 (void) fclose(curfile); 52 linect = 1; 53 if (openinfile() == 0) 54 goto loop; 55 return (EOF); 56 } 57 /* 58 * open file indexed by ifile in svargv, return non zero if fail 59 */ 60 int 61 openinfile(void) 62 { 63 if (strcmp(svargv[ifile], "-") == 0) { 64 curfile = stdin; 65 return (0); 66 } else if ((curfile = fopen(svargv[ifile], "r")) != NULL) { 67 return (0); 68 } 69 error(FATAL, gettext("can't open file %s"), svargv[ifile]); 70 return (1); 71 } 72 73 void 74 pbstr(char *str) 75 { 76 char *p; 77 78 p = str; 79 while (*p++) 80 ; 81 --p; 82 if (ip >= &ibuf[PUSHBACK]) 83 error(FATAL, gettext("pushback overflow")); 84 while (p > str) 85 putbak(*--p); 86 } 87 88 int 89 yylex(void) 90 { 91 int c; 92 tbl *tp, *lookup(); 93 extern tbl **keytbl, **deftbl; 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 extern tbl **deftbl; 230 231 getstr(token, SSIZE); /* get name */ 232 if (type != DEFINE) { 233 (void) cstr(token, 1, SSIZE); /* skip the definition too */ 234 return; 235 } 236 p1 = strsave(token); 237 if (cstr(token, 1, SSIZE)) 238 error(FATAL, gettext( 239 "Unterminated definition at %.20s"), token); 240 p2 = strsave(token); 241 lookup(deftbl, p1, p2); 242 if (dbg) printf(".\tname %s defined as %s\n", p1, p2); 243 } 244 245 char *spaceval = NULL; 246 247 void 248 space(void) /* collect line of form "space amt" to replace \x in output */ 249 { 250 char *strsave(); 251 252 getstr(token, SSIZE); 253 spaceval = strsave(token); 254 if (dbg) printf(".\tsetting space to %s\n", token); 255 } 256 257 258 char * 259 strsave(char *s) 260 { 261 char *malloc(); 262 char *q; 263 264 q = malloc(strlen(s)+1); 265 if (q == NULL) 266 error(FATAL, gettext("out of space in strsave on %s"), s); 267 strcpy(q, s); 268 return (q); 269 } 270 271 void 272 include(void) 273 { 274 error(!FATAL, gettext("Include not yet implemented")); 275 } 276 277 void 278 delim(void) 279 { 280 yyval = eqnreg = 0; 281 if (cstr(token, 0, SSIZE)) 282 error(FATAL, gettext("Bizarre delimiters at %.20s"), token); 283 lefteq = token[0]; 284 righteq = token[1]; 285 if (lefteq == 'o' && righteq == 'f') 286 lefteq = righteq = '\0'; 287 } 288