1 /*- 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)yyget.c 5.3 (Berkeley) 04/16/91"; 10 #endif /* not lint */ 11 12 #include "whoami.h" 13 #include <0.h> 14 #include "tree_ty.h" /* must be included for yy.h */ 15 #include "yy.h" 16 17 #ifdef PXP 18 int yytokcnt; 19 #endif 20 21 /* 22 * Readch returns the next 23 * character from the current 24 * input line or -1 on end-of-file. 25 * It also maintains yycol for use in 26 * printing error messages. 27 */ 28 readch() 29 { 30 register c; 31 32 if (*bufp == '\n' && bufp >= charbuf) { 33 #ifdef PXP 34 yytokcnt = 0; 35 #endif 36 if (getline() < 0) 37 return (-1); 38 } 39 c = *++bufp; 40 if (c == '\t') 41 yycol = ((yycol + 8) & ~7); 42 else 43 yycol++; 44 return (c); 45 } 46 47 /* 48 * Definitions of the structures used for the 49 * include facility. The variable "ibp" points 50 * to the getc buffer of the current input file. 51 * There are "inclev + 1" current include files, 52 * and information in saved in the incs stack 53 * whenever a new level of include nesting occurs. 54 * 55 * Ibp in the incs structure saves the pointer 56 * to the previous levels input buffer; 57 * filename saves the previous file name; 58 * Printed saves whether the previous file name 59 * had been printed before this nesting occurred; 60 * and yyline is the line we were on on the previous file. 61 */ 62 63 #define MAXINC 10 64 65 struct inc { 66 FILE *ibp; 67 char *filename; 68 int Printed; 69 int yyline; 70 int yyLinpt; 71 } incs[MAXINC]; 72 73 extern char printed; 74 75 int inclev = -1; 76 77 #ifdef PXP 78 /* 79 * These initializations survive only if 80 * pxp is asked to pretty print one file. 81 * Otherwise they are destroyed by the initial 82 * call to getline. 83 */ 84 char charbuf[CBSIZE] = " program x(output);\n"; 85 int yycol = 8; 86 char *bufp = charbuf; 87 88 #endif 89 /* 90 * YyLinpt is the seek pointer to the beginning of the 91 * next line in the file. 92 */ 93 int yyLinpt; 94 95 /* 96 * Getline places the next line 97 * from the input stream in the 98 * line buffer, returning -1 at YEOF. 99 */ 100 getline() 101 { 102 register char *cp; 103 register CHAR c; 104 #ifdef PXP 105 static char ateof; 106 #endif 107 register FILE *ib; 108 int i; 109 110 if (opt('l') && yyprtd == 0) 111 yyoutline(); 112 yyprtd = 0; 113 top: 114 yylinpt = yyLinpt; 115 yyline++; 116 yyseqid++; 117 cp = charbuf; 118 ib = ibp; 119 i = sizeof charbuf - 1; 120 for (;;) { 121 c = getc(ib); 122 if (c == EOF) { 123 if (uninclud()) 124 goto top; 125 #ifdef PXP 126 if (ateof == 0 && bracket) { 127 (void) pstrcpy(charbuf, "begin end.\n"); 128 ateof = 1; 129 goto out; 130 } 131 #endif 132 bufp = "\n"; 133 yyline--; 134 yyseqid--; 135 yyprtd = 1; 136 return (-1); 137 } 138 *cp++ = c; 139 if (c == '\n') 140 break; 141 if (--i == 0) { 142 line = yyline; 143 error("Input line too long - QUIT"); 144 pexit(DIED); 145 } 146 } 147 *cp = 0; 148 yyLinpt = yylinpt + cp - charbuf; 149 if (includ()) 150 goto top; 151 #ifdef PXP 152 if (cp == &charbuf[1]) 153 commnl(); 154 else if (cp == &charbuf[2]) 155 switch (charbuf[0]) { 156 case ' ': 157 commnlbl(); 158 break; 159 case '\f': 160 commform(); 161 } 162 #endif 163 if (opt('u')) 164 setuflg(); 165 #ifdef PXP 166 out: 167 #endif 168 bufp = charbuf - 1; 169 yycol = 8; 170 return (1); 171 } 172 173 /* 174 * Check an input line to see if it is a "#include" pseudo-statement. 175 * We allow arbitrary blanks in the line and the file name 176 * may be delimited by either 's or "s. A single semicolon 177 * may be placed after the name, but nothing else is allowed 178 */ 179 includ() 180 { 181 register char *cp, *dp; 182 char ch; 183 register struct inc *ip; 184 185 cp = charbuf; 186 if (*cp++ != '#') 187 return (0); 188 cp = skipbl(cp); 189 for (dp = "include"; *dp; dp++) 190 if (*dp != *cp++) 191 return (0); 192 line = yyline; 193 cp = skipbl(cp); 194 ch = *cp++; 195 if (ch != '\'' && ch != '"') { 196 /* 197 * This should be a yerror flagging the place 198 * but its not worth figuring out the column. 199 */ 200 line = yyline; 201 error("Include syntax error - expected ' or \" not found - QUIT"); 202 pexit(DIED); 203 } 204 for (dp = cp; *dp != ch; dp++) 205 if (*dp == 0) { 206 line = yyline; 207 error("Missing closing %c for include file name - QUIT", (char *) ch); 208 pexit(DIED); 209 } 210 *dp++ = 0; 211 /* 212 * if (*dp == ';') 213 * dp++; 214 * dp = skipbl(dp); 215 * if (*dp != '\n') { 216 * line = yyline; 217 * error("Garbage after filename in include"); 218 * pexit(DIED); 219 * } 220 */ 221 if (!dotted(cp, 'i') && !dotted(cp, 'h')) { 222 line = yyline; 223 error("Include filename must end in .i or .h"); 224 } 225 #ifdef PXP 226 commincl(cp, ch); 227 if (noinclude) 228 return (1); 229 #endif 230 inclev++; 231 if (inclev > MAXINC) { 232 line = yyline; 233 error("Absurdly deep include nesting - QUIT"); 234 pexit(DIED); 235 } 236 ip = &incs[inclev]; 237 ip->filename = filename; 238 filename = savestr(cp); 239 240 #ifdef OBJ 241 /* 242 * For the debugger pdx, we need to note that we've changed files. 243 */ 244 newfile(filename, 1); 245 #endif 246 247 /* 248 * left over from before stdio 249 * 250 * cp = malloc(518); 251 * if (cp == -1) { 252 * error("Ran out of memory (include)"); 253 * pexit(DIED); 254 * } 255 * 256 */ 257 ip->ibp = ibp; 258 if ( ( ibp = fopen(filename, "r" ) ) == NULL ) { 259 perror(filename); 260 pexit(DIED); 261 } 262 if (inpflist(filename)) { 263 #ifdef PI 264 opush('l'); 265 #endif 266 #ifdef PXP 267 opush('z'); 268 #endif 269 } 270 ip->Printed = printed; 271 printed = 0; 272 ip->yyline = yyline; 273 yyline = 0; 274 ip->yyLinpt = yyLinpt; 275 yyLinpt = 0; 276 /* 277 * left over from before stdio 278 * 279 * ip->ibp = ibp; 280 * ibp = cp; 281 * 282 */ 283 # ifdef PC 284 stabinclude( filename , TRUE ); 285 # endif PC 286 return (1); 287 } 288 289 char * 290 skipbl(ocp) 291 char *ocp; 292 { 293 register char *cp; 294 295 cp = ocp; 296 while (*cp == ' ' || *cp == '\t') 297 cp++; 298 return (cp); 299 } 300 301 302 /* 303 * At the end of an include, 304 * close the file, free the input buffer, 305 * and restore the environment before 306 * the "push", including the value of 307 * the z option for pxp and the l option for pi. 308 */ 309 uninclud() 310 { 311 register struct inc *ip; 312 313 if (inclev < 0) 314 return (0); 315 /* 316 * left over from before stdio: becomes fclose ( ibp ) 317 * 318 * (void) close(ibp[0]); 319 * free(ibp); 320 * 321 */ 322 (void) fclose ( ibp ); 323 ip = &incs[inclev]; 324 ibp = ip->ibp; 325 yyline = ip->yyline; 326 if (inpflist(filename)) { 327 #ifdef PI 328 opop('l'); 329 #endif 330 #ifdef PXP 331 opop('z'); 332 #endif 333 } 334 filename = ip->filename; 335 336 yyLinpt = ip->yyLinpt; 337 /* 338 * If we printed out the nested name, 339 * then we should print all covered names again. 340 * If we didn't print out the nested name 341 * we print the uncovered name only if it 342 * has not been printed before (unstack). 343 */ 344 if (printed) { 345 printed = 0; 346 while (ip >= incs) { 347 ip->Printed = 0; 348 ip--; 349 } 350 } else 351 printed = ip->Printed; 352 # ifdef OBJ 353 /* 354 * For the debugger pdx, we need to note that we've changed files. 355 */ 356 newfile(filename, yyline); 357 #endif 358 # ifdef PC 359 if ( inclev == 0 ) { 360 stabsource( filename ); 361 } else { 362 stabinclude( filename , FALSE ); 363 } 364 # endif PC 365 inclev--; 366 return (1); 367 } 368