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