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