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