1*12391Speter static char *sccsid = "@(#)yyput.c 1.3 (Berkeley) 05/11/83"; 22871Speter /* Copyright (c) 1979 Regents of the University of California */ 32871Speter # 42871Speter /* 52871Speter * pi - Pascal interpreter code translator 62871Speter * 72871Speter * Charles Haley, Bill Joy UCB 82871Speter * Version 1.2 January 1979 92871Speter * 102871Speter * 112871Speter * pxp - Pascal execution profiler 122871Speter * 132871Speter * Bill Joy UCB 142871Speter * Version 1.2 January 1979 152871Speter */ 162871Speter 17*12391Speter #include "whoami.h" 182871Speter #include "0.h" 192871Speter #include "tree.h" 202871Speter #include "yy.h" 212871Speter 222871Speter /* 232871Speter * Structure describing queued listing lines during the forward move 242871Speter * of error recovery. These lines will be stroed by yyoutline during 252871Speter * the forward move and flushed by yyoutfl or yyflush when an 262871Speter * error occurs or a program termination. 272871Speter */ 282871Speter struct B { 292871Speter int Bmagic; 302871Speter int Bline; 312871Speter int Bseekp; 322871Speter char *Bfile; 332871Speter int Bseqid; 342871Speter struct B *Bnext; 352871Speter } *bottled; 362871Speter 372871Speter /* 382871Speter * Filename gives the current input file, lastname is 392871Speter * the last filename we printed, and lastid is the seqid of the last line 402871Speter * we printed, to help us avoid printing 412871Speter * multiple copies of lines. 422871Speter */ 432871Speter extern char *filename; 442871Speter char *lastname; 452871Speter int lastid; 462871Speter 472871Speter char hadsome; 482871Speter char holdbl; 492871Speter 502871Speter /* 512871Speter * Print the current line in the input line 522871Speter * buffer or, in a forward move of the recovery, queue it for printing. 532871Speter */ 542871Speter yyoutline() 552871Speter { 562871Speter register struct B *bp; 572871Speter 582871Speter if (Recovery) { 592871Speter bp = tree(6, T_BOTTLE, yyline, yylinpt, filename, yyseqid); 602871Speter if (bottled != NIL) 612871Speter bp->Bnext = bottled->Bnext, bottled->Bnext = bp; 622871Speter else 632871Speter bp->Bnext = bp; 642871Speter bottled = bp; 652871Speter return; 662871Speter } 672871Speter yyoutfl(yyseqid); 682871Speter if (yyseqid != lastid) 692871Speter yyprline(charbuf, yyline, filename, yyseqid); 702871Speter } 712871Speter 722871Speter /* 732871Speter * Flush all the bottled output. 742871Speter */ 752871Speter yyflush() 762871Speter { 772871Speter 782871Speter yyoutfl(32767); 792871Speter } 802871Speter 812871Speter /* 822871Speter * Flush the listing to the sequence id toseqid 832871Speter */ 842871Speter yyoutfl(toseqid) 852871Speter int toseqid; 862871Speter { 872871Speter register struct B *bp; 882871Speter 892871Speter bp = bottled; 902871Speter if (bp == NIL) 912871Speter return; 922871Speter bp = bp->Bnext; 932871Speter while (bp->Bseqid <= toseqid) { 942871Speter yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid); 952871Speter if (bp->Bnext == bp) { 962871Speter bottled = NIL; 972871Speter break; 982871Speter } 992871Speter bp = bp->Bnext; 1002871Speter bottled->Bnext = bp; 1012871Speter } 1022871Speter } 1032871Speter 1043055Smckusic int yygetunit = -1; 1052871Speter char *yygetfile; 1062871Speter 1072871Speter /* 1082871Speter * Yysync guarantees that the line associated 1092871Speter * with the current token was the last line 1102871Speter * printed for a syntactic error message. 1112871Speter */ 1122871Speter yysync() 1132871Speter { 1142871Speter 1152871Speter yyoutfl(yyeseqid); 1162871Speter if (lastid != yyeseqid) 1172871Speter yygetline(yyefile, yyseekp, yyeline, yyeseqid); 1182871Speter } 1192871Speter 1202871Speter yySsync() 1212871Speter { 1222871Speter 1232871Speter yyoutfl(OY.Yyeseqid); 1242871Speter } 1252871Speter 1262871Speter /* 1272871Speter * Yygetline gets a line from a file after we have 1282871Speter * lost it. The pointer efile gives the name of the file, 1292871Speter * seekp its offset in the file, and eline its line number. 1302871Speter * If this routine has been called before the last file 1312871Speter * it worked on will be open in yygetunit, with the files 1322871Speter * name being given in yygetfile. Note that this unit must 1332871Speter * be opened independently of the unit in use for normal i/o 1342871Speter * to this file; if it were a dup seeks would seek both files. 1352871Speter */ 1362871Speter yygetline(efile, seekp, eline, eseqid) 1372871Speter char *efile; 1382871Speter int seekp, eline, eseqid; 1392871Speter { 1402871Speter register int cnt; 1412871Speter register char *bp; 1422871Speter char buf[CBSIZE + 1]; 1432871Speter 1442871Speter if (lastid == eseqid) 1452871Speter return; 1462871Speter if (eseqid == yyseqid) { 1472871Speter bp = charbuf; 1482871Speter yyprtd++; 1492871Speter } else { 1502871Speter bp = buf; 1512871Speter if (efile != yygetfile) { 1522871Speter close(yygetunit); 1532871Speter yygetfile = efile; 1542871Speter yygetunit = open(yygetfile, 0); 1552871Speter if (yygetunit < 0) 1562871Speter oops: 1572871Speter perror(yygetfile), pexit(DIED); 1582871Speter } 1592871Speter if (lseek(yygetunit, (long)seekp, 0) < 0) 1602871Speter goto oops; 1612871Speter cnt = read(yygetunit, bp, CBSIZE); 1622871Speter if (cnt < 0) 1632871Speter goto oops; 1642871Speter bp[cnt] = 0; 1652871Speter } 1662871Speter yyprline(bp, eline, efile, eseqid); 1672871Speter } 1682871Speter 1692871Speter yyretrieve() 1702871Speter { 1712871Speter 1722871Speter yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid); 1732871Speter } 1742871Speter 1752871Speter /* 1762871Speter * Print the line in the character buffer which has 1772871Speter * line number line. The buffer may be terminated by a new 1782871Speter * line character or a null character. We process 1792871Speter * form feed directives, lines with only a form feed character, and 1802871Speter * suppress numbering lines which are empty here. 1812871Speter */ 1822871Speter yyprline(buf, line, file, id) 1832871Speter register char *buf; 1842871Speter int line; 1852871Speter char *file; 1862871Speter int id; 1872871Speter { 1882871Speter 1892871Speter lastid = id; 1902871Speter if (buf[0] == '\f' && buf[1] == '\n') { 1912871Speter printf("\f\n"); 1922871Speter hadsome = 0; 1932871Speter holdbl = 0; 1942871Speter return; 1952871Speter } 1962871Speter if (holdbl) { 1972871Speter putchar('\n'); 1982871Speter holdbl = 0; 1992871Speter } 2002871Speter if (buf[0] == '\n') 2012871Speter holdbl = 1; 2022871Speter else { 2032871Speter yysetfile(file); 2042871Speter yyprintf(buf, line); 2052871Speter } 2062871Speter hadsome = 1; 2072871Speter } 2082871Speter 2092871Speter yyprintf(cp, line) 2102871Speter register char *cp; 2112871Speter int line; 2122871Speter { 2132871Speter 2142871Speter printf("%6d ", line); 2152871Speter while (*cp != 0 && *cp != '\n') 2162871Speter putchar(graphic(*cp++)); 2172871Speter putchar('\n'); 2182871Speter } 2192871Speter 2202871Speter graphic(ch) 2212871Speter register CHAR ch; 2222871Speter { 2232871Speter 2242871Speter switch (ch) { 2252871Speter default: 2262871Speter if (ch >= ' ') 2272871Speter return (ch); 2282871Speter case 0177: 2292871Speter return ('?'); 2302871Speter case '\n': 2312871Speter case '\t': 2322871Speter return (ch); 2332871Speter } 2342871Speter } 2352871Speter 2362871Speter extern int nopflg; 2372871Speter 2383055Smckusic char printed = 1; 2392871Speter /* 2402871Speter * Set the current file name to be file, 2412871Speter * printing the name, or a header on a new 2422871Speter * page if required. 2432871Speter */ 2442871Speter yysetfile(file) 2452871Speter register char *file; 2462871Speter { 2472871Speter 2482871Speter #ifdef PXP 2492871Speter if (nopflg == 1) 2502871Speter return; 2512871Speter #endif 2522871Speter 2532871Speter if (lastname == file) 2542871Speter return; 2552871Speter if (file == filename && opt('n') && (printed & 02) == 0) { 2562871Speter printed =| 02; 2572871Speter header(); 2582871Speter } else 2592871Speter yyputfn(file); 2602871Speter lastname = file; 2612871Speter } 2622871Speter 2632871Speter /* 2642871Speter * Put out an include file name 2652871Speter * if an error occurs but the name has 2662871Speter * not been printed (or if another name 2672871Speter * has been printed since it has). 2682871Speter */ 2692871Speter yyputfn(cp) 2702871Speter register char *cp; 2712871Speter { 2722871Speter extern int outcol; 2732871Speter 2742871Speter if (cp == lastname && printed) 2752871Speter return; 2762871Speter lastname = cp; 2772871Speter printed = 1; 2782871Speter #ifdef PXP 2792871Speter if (outcol) 2802871Speter putchar('\n'); 2812871Speter #endif 2822871Speter printf("%s:\n", cp); 2832871Speter hadsome = 1; 2842871Speter } 285