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