1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)yyget.c 1.1 08/27/80"; 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 * left over from before stdio 231 * 232 * cp = malloc(518); 233 * if (cp == -1) { 234 * error("Ran out of memory (include)"); 235 * pexit(DIED); 236 * } 237 * 238 */ 239 ip->ibp = ibp; 240 if ( ( ibp = fopen(filename, "r" ) ) == NULL ) { 241 perror(filename); 242 pexit(DIED); 243 } 244 if (inpflist(filename)) { 245 #ifdef PI 246 opush('l'); 247 #endif 248 #ifdef PXP 249 opush('z'); 250 #endif 251 } 252 ip->Printed = printed; 253 printed = 0; 254 ip->yyline = yyline; 255 yyline = 0; 256 ip->yyLinpt = yyLinpt; 257 yyLinpt = 0; 258 /* 259 * left over from before stdio 260 * 261 * ip->ibp = ibp; 262 * ibp = cp; 263 * 264 */ 265 # ifdef PC 266 stabinclude( filename ); 267 # endif PC 268 return (1); 269 } 270 271 skipbl(ocp) 272 char *ocp; 273 { 274 register char *cp; 275 276 cp = ocp; 277 while (*cp == ' ' || *cp == '\t') 278 cp++; 279 return (cp); 280 } 281 282 283 /* 284 * At the end of an include, 285 * close the file, free the input buffer, 286 * and restore the environment before 287 * the "push", including the value of 288 * the z option for pxp and the l option for pi. 289 */ 290 uninclud() 291 { 292 register struct inc *ip; 293 294 if (inclev < 0) 295 return (0); 296 /* 297 * left over from before stdio: becomes fclose ( ibp ) 298 * 299 * close(ibp[0]); 300 * free(ibp); 301 * 302 */ 303 fclose ( ibp ); 304 ip = &incs[inclev]; 305 ibp = ip->ibp; 306 yyline = ip->yyline; 307 if (inpflist(filename)) { 308 #ifdef PI 309 opop('l'); 310 #endif 311 #ifdef PXP 312 opop('z'); 313 #endif 314 } 315 filename = ip->filename; 316 yyLinpt = ip->yyLinpt; 317 /* 318 * If we printed out the nested name, 319 * then we should print all covered names again. 320 * If we didn't print out the nested name 321 * we print the uncovered name only if it 322 * has not been printed before (unstack). 323 */ 324 if (printed) { 325 printed = 0; 326 while (ip >= incs) { 327 ip->Printed = 0; 328 ip--; 329 } 330 } else 331 printed = ip->Printed; 332 # ifdef PC 333 if ( inclev == 0 ) { 334 stabsource( filename ); 335 } else { 336 stabinclude( filename ); 337 } 338 # endif PC 339 inclev--; 340 return (1); 341 } 342