home *** CD-ROM | disk | FTP | other *** search
/ Dream 48 / Amiga_Dream_48.iso / Atari / c / cpp.zoo / src / input.c < prev    next >
C/C++ Source or Header  |  1993-06-03  |  3KB  |  182 lines

  1.  
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include "global.h"
  7.  
  8. #define LINEBUF 128
  9.  
  10. char *cur_file;
  11. unsigned long last_line,    /* the last line we registered */
  12.   this_line,            /* the line we just read */
  13.   next_line;            /* the line we're about to read */
  14.  
  15. static char *the_line;
  16. static size_t the_size;
  17. char *next_c;
  18.  
  19. /*
  20.    trigraph() -- translate trigraph sequences in string |s|.  |s| is modified
  21.    in place.
  22. */
  23. static void trigraph(s)
  24.   register char *s;
  25. {
  26.   register char *t = s;
  27.  
  28.   while (*s) {
  29.     if (*s == '?' && s[1] == '?')
  30.       switch (s[2]) {
  31.       case '=':
  32.     *t++ = '#';
  33.     goto skip;
  34.       case '/':
  35.     *t++ = '\\';
  36.     goto skip;
  37.       case '\'':
  38.     *t++ = '^';
  39.     goto skip;
  40.       case '(':
  41.     *t++ = '[';
  42.     goto skip;
  43.       case ')':
  44.     *t++ = ']';
  45.     goto skip;
  46.       case '!':
  47.     *t++ = '|';
  48.     goto skip;
  49.       case '<':
  50.     *t++ = '{';
  51.     goto skip;
  52.       case '>':
  53.     *t++ = '}';
  54.     goto skip;
  55.       case '-':
  56.     *t++ = '~';
  57.       skip:s += 3;
  58.     break;
  59.       default:
  60.     *t++ = *s++;
  61.     } else
  62.       *t++ = *s++;
  63.   }
  64.   *t = '\0';
  65. }
  66.  
  67. /*
  68.    getline() -- read a line from input file |f|, translate trigraphs if
  69.    necessary, collapse lines spliced with \<newline>, and strip comments if
  70.    necessary
  71. */
  72. char *getline()
  73. {
  74.   register char *s, *t;
  75.   ptrdiff_t dp;
  76.  
  77.   this_line = next_line;    /* tomorrow never arrives; it just becomes
  78.                    today */
  79.   if (!the_line)
  80.     the_line = mallok(the_size = LINEBUF);
  81.   s = the_line;
  82.   if (!fgets(s, the_size, inf)) {
  83.     return NULL;
  84.   }
  85.   if (do_trigraphs)
  86.     trigraph(s);
  87.   t = s + strlen(s);
  88.   next_line++;
  89.   for (;;) {
  90.     if (t[-1] != '\n' || (--t > s && t[-1] == '\\')) {
  91.       if (t[-1] == '\\') {
  92.     t--;
  93.     next_line++;
  94.       }
  95.       if (the_size - (t - s) < LINEBUF) {
  96.     dp = t - s;
  97.     the_size += LINEBUF;
  98.     s = reallok(s, the_size);
  99.     t = s + dp;
  100.       }
  101.       if (!fgets(t, (int)(the_size - (t - s)), inf)) {
  102.     *t = '\0';
  103.     break;
  104.       }
  105.       if (do_trigraphs)
  106.     trigraph(t);
  107.       t += strlen(t);
  108.     } else
  109.       break;
  110.   }
  111.   *t++ = '\0';
  112.   the_line = next_c = s;
  113.   return s;
  114. }
  115.  
  116. /*
  117.    flush_line() -- discard the rest of the input line and any pushed-back
  118.    tokens
  119. */
  120. void flush_line()
  121. {
  122.   next_c = NULL;
  123.   flush_tokenizer();
  124. }
  125.  
  126. /*
  127.    rest_of_line() -- return a pointer to the remainder of the input line
  128. */
  129. char *rest_of_line()
  130. {
  131.   return next_c;
  132. }
  133.  
  134. /*
  135.    tokenize_string() -- convert the string pointed to by |s| into a list of
  136.    tokens.  If |s| is NULL, convert the remainder of the input line.
  137. */
  138. TokenP tokenize_string(s)
  139.   char *s;
  140. {
  141.   char *old_next_c;
  142.   TokenP T = NULL, t = NULL, tt;
  143.  
  144.   if (s) {
  145.     old_next_c = next_c;
  146.     next_c = s;
  147.   }
  148.   for (;;) {
  149.     tt = _one_token();
  150.     if (tt->type == EOL) {
  151.       free_token(tt);
  152.       break;
  153.     }
  154.     if (!T)
  155.       t = T = tt;
  156.     else
  157.       t = t->next = tt;
  158.   }
  159.   if (s)
  160.     next_c = old_next_c;
  161.   if (t) {
  162.     t->next = NULL;
  163.     *T->pre_ws = '\0';
  164.   }
  165.   return T;
  166. }
  167.  
  168. /*
  169.    expand_rest_of_line() -- tokenize and macro-expand the remainder of the
  170.    input line.  Pushes the resulting Token list back onto the input stream.
  171.    Note:  we restore here the EOL token that tokenize_string() threw away.
  172. */
  173. void expand_rest_of_line()
  174. {
  175.   TokenP T1, T2, T3;
  176.  
  177.   T1 = tokenize_string(NULL);
  178.   T2 = expand_tlist(T1);
  179.   push_tlist(mk_eol());
  180.   push_tlist(T2);
  181. }
  182.