1*48112Sbostic /*- 2*48112Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48112Sbostic * All rights reserved. 4*48112Sbostic * 5*48112Sbostic * %sccs.include.redist.c% 648111Sbostic */ 748111Sbostic 848111Sbostic #ifndef lint 9*48112Sbostic static char sccsid[] = "@(#)yyget.c 5.3 (Berkeley) 04/16/91"; 10*48112Sbostic #endif /* not lint */ 1148111Sbostic 1248111Sbostic #include "whoami.h" 1348111Sbostic #include <0.h> 1448111Sbostic #include "tree_ty.h" /* must be included for yy.h */ 1548111Sbostic #include "yy.h" 1648111Sbostic 1748111Sbostic #ifdef PXP 1848111Sbostic int yytokcnt; 1948111Sbostic #endif 2048111Sbostic 2148111Sbostic /* 2248111Sbostic * Readch returns the next 2348111Sbostic * character from the current 2448111Sbostic * input line or -1 on end-of-file. 2548111Sbostic * It also maintains yycol for use in 2648111Sbostic * printing error messages. 2748111Sbostic */ 2848111Sbostic readch() 2948111Sbostic { 3048111Sbostic register c; 3148111Sbostic 3248111Sbostic if (*bufp == '\n' && bufp >= charbuf) { 3348111Sbostic #ifdef PXP 3448111Sbostic yytokcnt = 0; 3548111Sbostic #endif 3648111Sbostic if (getline() < 0) 3748111Sbostic return (-1); 3848111Sbostic } 3948111Sbostic c = *++bufp; 4048111Sbostic if (c == '\t') 4148111Sbostic yycol = ((yycol + 8) & ~7); 4248111Sbostic else 4348111Sbostic yycol++; 4448111Sbostic return (c); 4548111Sbostic } 4648111Sbostic 4748111Sbostic /* 4848111Sbostic * Definitions of the structures used for the 4948111Sbostic * include facility. The variable "ibp" points 5048111Sbostic * to the getc buffer of the current input file. 5148111Sbostic * There are "inclev + 1" current include files, 5248111Sbostic * and information in saved in the incs stack 5348111Sbostic * whenever a new level of include nesting occurs. 5448111Sbostic * 5548111Sbostic * Ibp in the incs structure saves the pointer 5648111Sbostic * to the previous levels input buffer; 5748111Sbostic * filename saves the previous file name; 5848111Sbostic * Printed saves whether the previous file name 5948111Sbostic * had been printed before this nesting occurred; 6048111Sbostic * and yyline is the line we were on on the previous file. 6148111Sbostic */ 6248111Sbostic 6348111Sbostic #define MAXINC 10 6448111Sbostic 6548111Sbostic struct inc { 6648111Sbostic FILE *ibp; 6748111Sbostic char *filename; 6848111Sbostic int Printed; 6948111Sbostic int yyline; 7048111Sbostic int yyLinpt; 7148111Sbostic } incs[MAXINC]; 7248111Sbostic 7348111Sbostic extern char printed; 7448111Sbostic 7548111Sbostic int inclev = -1; 7648111Sbostic 7748111Sbostic #ifdef PXP 7848111Sbostic /* 7948111Sbostic * These initializations survive only if 8048111Sbostic * pxp is asked to pretty print one file. 8148111Sbostic * Otherwise they are destroyed by the initial 8248111Sbostic * call to getline. 8348111Sbostic */ 8448111Sbostic char charbuf[CBSIZE] = " program x(output);\n"; 8548111Sbostic int yycol = 8; 8648111Sbostic char *bufp = charbuf; 8748111Sbostic 8848111Sbostic #endif 8948111Sbostic /* 9048111Sbostic * YyLinpt is the seek pointer to the beginning of the 9148111Sbostic * next line in the file. 9248111Sbostic */ 9348111Sbostic int yyLinpt; 9448111Sbostic 9548111Sbostic /* 9648111Sbostic * Getline places the next line 9748111Sbostic * from the input stream in the 9848111Sbostic * line buffer, returning -1 at YEOF. 9948111Sbostic */ 10048111Sbostic getline() 10148111Sbostic { 10248111Sbostic register char *cp; 10348111Sbostic register CHAR c; 10448111Sbostic #ifdef PXP 10548111Sbostic static char ateof; 10648111Sbostic #endif 10748111Sbostic register FILE *ib; 10848111Sbostic int i; 10948111Sbostic 11048111Sbostic if (opt('l') && yyprtd == 0) 11148111Sbostic yyoutline(); 11248111Sbostic yyprtd = 0; 11348111Sbostic top: 11448111Sbostic yylinpt = yyLinpt; 11548111Sbostic yyline++; 11648111Sbostic yyseqid++; 11748111Sbostic cp = charbuf; 11848111Sbostic ib = ibp; 11948111Sbostic i = sizeof charbuf - 1; 12048111Sbostic for (;;) { 12148111Sbostic c = getc(ib); 12248111Sbostic if (c == EOF) { 12348111Sbostic if (uninclud()) 12448111Sbostic goto top; 12548111Sbostic #ifdef PXP 12648111Sbostic if (ateof == 0 && bracket) { 12748111Sbostic (void) pstrcpy(charbuf, "begin end.\n"); 12848111Sbostic ateof = 1; 12948111Sbostic goto out; 13048111Sbostic } 13148111Sbostic #endif 13248111Sbostic bufp = "\n"; 13348111Sbostic yyline--; 13448111Sbostic yyseqid--; 13548111Sbostic yyprtd = 1; 13648111Sbostic return (-1); 13748111Sbostic } 13848111Sbostic *cp++ = c; 13948111Sbostic if (c == '\n') 14048111Sbostic break; 14148111Sbostic if (--i == 0) { 14248111Sbostic line = yyline; 14348111Sbostic error("Input line too long - QUIT"); 14448111Sbostic pexit(DIED); 14548111Sbostic } 14648111Sbostic } 14748111Sbostic *cp = 0; 14848111Sbostic yyLinpt = yylinpt + cp - charbuf; 14948111Sbostic if (includ()) 15048111Sbostic goto top; 15148111Sbostic #ifdef PXP 15248111Sbostic if (cp == &charbuf[1]) 15348111Sbostic commnl(); 15448111Sbostic else if (cp == &charbuf[2]) 15548111Sbostic switch (charbuf[0]) { 15648111Sbostic case ' ': 15748111Sbostic commnlbl(); 15848111Sbostic break; 15948111Sbostic case '\f': 16048111Sbostic commform(); 16148111Sbostic } 16248111Sbostic #endif 16348111Sbostic if (opt('u')) 16448111Sbostic setuflg(); 16548111Sbostic #ifdef PXP 16648111Sbostic out: 16748111Sbostic #endif 16848111Sbostic bufp = charbuf - 1; 16948111Sbostic yycol = 8; 17048111Sbostic return (1); 17148111Sbostic } 17248111Sbostic 17348111Sbostic /* 17448111Sbostic * Check an input line to see if it is a "#include" pseudo-statement. 17548111Sbostic * We allow arbitrary blanks in the line and the file name 17648111Sbostic * may be delimited by either 's or "s. A single semicolon 17748111Sbostic * may be placed after the name, but nothing else is allowed 17848111Sbostic */ 17948111Sbostic includ() 18048111Sbostic { 18148111Sbostic register char *cp, *dp; 18248111Sbostic char ch; 18348111Sbostic register struct inc *ip; 18448111Sbostic 18548111Sbostic cp = charbuf; 18648111Sbostic if (*cp++ != '#') 18748111Sbostic return (0); 18848111Sbostic cp = skipbl(cp); 18948111Sbostic for (dp = "include"; *dp; dp++) 19048111Sbostic if (*dp != *cp++) 19148111Sbostic return (0); 19248111Sbostic line = yyline; 19348111Sbostic cp = skipbl(cp); 19448111Sbostic ch = *cp++; 19548111Sbostic if (ch != '\'' && ch != '"') { 19648111Sbostic /* 19748111Sbostic * This should be a yerror flagging the place 19848111Sbostic * but its not worth figuring out the column. 19948111Sbostic */ 20048111Sbostic line = yyline; 20148111Sbostic error("Include syntax error - expected ' or \" not found - QUIT"); 20248111Sbostic pexit(DIED); 20348111Sbostic } 20448111Sbostic for (dp = cp; *dp != ch; dp++) 20548111Sbostic if (*dp == 0) { 20648111Sbostic line = yyline; 20748111Sbostic error("Missing closing %c for include file name - QUIT", (char *) ch); 20848111Sbostic pexit(DIED); 20948111Sbostic } 21048111Sbostic *dp++ = 0; 21148111Sbostic /* 21248111Sbostic * if (*dp == ';') 21348111Sbostic * dp++; 21448111Sbostic * dp = skipbl(dp); 21548111Sbostic * if (*dp != '\n') { 21648111Sbostic * line = yyline; 21748111Sbostic * error("Garbage after filename in include"); 21848111Sbostic * pexit(DIED); 21948111Sbostic * } 22048111Sbostic */ 22148111Sbostic if (!dotted(cp, 'i') && !dotted(cp, 'h')) { 22248111Sbostic line = yyline; 22348111Sbostic error("Include filename must end in .i or .h"); 22448111Sbostic } 22548111Sbostic #ifdef PXP 22648111Sbostic commincl(cp, ch); 22748111Sbostic if (noinclude) 22848111Sbostic return (1); 22948111Sbostic #endif 23048111Sbostic inclev++; 23148111Sbostic if (inclev > MAXINC) { 23248111Sbostic line = yyline; 23348111Sbostic error("Absurdly deep include nesting - QUIT"); 23448111Sbostic pexit(DIED); 23548111Sbostic } 23648111Sbostic ip = &incs[inclev]; 23748111Sbostic ip->filename = filename; 23848111Sbostic filename = savestr(cp); 23948111Sbostic 24048111Sbostic #ifdef OBJ 24148111Sbostic /* 24248111Sbostic * For the debugger pdx, we need to note that we've changed files. 24348111Sbostic */ 24448111Sbostic newfile(filename, 1); 24548111Sbostic #endif 24648111Sbostic 24748111Sbostic /* 24848111Sbostic * left over from before stdio 24948111Sbostic * 25048111Sbostic * cp = malloc(518); 25148111Sbostic * if (cp == -1) { 25248111Sbostic * error("Ran out of memory (include)"); 25348111Sbostic * pexit(DIED); 25448111Sbostic * } 25548111Sbostic * 25648111Sbostic */ 25748111Sbostic ip->ibp = ibp; 25848111Sbostic if ( ( ibp = fopen(filename, "r" ) ) == NULL ) { 25948111Sbostic perror(filename); 26048111Sbostic pexit(DIED); 26148111Sbostic } 26248111Sbostic if (inpflist(filename)) { 26348111Sbostic #ifdef PI 26448111Sbostic opush('l'); 26548111Sbostic #endif 26648111Sbostic #ifdef PXP 26748111Sbostic opush('z'); 26848111Sbostic #endif 26948111Sbostic } 27048111Sbostic ip->Printed = printed; 27148111Sbostic printed = 0; 27248111Sbostic ip->yyline = yyline; 27348111Sbostic yyline = 0; 27448111Sbostic ip->yyLinpt = yyLinpt; 27548111Sbostic yyLinpt = 0; 27648111Sbostic /* 27748111Sbostic * left over from before stdio 27848111Sbostic * 27948111Sbostic * ip->ibp = ibp; 28048111Sbostic * ibp = cp; 28148111Sbostic * 28248111Sbostic */ 28348111Sbostic # ifdef PC 28448111Sbostic stabinclude( filename , TRUE ); 28548111Sbostic # endif PC 28648111Sbostic return (1); 28748111Sbostic } 28848111Sbostic 28948111Sbostic char * 29048111Sbostic skipbl(ocp) 29148111Sbostic char *ocp; 29248111Sbostic { 29348111Sbostic register char *cp; 29448111Sbostic 29548111Sbostic cp = ocp; 29648111Sbostic while (*cp == ' ' || *cp == '\t') 29748111Sbostic cp++; 29848111Sbostic return (cp); 29948111Sbostic } 30048111Sbostic 30148111Sbostic 30248111Sbostic /* 30348111Sbostic * At the end of an include, 30448111Sbostic * close the file, free the input buffer, 30548111Sbostic * and restore the environment before 30648111Sbostic * the "push", including the value of 30748111Sbostic * the z option for pxp and the l option for pi. 30848111Sbostic */ 30948111Sbostic uninclud() 31048111Sbostic { 31148111Sbostic register struct inc *ip; 31248111Sbostic 31348111Sbostic if (inclev < 0) 31448111Sbostic return (0); 31548111Sbostic /* 31648111Sbostic * left over from before stdio: becomes fclose ( ibp ) 31748111Sbostic * 31848111Sbostic * (void) close(ibp[0]); 31948111Sbostic * free(ibp); 32048111Sbostic * 32148111Sbostic */ 32248111Sbostic (void) fclose ( ibp ); 32348111Sbostic ip = &incs[inclev]; 32448111Sbostic ibp = ip->ibp; 32548111Sbostic yyline = ip->yyline; 32648111Sbostic if (inpflist(filename)) { 32748111Sbostic #ifdef PI 32848111Sbostic opop('l'); 32948111Sbostic #endif 33048111Sbostic #ifdef PXP 33148111Sbostic opop('z'); 33248111Sbostic #endif 33348111Sbostic } 33448111Sbostic filename = ip->filename; 33548111Sbostic 33648111Sbostic yyLinpt = ip->yyLinpt; 33748111Sbostic /* 33848111Sbostic * If we printed out the nested name, 33948111Sbostic * then we should print all covered names again. 34048111Sbostic * If we didn't print out the nested name 34148111Sbostic * we print the uncovered name only if it 34248111Sbostic * has not been printed before (unstack). 34348111Sbostic */ 34448111Sbostic if (printed) { 34548111Sbostic printed = 0; 34648111Sbostic while (ip >= incs) { 34748111Sbostic ip->Printed = 0; 34848111Sbostic ip--; 34948111Sbostic } 35048111Sbostic } else 35148111Sbostic printed = ip->Printed; 35248111Sbostic # ifdef OBJ 35348111Sbostic /* 35448111Sbostic * For the debugger pdx, we need to note that we've changed files. 35548111Sbostic */ 35648111Sbostic newfile(filename, yyline); 35748111Sbostic #endif 35848111Sbostic # ifdef PC 35948111Sbostic if ( inclev == 0 ) { 36048111Sbostic stabsource( filename ); 36148111Sbostic } else { 36248111Sbostic stabinclude( filename , FALSE ); 36348111Sbostic } 36448111Sbostic # endif PC 36548111Sbostic inclev--; 36648111Sbostic return (1); 36748111Sbostic } 368