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