home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / yyget.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  8.1 KB  |  394 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[] = "@(#)yyget.c    5.3 (Berkeley) 4/16/91";
  36. #endif /* not lint */
  37.  
  38. #include "whoami.h"
  39. #include <0.h>
  40. #include "tree_ty.h"    /* must be included for yy.h */
  41. #include "yy.h"
  42.  
  43. #ifdef PXP
  44. int    yytokcnt;
  45. #endif
  46.  
  47. /*
  48.  * Readch returns the next
  49.  * character from the current
  50.  * input line or -1 on end-of-file.
  51.  * It also maintains yycol for use in
  52.  * printing error messages.
  53.  */
  54. readch()
  55. {
  56.     register c;
  57.  
  58.     if (*bufp == '\n' && bufp >= charbuf) {
  59. #ifdef PXP
  60.         yytokcnt = 0;
  61. #endif
  62.         if (getline() < 0)
  63.             return (-1);
  64.     }
  65.     c = *++bufp;
  66.     if (c == '\t')
  67.         yycol = ((yycol + 8) & ~7);
  68.     else
  69.         yycol++;
  70.     return (c);
  71. }
  72.  
  73. /*
  74.  * Definitions of the structures used for the
  75.  * include facility.  The variable "ibp" points
  76.  * to the getc buffer of the current input file.
  77.  * There are "inclev + 1" current include files,
  78.  * and information in saved in the incs stack
  79.  * whenever a new level of include nesting occurs.
  80.  *
  81.  * Ibp in the incs structure saves the pointer
  82.  * to the previous levels input buffer;
  83.  * filename saves the previous file name;
  84.  * Printed saves whether the previous file name
  85.  * had been printed before this nesting occurred;
  86.  * and yyline is the line we were on on the previous file.
  87.  */
  88.  
  89. #define    MAXINC    10
  90.  
  91. struct inc {
  92.     FILE    *ibp;
  93.     char    *filename;
  94.     int    Printed;
  95.     int    yyline;
  96.     int    yyLinpt;
  97. } incs[MAXINC];
  98.  
  99. extern    char printed;
  100.  
  101. int    inclev    = -1;
  102.  
  103. #ifdef PXP
  104. /*
  105.  * These initializations survive only if
  106.  * pxp is asked to pretty print one file.
  107.  * Otherwise they are destroyed by the initial
  108.  * call to getline.
  109.  */
  110. char    charbuf[CBSIZE]    = " program x(output);\n";
  111. int    yycol = 8;
  112. char    *bufp = charbuf;
  113.  
  114. #endif
  115. /*
  116.  * YyLinpt is the seek pointer to the beginning of the
  117.  * next line in the file.
  118.  */
  119. int    yyLinpt;
  120.  
  121. /*
  122.  * Getline places the next line
  123.  * from the input stream in the
  124.  * line buffer, returning -1 at YEOF.
  125.  */
  126. getline()
  127. {
  128.     register char *cp;
  129.     register CHAR c;
  130. #ifdef PXP
  131.     static char ateof;
  132. #endif
  133.     register FILE *ib;
  134.     int i;
  135.  
  136.     if (opt('l') && yyprtd == 0)
  137.         yyoutline();
  138.     yyprtd = 0;
  139. top:
  140.     yylinpt = yyLinpt;
  141.     yyline++;
  142.     yyseqid++;
  143.     cp = charbuf;
  144.     ib = ibp;
  145.     i = sizeof charbuf - 1;
  146.     for (;;) {
  147.         c = getc(ib);
  148.         if (c == EOF) {
  149.             if (uninclud())
  150.                 goto top;
  151. #ifdef PXP
  152.             if (ateof == 0 && bracket) {
  153.                 (void) pstrcpy(charbuf, "begin end.\n");
  154.                 ateof = 1;
  155.                 goto out;
  156.             }
  157. #endif
  158.             bufp = "\n";
  159.             yyline--;
  160.             yyseqid--;
  161.             yyprtd = 1;
  162.             return (-1);
  163.         }
  164.         *cp++ = c;
  165.         if (c == '\n')
  166.             break;
  167.         if (--i == 0) {
  168.             line = yyline;
  169.             error("Input line too long - QUIT");
  170.             pexit(DIED);
  171.         }
  172.     }
  173.     *cp = 0;
  174.     yyLinpt = yylinpt + cp - charbuf;
  175.     if (includ())
  176.         goto top;
  177. #ifdef PXP
  178.     if (cp == &charbuf[1])
  179.         commnl();
  180.     else if (cp == &charbuf[2])
  181.         switch (charbuf[0]) {
  182.             case ' ':
  183.                 commnlbl();
  184.                 break;
  185.             case '\f':
  186.                 commform();
  187.         }
  188. #endif
  189.     if (opt('u'))
  190.         setuflg();
  191. #ifdef PXP
  192. out:
  193. #endif
  194.     bufp = charbuf - 1;
  195.     yycol = 8;
  196.     return (1);
  197. }
  198.  
  199. /*
  200.  * Check an input line to see if it is a "#include" pseudo-statement.
  201.  * We allow arbitrary blanks in the line and the file name
  202.  * may be delimited by either 's or "s.  A single semicolon
  203.  * may be placed after the name, but nothing else is allowed
  204.  */
  205. includ()
  206. {
  207.     register char *cp, *dp;
  208.     char ch;
  209.     register struct inc *ip;
  210.  
  211.     cp = charbuf;
  212.     if (*cp++ != '#')
  213.         return (0);
  214.     cp = skipbl(cp);
  215.     for (dp = "include"; *dp; dp++)
  216.         if (*dp != *cp++)
  217.             return (0);
  218.     line = yyline;
  219.     cp = skipbl(cp);
  220.     ch = *cp++;
  221.     if (ch != '\'' && ch != '"') {
  222.         /*
  223.          * This should be a yerror flagging the place
  224.          * but its not worth figuring out the column.
  225.          */
  226.         line = yyline;
  227.         error("Include syntax error - expected ' or \" not found - QUIT");
  228.         pexit(DIED);
  229.     }
  230.     for (dp = cp; *dp != ch; dp++)
  231.         if (*dp == 0) {
  232.             line = yyline;
  233.             error("Missing closing %c for include file name - QUIT", (char *) ch);
  234.             pexit(DIED);
  235.         }
  236.     *dp++ = 0;
  237. /*
  238.  *    if (*dp == ';')
  239.  *        dp++;
  240.  *    dp = skipbl(dp);
  241.  *    if (*dp != '\n') {
  242.  *        line = yyline;
  243.  *        error("Garbage after filename in include");
  244.  *        pexit(DIED);
  245.  *    }
  246.  */
  247.     if (!dotted(cp, 'i') && !dotted(cp, 'h')) {
  248.         line = yyline;
  249.         error("Include filename must end in .i or .h");
  250.     }
  251. #ifdef PXP
  252.     commincl(cp, ch);
  253.     if (noinclude)
  254.         return (1);
  255. #endif
  256.     inclev++;
  257.     if (inclev > MAXINC) {
  258.         line = yyline;
  259.         error("Absurdly deep include nesting - QUIT");
  260.         pexit(DIED);
  261.     }
  262.     ip = &incs[inclev];
  263.     ip->filename = filename;
  264.     filename = savestr(cp);
  265.  
  266. #ifdef OBJ
  267. /*
  268.  * For the debugger pdx, we need to note that we've changed files.
  269.  */
  270.     newfile(filename, 1);
  271. #endif
  272.  
  273. /*
  274.  *    left over from before stdio
  275.  *
  276.  *    cp = malloc(518);
  277.  *    if (cp == -1) {
  278.  *        error("Ran out of memory (include)");
  279.  *        pexit(DIED);
  280.  *    }
  281.  *
  282.  */
  283.     ip->ibp = ibp;
  284.     if ( ( ibp = fopen(filename, "r" ) ) == NULL ) {
  285.         perror(filename);
  286.         pexit(DIED);
  287.     }
  288.     if (inpflist(filename)) {
  289. #ifdef PI
  290.         opush('l');
  291. #endif
  292. #ifdef PXP
  293.         opush('z');
  294. #endif
  295.     }
  296.     ip->Printed = printed;
  297.     printed = 0;
  298.     ip->yyline = yyline;
  299.     yyline = 0;
  300.     ip->yyLinpt = yyLinpt;
  301.     yyLinpt = 0;
  302. /*
  303.  *    left over from before stdio
  304.  *
  305.  *    ip->ibp = ibp;
  306.  *    ibp = cp;
  307.  *
  308.  */
  309. #    ifdef PC
  310.         stabinclude( filename , TRUE );
  311. #    endif PC
  312.     return (1);
  313. }
  314.  
  315. char *
  316. skipbl(ocp)
  317.     char *ocp;
  318. {
  319.     register char *cp;
  320.  
  321.     cp = ocp;
  322.     while (*cp == ' ' || *cp == '\t')
  323.         cp++;
  324.     return (cp);
  325. }
  326.  
  327.  
  328. /*
  329.  * At the end of an include,
  330.  * close the file, free the input buffer,
  331.  * and restore the environment before
  332.  * the "push", including the value of
  333.  * the z option for pxp and the l option for pi.
  334.  */
  335. uninclud()
  336. {
  337.     register struct inc *ip;
  338.  
  339.     if (inclev < 0)
  340.         return (0);
  341. /*
  342.  *    left over from before stdio: becomes fclose ( ibp )
  343.  *
  344.  *    (void) close(ibp[0]);
  345.  *    free(ibp);
  346.  *
  347.  */
  348.     (void) fclose ( ibp );
  349.     ip = &incs[inclev];
  350.     ibp = ip->ibp;
  351.     yyline = ip->yyline;
  352.     if (inpflist(filename)) {
  353. #ifdef PI
  354.         opop('l');
  355. #endif
  356. #ifdef PXP
  357.         opop('z');
  358. #endif
  359.     }
  360.     filename = ip->filename;
  361.  
  362.     yyLinpt = ip->yyLinpt;
  363.     /*
  364.      * If we printed out the nested name,
  365.      * then we should print all covered names again.
  366.      * If we didn't print out the nested name
  367.      * we print the uncovered name only if it
  368.      * has not been printed before (unstack).
  369.      */
  370.     if (printed) {
  371.         printed = 0;
  372.         while (ip >= incs) {
  373.             ip->Printed = 0;
  374.             ip--;
  375.         }
  376.     } else
  377.         printed = ip->Printed;
  378. #    ifdef OBJ
  379.     /*
  380.      * For the debugger pdx, we need to note that we've changed files.
  381.      */
  382.     newfile(filename, yyline);
  383. #endif
  384. #    ifdef PC
  385.         if ( inclev == 0 ) {
  386.         stabsource( filename );
  387.         } else {
  388.         stabinclude( filename , FALSE );
  389.         }
  390. #    endif PC
  391.     inclev--;
  392.     return (1);
  393. }
  394.