home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / yyput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  6.9 KB  |  312 lines

  1. /*-
  2.  * Copyright (c) 1980 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)yyput.c    5.3 (Berkeley) 4/16/91";
  36. #endif /* not lint */
  37.  
  38. #include "whoami.h"
  39. #include "0.h"
  40. #include "tree.h"
  41. #include "tree_ty.h"    /* must be included for yy.h */
  42. #include "yy.h"
  43.  
  44. /*
  45.  * Structure describing queued listing lines during the forward move
  46.  * of error recovery.  These lines will be stroed by yyoutline during
  47.  * the forward move and flushed by yyoutfl or yyflush when an
  48.  * error occurs or a program termination.
  49.  */
  50. struct    B {
  51.     int    Bmagic;
  52.     int    Bline;
  53.     int    Bseekp;
  54.     char    *Bfile;
  55.     int    Bseqid;
  56.     struct    B *Bnext;
  57. } *bottled;
  58.  
  59. /*
  60.  * Filename gives the current input file, lastname is
  61.  * the last filename we printed, and lastid is the seqid of the last line
  62.  * we printed, to help us avoid printing
  63.  * multiple copies of lines.
  64.  */
  65. extern    char *filename;
  66. char    *lastname;
  67. int    lastid;
  68.  
  69. char    hadsome;
  70. char    holdbl;
  71.  
  72. /*
  73.  * Print the current line in the input line
  74.  * buffer or, in a forward move of the recovery, queue it for printing.
  75.  */
  76. yyoutline()
  77. {
  78.     register struct B *bp;
  79.  
  80.     if (Recovery) {
  81.         bp = (struct B *) tree(6, T_BOTTLE, yyline, yylinpt, filename,
  82.                 yyseqid);
  83.         if (bottled != NIL)
  84.             bp->Bnext = bottled->Bnext, bottled->Bnext = bp;
  85.         else
  86.             bp->Bnext = bp;
  87.         bottled = bp;
  88.         return;
  89.     }
  90.     yyoutfl(yyseqid);
  91.     if (yyseqid != lastid)
  92.         yyprline(charbuf, yyline, filename, yyseqid);
  93. }
  94.  
  95. /*
  96.  * Flush all the bottled output.
  97.  */
  98. yyflush()
  99. {
  100.  
  101.     yyoutfl(32767);
  102. }
  103.  
  104. /*
  105.  * Flush the listing to the sequence id toseqid
  106.  */
  107. yyoutfl(toseqid)
  108.     int toseqid;
  109. {
  110.     register struct B *bp;
  111.  
  112.     bp = bottled;
  113.     if (bp == NIL)
  114.         return;
  115.     bp = bp->Bnext;
  116.     while (bp->Bseqid <= toseqid) {
  117.         yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid);
  118.         if (bp->Bnext == bp) {
  119.             bottled = NIL;
  120.             break;
  121.         }
  122.         bp = bp->Bnext;
  123.         bottled->Bnext = bp;
  124.     }
  125. }
  126.  
  127. FILE    *yygetunit = NULL;
  128. char    *yygetfile;
  129.  
  130. /*
  131.  * Yysync guarantees that the line associated
  132.  * with the current token was the last line
  133.  * printed for a syntactic error message.
  134.  */
  135. yysync()
  136. {
  137.  
  138.     yyoutfl(yyeseqid);
  139.     if (lastid != yyeseqid)
  140.         yygetline(yyefile, yyseekp, yyeline, yyeseqid);
  141. }
  142.  
  143. yySsync()
  144. {
  145.  
  146.     yyoutfl(OY.Yyeseqid);
  147. }
  148.  
  149. /*
  150.  * Yygetline gets a line from a file after we have
  151.  * lost it.  The pointer efile gives the name of the file,
  152.  * seekp its offset in the file, and eline its line number.
  153.  * If this routine has been called before the last file
  154.  * it worked on will be open in yygetunit, with the files
  155.  * name being given in yygetfile.  Note that this unit must
  156.  * be opened independently of the unit in use for normal i/o
  157.  * to this file; if it were a dup seeks would seek both files.
  158.  */
  159. yygetline(efile, seekp, eline, eseqid)
  160.     char *efile;
  161.     int seekp, eline, eseqid;
  162. {
  163.     register int cnt;
  164.     register char *bp;
  165.     char buf[CBSIZE + 1];
  166.  
  167.     if (lastid == eseqid)
  168.         return;
  169.     if (eseqid == yyseqid) {
  170.         bp = charbuf;
  171.         yyprtd++;
  172.     } else {
  173.         bp = buf;
  174.         if (efile != yygetfile) {
  175.             if ( yygetunit != NULL )
  176.                 (void) fclose( yygetunit );
  177.             yygetfile = efile;
  178.             yygetunit = fopen( yygetfile , "r" );
  179.             if (yygetunit == 0)
  180. oops:
  181.                 perror(yygetfile), pexit(DIED);
  182.         } 
  183.         if ( fseek( yygetunit , (long) seekp , 0 ) < 0)
  184.             goto oops;
  185.         cnt = fread( bp , sizeof( * bp ) , CBSIZE , yygetunit );
  186.         if (cnt < 0)
  187.             goto oops;
  188.         bp[cnt] = 0;
  189.     }
  190.     yyprline(bp, eline, efile, eseqid);
  191. }
  192.  
  193. yyretrieve()
  194. {
  195.  
  196.     yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid);
  197. }
  198.  
  199. /*
  200.  * Print the line in the character buffer which has
  201.  * line number line.  The buffer may be terminated by a new
  202.  * line character or a null character.  We process
  203.  * form feed directives, lines with only a form feed character, and
  204.  * suppress numbering lines which are empty here.
  205.  */
  206. yyprline(buf, line, file, id)
  207.     register char *buf;
  208.     int line;
  209.     char *file;
  210.     int id;
  211. {
  212.  
  213.     lastid = id;
  214.     if (buf[0] == '\f' && buf[1] == '\n') {
  215.         printf("\f\n");
  216.         hadsome = 0;
  217.         holdbl = 0;
  218.         return;
  219.     }
  220.     if (holdbl) {
  221.         pchr('\n');
  222.         holdbl = 0;
  223.     }
  224.     if (buf[0] == '\n')
  225.         holdbl = 1;
  226.     else {
  227.         yysetfile(file);
  228.         yyprintf(buf, line);
  229.     }
  230.     hadsome = 1;
  231. }
  232.  
  233. yyprintf(cp, line)
  234.     register char *cp;
  235.     int line;
  236. {
  237.  
  238.     printf("%6d  ", line);
  239.     while (*cp != 0 && *cp != '\n')
  240.         pchr(graphic(*cp++));
  241.     pchr('\n');
  242. }
  243.  
  244. graphic(ch)
  245.     register CHAR ch;
  246. {
  247.  
  248.     switch (ch) {
  249.         default:
  250.             if (ch >= ' ')
  251.                 return (ch);
  252.         case 0177:
  253.             return ('?');
  254.         case '\n':
  255.         case '\t':
  256.             return (ch);
  257.     }
  258. }
  259.  
  260. extern    int nopflg;
  261.  
  262. char    printed = 1;
  263. /*
  264.  * Set the current file name to be file,
  265.  * printing the name, or a header on a new
  266.  * page if required.
  267.  * there is another yysetfile in error.c
  268.  * this one is for PI and PXP that one is for PI1
  269.  */
  270. yysetfile(file)
  271.     register char *file;
  272. {
  273.  
  274. #ifdef PXP
  275.     if (nopflg == 1)
  276.         return;
  277. #endif
  278.  
  279.     if (lastname == file)
  280.         return;
  281.     if (file == filename && opt('n') && (printed & 02) == 0) {
  282.         printed |= 02;
  283.         header();
  284.     } else
  285.         yyputfn(file);
  286.     lastname = file;
  287. }
  288.  
  289. /*
  290.  * Put out an include file name
  291.  * if an error occurs but the name has
  292.  * not been printed (or if another name
  293.  * has been printed since it has).
  294.  */
  295. yyputfn(cp)
  296.     register char *cp;
  297. {
  298.     extern int outcol;
  299.  
  300.     if (cp == lastname && printed)
  301.         return;
  302.     lastname = cp;
  303.     printed = 1;
  304. #ifdef PXP
  305.     if (outcol)
  306.         pchr('\n');
  307. #endif
  308.     gettime( cp );
  309.     printf("%s  %s:\n" , myctime( (int *) (&tvec) ) , cp );
  310.     hadsome = 1;
  311. }
  312.