1785Speter /* Copyright (c) 1979 Regents of the University of California */ 2785Speter 315943Smckusick #ifndef lint 4*15944Smckusick static char sccsid[] = "@(#)yyget.c 1.6 02/04/84"; 515943Smckusick #endif 6785Speter 7785Speter #include "whoami.h" 8785Speter #include "0.h" 915943Smckusick #include "tree_ty.h" /* must be included for yy.h */ 10785Speter #include "yy.h" 11785Speter 12785Speter #ifdef PXP 13785Speter int yytokcnt; 14785Speter #endif 15785Speter 16785Speter /* 17785Speter * Readch returns the next 18785Speter * character from the current 19785Speter * input line or -1 on end-of-file. 20785Speter * It also maintains yycol for use in 21785Speter * printing error messages. 22785Speter */ 23785Speter readch() 24785Speter { 2515943Smckusick register c; 26785Speter 27785Speter if (*bufp == '\n' && bufp >= charbuf) { 28785Speter #ifdef PXP 29785Speter yytokcnt = 0; 30785Speter #endif 31785Speter if (getline() < 0) 32785Speter return (-1); 33785Speter } 34785Speter c = *++bufp; 35785Speter if (c == '\t') 36785Speter yycol = ((yycol + 8) & ~7); 37785Speter else 38785Speter yycol++; 39785Speter return (c); 40785Speter } 41785Speter 42785Speter /* 43785Speter * Definitions of the structures used for the 44785Speter * include facility. The variable "ibp" points 45785Speter * to the getc buffer of the current input file. 46785Speter * There are "inclev + 1" current include files, 47785Speter * and information in saved in the incs stack 48785Speter * whenever a new level of include nesting occurs. 49785Speter * 50785Speter * Ibp in the incs structure saves the pointer 51785Speter * to the previous levels input buffer; 52785Speter * filename saves the previous file name; 53785Speter * Printed saves whether the previous file name 54785Speter * had been printed before this nesting occurred; 55785Speter * and yyline is the line we were on on the previous file. 56785Speter */ 57785Speter 58785Speter #define MAXINC 10 59785Speter 60785Speter struct inc { 61785Speter FILE *ibp; 62785Speter char *filename; 63785Speter int Printed; 64785Speter int yyline; 65785Speter int yyLinpt; 66785Speter } incs[MAXINC]; 67785Speter 6812394Speter extern char printed; 69785Speter 70785Speter int inclev = -1; 71785Speter 72785Speter #ifdef PXP 73785Speter /* 74785Speter * These initializations survive only if 75785Speter * pxp is asked to pretty print one file. 76785Speter * Otherwise they are destroyed by the initial 77785Speter * call to getline. 78785Speter */ 79785Speter char charbuf[CBSIZE] = " program x(output);\n"; 80785Speter int yycol = 8; 81785Speter char *bufp = charbuf; 82785Speter 83785Speter #endif 84785Speter /* 85785Speter * YyLinpt is the seek pointer to the beginning of the 86785Speter * next line in the file. 87785Speter */ 88785Speter int yyLinpt; 89785Speter 90785Speter /* 91785Speter * Getline places the next line 92785Speter * from the input stream in the 93785Speter * line buffer, returning -1 at YEOF. 94785Speter */ 95785Speter getline() 96785Speter { 97785Speter register char *cp; 98785Speter register CHAR c; 99785Speter #ifdef PXP 100785Speter static char ateof; 101785Speter #endif 102785Speter register FILE *ib; 103785Speter int i; 104785Speter 105785Speter if (opt('l') && yyprtd == 0) 106785Speter yyoutline(); 107785Speter yyprtd = 0; 108785Speter top: 109785Speter yylinpt = yyLinpt; 110785Speter yyline++; 111785Speter yyseqid++; 112785Speter cp = charbuf; 113785Speter ib = ibp; 114785Speter i = sizeof charbuf - 1; 115785Speter for (;;) { 116785Speter c = getc(ib); 117785Speter if (c == EOF) { 118785Speter if (uninclud()) 119785Speter goto top; 120785Speter #ifdef PXP 121785Speter if (ateof == 0 && bracket) { 12215943Smckusick (void) pstrcpy(charbuf, "begin end.\n"); 123785Speter ateof = 1; 124785Speter goto out; 125785Speter } 126785Speter #endif 127785Speter bufp = "\n"; 128785Speter yyline--; 129785Speter yyseqid--; 130785Speter yyprtd = 1; 131785Speter return (-1); 132785Speter } 133785Speter *cp++ = c; 134785Speter if (c == '\n') 135785Speter break; 136785Speter if (--i == 0) { 137785Speter line = yyline; 138785Speter error("Input line too long - QUIT"); 139785Speter pexit(DIED); 140785Speter } 141785Speter } 142785Speter *cp = 0; 143785Speter yyLinpt = yylinpt + cp - charbuf; 144785Speter if (includ()) 145785Speter goto top; 146785Speter #ifdef PXP 147785Speter if (cp == &charbuf[1]) 148785Speter commnl(); 149785Speter else if (cp == &charbuf[2]) 150785Speter switch (charbuf[0]) { 151785Speter case ' ': 152785Speter commnlbl(); 153785Speter break; 154785Speter case '\f': 155785Speter commform(); 156785Speter } 157785Speter #endif 158785Speter if (opt('u')) 159785Speter setuflg(); 16015943Smckusick #ifdef PXP 161785Speter out: 16215943Smckusick #endif 163785Speter bufp = charbuf - 1; 164785Speter yycol = 8; 165785Speter return (1); 166785Speter } 167785Speter 168785Speter /* 169785Speter * Check an input line to see if it is a "#include" pseudo-statement. 170785Speter * We allow arbitrary blanks in the line and the file name 171785Speter * may be delimited by either 's or "s. A single semicolon 172785Speter * may be placed after the name, but nothing else is allowed 173785Speter */ 174785Speter includ() 175785Speter { 176785Speter register char *cp, *dp; 177785Speter char ch; 178785Speter register struct inc *ip; 179785Speter 180785Speter cp = charbuf; 181785Speter if (*cp++ != '#') 182785Speter return (0); 183785Speter cp = skipbl(cp); 184785Speter for (dp = "include"; *dp; dp++) 185785Speter if (*dp != *cp++) 186785Speter return (0); 187785Speter line = yyline; 188785Speter cp = skipbl(cp); 189785Speter ch = *cp++; 190785Speter if (ch != '\'' && ch != '"') { 191785Speter /* 192785Speter * This should be a yerror flagging the place 193785Speter * but its not worth figuring out the column. 194785Speter */ 195785Speter line = yyline; 196785Speter error("Include syntax error - expected ' or \" not found - QUIT"); 197785Speter pexit(DIED); 198785Speter } 199785Speter for (dp = cp; *dp != ch; dp++) 200785Speter if (*dp == 0) { 201785Speter line = yyline; 20215943Smckusick error("Missing closing %c for include file name - QUIT", (char *) ch); 203785Speter pexit(DIED); 204785Speter } 205785Speter *dp++ = 0; 206785Speter /* 207785Speter * if (*dp == ';') 208785Speter * dp++; 209785Speter * dp = skipbl(dp); 210785Speter * if (*dp != '\n') { 211785Speter * line = yyline; 212785Speter * error("Garbage after filename in include"); 213785Speter * pexit(DIED); 214785Speter * } 215785Speter */ 21612394Speter if (!dotted(cp, 'i') && !dotted(cp, 'h')) { 217785Speter line = yyline; 218785Speter error("Include filename must end in .i or .h"); 219785Speter } 220785Speter #ifdef PXP 221785Speter commincl(cp, ch); 222785Speter if (noinclude) 223785Speter return (1); 224785Speter #endif 225785Speter inclev++; 226785Speter if (inclev > MAXINC) { 227785Speter line = yyline; 228785Speter error("Absurdly deep include nesting - QUIT"); 229785Speter pexit(DIED); 230785Speter } 231785Speter ip = &incs[inclev]; 232785Speter ip->filename = filename; 233785Speter filename = savestr(cp); 2345654Slinton 2355654Slinton #ifdef OBJ 236785Speter /* 2375654Slinton * For the debugger pdx, we need to note that we've changed files. 2385654Slinton */ 2395654Slinton newfile(filename, 1); 2405654Slinton #endif 2415654Slinton 2425654Slinton /* 243785Speter * left over from before stdio 244785Speter * 245785Speter * cp = malloc(518); 246785Speter * if (cp == -1) { 247785Speter * error("Ran out of memory (include)"); 248785Speter * pexit(DIED); 249785Speter * } 250785Speter * 251785Speter */ 252785Speter ip->ibp = ibp; 253785Speter if ( ( ibp = fopen(filename, "r" ) ) == NULL ) { 254785Speter perror(filename); 255785Speter pexit(DIED); 256785Speter } 257785Speter if (inpflist(filename)) { 258785Speter #ifdef PI 259785Speter opush('l'); 260785Speter #endif 261785Speter #ifdef PXP 262785Speter opush('z'); 263785Speter #endif 264785Speter } 265785Speter ip->Printed = printed; 266785Speter printed = 0; 267785Speter ip->yyline = yyline; 268785Speter yyline = 0; 269785Speter ip->yyLinpt = yyLinpt; 270785Speter yyLinpt = 0; 271785Speter /* 272785Speter * left over from before stdio 273785Speter * 274785Speter * ip->ibp = ibp; 275785Speter * ibp = cp; 276785Speter * 277785Speter */ 278785Speter # ifdef PC 279*15944Smckusick stabinclude( filename , TRUE ); 280785Speter # endif PC 281785Speter return (1); 282785Speter } 283785Speter 28415943Smckusick char * 285785Speter skipbl(ocp) 286785Speter char *ocp; 287785Speter { 288785Speter register char *cp; 289785Speter 290785Speter cp = ocp; 291785Speter while (*cp == ' ' || *cp == '\t') 292785Speter cp++; 293785Speter return (cp); 294785Speter } 295785Speter 296785Speter 297785Speter /* 298785Speter * At the end of an include, 299785Speter * close the file, free the input buffer, 300785Speter * and restore the environment before 301785Speter * the "push", including the value of 302785Speter * the z option for pxp and the l option for pi. 303785Speter */ 304785Speter uninclud() 305785Speter { 306785Speter register struct inc *ip; 307785Speter 308785Speter if (inclev < 0) 309785Speter return (0); 310785Speter /* 311785Speter * left over from before stdio: becomes fclose ( ibp ) 312785Speter * 31315943Smckusick * (void) close(ibp[0]); 314785Speter * free(ibp); 315785Speter * 316785Speter */ 31715943Smckusick (void) fclose ( ibp ); 318785Speter ip = &incs[inclev]; 319785Speter ibp = ip->ibp; 320785Speter yyline = ip->yyline; 321785Speter if (inpflist(filename)) { 322785Speter #ifdef PI 323785Speter opop('l'); 324785Speter #endif 325785Speter #ifdef PXP 326785Speter opop('z'); 327785Speter #endif 328785Speter } 329785Speter filename = ip->filename; 3305654Slinton 331785Speter yyLinpt = ip->yyLinpt; 332785Speter /* 333785Speter * If we printed out the nested name, 334785Speter * then we should print all covered names again. 335785Speter * If we didn't print out the nested name 336785Speter * we print the uncovered name only if it 337785Speter * has not been printed before (unstack). 338785Speter */ 339785Speter if (printed) { 340785Speter printed = 0; 341785Speter while (ip >= incs) { 342785Speter ip->Printed = 0; 343785Speter ip--; 344785Speter } 345785Speter } else 346785Speter printed = ip->Printed; 3475757Slinton # ifdef OBJ 3485757Slinton /* 3495757Slinton * For the debugger pdx, we need to note that we've changed files. 3505757Slinton */ 3515757Slinton newfile(filename, yyline); 3525757Slinton #endif 353785Speter # ifdef PC 354785Speter if ( inclev == 0 ) { 355785Speter stabsource( filename ); 356785Speter } else { 357*15944Smckusick stabinclude( filename , FALSE ); 358785Speter } 359785Speter # endif PC 360785Speter inclev--; 361785Speter return (1); 362785Speter } 363