home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / src / preproc / pchars.c < prev    next >
C/C++ Source or Header  |  2001-12-12  |  4KB  |  158 lines

  1. #include "../preproc/preproc.h"
  2. #include "../preproc/pproto.h"
  3.  
  4. int *first_char;
  5. int *next_char;
  6. int *last_char;
  7.  
  8. /*
  9.  * fill_cbuf - fill the current character buffer.
  10.  */
  11. void fill_cbuf()
  12.    {
  13.    register int c1, c2, c3;
  14.    register int *s;
  15.    register int *l;
  16.    int c;
  17.    int line;
  18.    int changes;
  19.    struct char_src *cs;
  20.    FILE *f;
  21.  
  22.    cs = src_stack->u.cs;
  23.    f = cs->f;
  24.    s = cs->char_buf;
  25.    l = cs->line_buf;
  26.  
  27.    if (next_char == NULL) {
  28.       /*
  29.        * Initial filling of buffer.
  30.        */
  31.       first_char = cs->char_buf;
  32.       last_char = first_char + cs->bufsize - 3;
  33.       cs->last_char = last_char;
  34.       line = 1;
  35.       /*
  36.        * Get initial read-ahead.
  37.        */
  38.       if ((c2 = getc(f)) != EOF)
  39.          c3 = getc(f);
  40.       }
  41.    else if (*next_char == EOF)
  42.       return;
  43.    else {
  44.       /*
  45.        * The calling routine needs at least 2 characters, so there is one
  46.        *  left in the buffer.
  47.        */
  48.       *s++= *next_char;
  49.       line = cs->line_buf[next_char - first_char];
  50.       *l++ = line;
  51.  
  52.       /*
  53.        * Retrieve the 2 read-ahead characters that were saved the last
  54.        *  time the buffer was filled.
  55.        */
  56.       c2 = last_char[1];
  57.       c3 = last_char[2];
  58.       }
  59.  
  60.    next_char = first_char;
  61.  
  62.    /*
  63.     * Fill buffer from input file.
  64.     */
  65.    while (s <= last_char) {
  66.       c1 = c2;
  67.       c2 = c3;
  68.       c3 = getc(f);
  69.  
  70.       /*
  71.        * The first phase of input translation is done here: trigraph
  72.        *  translation and the deletion of backslash-newline pairs.
  73.        */
  74.       changes = 1;
  75.       while (changes) {
  76.          changes = 0;
  77.          /*
  78.           * check for trigraphs
  79.           */
  80.          if (c1 == '?' && c2 == '?') {
  81.             c = ' ';
  82.             switch (c3) {
  83.                case '=':
  84.                   c = '#';
  85.                   break;
  86.                case '(':
  87.                   c = '[';
  88.                   break;
  89.                case '/':
  90.                   c = '\\';
  91.                   break;
  92.                case ')':
  93.                   c = ']';
  94.                   break;
  95.                case '\'':
  96.                   c = '^';
  97.                   break;
  98.                case '<':
  99.                   c = '{';
  100.                   break;
  101.                case '!':
  102.                   c = '|';
  103.                   break;
  104.                case '>':
  105.                   c = '}';
  106.                   break;
  107.                case '-':
  108.                   c = '~';
  109.                   break;
  110.                }
  111.             /*
  112.              * If we found a trigraph, use it and refill the 2-character
  113.              *  read-ahead.
  114.              */
  115.             if (c != ' ') {
  116.                c1 = c;
  117.                if ((c2 = getc(f)) != EOF)
  118.                   c3 = getc(f);
  119.                changes = 1;
  120.                }
  121.             }
  122.  
  123.          /*
  124.           * delete backslash-newline pairs
  125.           */
  126.          if (c1 == '\\' && c2 == '\n') {
  127.             ++line;
  128.             if ((c1 = c3) != EOF)
  129.                if ((c2 = getc(f)) != EOF)
  130.                   c3 = getc(f);
  131.             changes = 1;
  132.             }
  133.          }
  134.       if (c1 == EOF) {
  135.          /*
  136.           * If last character in file is not a new-line, insert one.
  137.           */
  138.          if (s == first_char || s[-1] != '\n')
  139.             *s++ = '\n';
  140.          *s = EOF;
  141.          last_char = s;
  142.          cs->last_char = last_char;
  143.          return;
  144.          }
  145.       if (c1 == '\n')
  146.          ++line;
  147.       *s++ = c1;   /* put character in buffer */
  148.       *l++ = line;
  149.       }
  150.  
  151.    /*
  152.     * Save the 2 character read-ahead in the reserved space at the end
  153.     *  of the buffer.
  154.     */
  155.    last_char[1] = c2;
  156.    last_char[2] = c3;
  157.    }
  158.