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