home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / pxp / yyput.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  5KB  |  283 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #
  3. /*
  4.  * pi - Pascal interpreter code translator
  5.  *
  6.  * Charles Haley, Bill Joy UCB
  7.  * Version 1.2 January 1979
  8.  *
  9.  *
  10.  * pxp - Pascal execution profiler
  11.  *
  12.  * Bill Joy UCB
  13.  * Version 1.2 January 1979
  14.  */
  15.  
  16. #include "0.h"
  17. #include "tree.h"
  18. #include "yy.h"
  19.  
  20. /*
  21.  * Structure describing queued listing lines during the forward move
  22.  * of error recovery.  These lines will be stroed by yyoutline during
  23.  * the forward move and flushed by yyoutfl or yyflush when an
  24.  * error occurs or a program termination.
  25.  */
  26. struct    B {
  27.     int    Bmagic;
  28.     int    Bline;
  29.     int    Bseekp;
  30.     char    *Bfile;
  31.     int    Bseqid;
  32.     struct    B *Bnext;
  33. } *bottled;
  34.  
  35. /*
  36.  * Filename gives the current input file, lastname is
  37.  * the last filename we printed, and lastid is the seqid of the last line
  38.  * we printed, to help us avoid printing
  39.  * multiple copies of lines.
  40.  */
  41. extern    char *filename;
  42. char    *lastname;
  43. int    lastid;
  44.  
  45. char    hadsome;
  46. char    holdbl;
  47.  
  48. /*
  49.  * Print the current line in the input line
  50.  * buffer or, in a forward move of the recovery, queue it for printing.
  51.  */
  52. yyoutline()
  53. {
  54.     register struct B *bp;
  55.  
  56.     if (Recovery) {
  57.         bp = tree(6, T_BOTTLE, yyline, yylinpt, filename, yyseqid);
  58.         if (bottled != NIL)
  59.             bp->Bnext = bottled->Bnext, bottled->Bnext = bp;
  60.         else
  61.             bp->Bnext = bp;
  62.         bottled = bp;
  63.         return;
  64.     }
  65.     yyoutfl(yyseqid);
  66.     if (yyseqid != lastid)
  67.         yyprline(charbuf, yyline, filename, yyseqid);
  68. }
  69.  
  70. /*
  71.  * Flush all the bottled output.
  72.  */
  73. yyflush()
  74. {
  75.  
  76.     yyoutfl(32767);
  77. }
  78.  
  79. /*
  80.  * Flush the listing to the sequence id toseqid
  81.  */
  82. yyoutfl(toseqid)
  83.     int toseqid;
  84. {
  85.     register struct B *bp;
  86.  
  87.     bp = bottled;
  88.     if (bp == NIL)
  89.         return;
  90.     bp = bp->Bnext;
  91.     while (bp->Bseqid <= toseqid) {
  92.         yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid);
  93.         if (bp->Bnext == bp) {
  94.             bottled = NIL;
  95.             break;
  96.         }
  97.         bp = bp->Bnext;
  98.         bottled->Bnext = bp;
  99.     }
  100. }
  101.  
  102. int    yygetunit -1;
  103. char    *yygetfile;
  104.  
  105. /*
  106.  * Yysync guarantees that the line associated
  107.  * with the current token was the last line
  108.  * printed for a syntactic error message.
  109.  */
  110. yysync()
  111. {
  112.  
  113.     yyoutfl(yyeseqid);
  114.     if (lastid != yyeseqid)
  115.         yygetline(yyefile, yyseekp, yyeline, yyeseqid);
  116. }
  117.  
  118. yySsync()
  119. {
  120.  
  121.     yyoutfl(OY.Yyeseqid);
  122. }
  123.  
  124. /*
  125.  * Yygetline gets a line from a file after we have
  126.  * lost it.  The pointer efile gives the name of the file,
  127.  * seekp its offset in the file, and eline its line number.
  128.  * If this routine has been called before the last file
  129.  * it worked on will be open in yygetunit, with the files
  130.  * name being given in yygetfile.  Note that this unit must
  131.  * be opened independently of the unit in use for normal i/o
  132.  * to this file; if it were a dup seeks would seek both files.
  133.  */
  134. yygetline(efile, seekp, eline, eseqid)
  135.     char *efile;
  136.     int seekp, eline, eseqid;
  137. {
  138.     register int cnt;
  139.     register char *bp;
  140.     char buf[CBSIZE + 1];
  141.  
  142.     if (lastid == eseqid)
  143.         return;
  144.     if (eseqid == yyseqid) {
  145.         bp = charbuf;
  146.         yyprtd++;
  147.     } else {
  148.         bp = buf;
  149.         if (efile != yygetfile) {
  150.             close(yygetunit);
  151.             yygetfile = efile;
  152.             yygetunit = open(yygetfile, 0);
  153.             if (yygetunit < 0)
  154. oops:
  155.                 perror(yygetfile), pexit(DIED);
  156.         } 
  157.         if (seek(yygetunit, seekp, 0) < 0)
  158.             goto oops;
  159.         cnt = read(yygetunit, bp, CBSIZE);
  160.         if (cnt < 0)
  161.             goto oops;
  162.         bp[cnt] = 0;
  163.     }
  164.     yyprline(bp, eline, efile, eseqid);
  165. }
  166.  
  167. yyretrieve()
  168. {
  169.  
  170.     yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid);
  171. }
  172.  
  173. /*
  174.  * Print the line in the character buffer which has
  175.  * line number line.  The buffer may be terminated by a new
  176.  * line character or a null character.  We process
  177.  * form feed directives, lines with only a form feed character, and
  178.  * suppress numbering lines which are empty here.
  179.  */
  180. yyprline(buf, line, file, id)
  181.     register char *buf;
  182.     int line;
  183.     char *file;
  184.     int id;
  185. {
  186.  
  187.     lastid = id;
  188.     if (buf[0] == '\f' && buf[1] == '\n') {
  189.         printf("\f\n");
  190.         hadsome = 0;
  191.         holdbl = 0;
  192.         return;
  193.     }
  194.     if (holdbl) {
  195.         putchar('\n');
  196.         holdbl = 0;
  197.     }
  198.     if (buf[0] == '\n')
  199.         holdbl = 1;
  200.     else {
  201.         yysetfile(file);
  202.         yyprintf(buf, line);
  203.     }
  204.     hadsome = 1;
  205. }
  206.  
  207. yyprintf(cp, line)
  208.     register char *cp;
  209.     int line;
  210. {
  211.  
  212.     printf("%6d  ", line);
  213.     while (*cp != 0 && *cp != '\n')
  214.         putchar(graphic(*cp++));
  215.     putchar('\n');
  216. }
  217.  
  218. graphic(ch)
  219.     register CHAR ch;
  220. {
  221.  
  222.     switch (ch) {
  223.         default:
  224.             if (ch >= ' ')
  225.                 return (ch);
  226.         case 0177:
  227.             return ('?');
  228.         case '\n':
  229.         case '\t':
  230.             return (ch);
  231.     }
  232. }
  233.  
  234. extern    int nopflg;
  235.  
  236. char    printed 1;
  237. /*
  238.  * Set the current file name to be file,
  239.  * printing the name, or a header on a new
  240.  * page if required.
  241.  */
  242. yysetfile(file)
  243.     register char *file;
  244. {
  245.  
  246. #ifdef PXP
  247.     if (nopflg == 1)
  248.         return;
  249. #endif
  250.  
  251.     if (lastname == file)
  252.         return;
  253.     if (file == filename && opt('n') && (printed & 02) == 0) {
  254.         printed =| 02;
  255.         header();
  256.     } else
  257.         yyputfn(file);
  258.     lastname = file;
  259. }
  260.  
  261. /*
  262.  * Put out an include file name
  263.  * if an error occurs but the name has
  264.  * not been printed (or if another name
  265.  * has been printed since it has).
  266.  */
  267. yyputfn(cp)
  268.     register char *cp;
  269. {
  270.     extern int outcol;
  271.  
  272.     if (cp == lastname && printed)
  273.         return;
  274.     lastname = cp;
  275.     printed = 1;
  276. #ifdef PXP
  277.     if (outcol)
  278.         putchar('\n');
  279. #endif
  280.     printf("%s:\n", cp);
  281.     hadsome = 1;
  282. }
  283.