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