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