xref: /386bsd/usr/src/usr.bin/g++/cc1plus/cp-input.c (revision a2142627)
1 /* Input handling for G++.
2    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3    Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
4 
5 This file is part of GNU CC.
6 
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11 
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
20 
21 /* G++ needs to do enough saving and re-parsing of text that it is
22    necessary to abandon the simple FILE* model and use a mechanism where
23    we can pre-empt one input stream with another derived from saved text;
24    we may need to do this arbitrarily often, and cannot depend on having
25    the GNU library available, so FILE objects just don't cut it.
26 
27    This file is written as a separate module, but can be included by
28    cp-lex.c for very minor efficiency gains (primarily in function
29    inlining).  */
30 
31 #include <stdio.h>
32 #include "obstack.h"
33 
34 extern FILE *finput;
35 
36 struct pending_input *save_pending_input ();
37 void restore_pending_input ();
38 
39 struct input_source {
40   /* saved string */
41   char *str;
42   int length;
43   /* current position, when reading as input */
44   int offset;
45   /* obstack to free this input string from when finished, if any */
46   struct obstack *obstack;
47   /* linked list maintenance */
48   struct input_source *next;
49   /* values to restore after reading all of current string */
50   char *filename;
51   int lineno;
52   struct pending_input *input;
53   int putback_char;
54 };
55 
56 static struct input_source *input, *free_inputs;
57 
58 extern char *input_filename;
59 extern int lineno;
60 
61 #ifdef __GNUC__
62 #define inline __inline__
63 #else
64 #define inline
65 #endif
66 
67 static inline struct input_source *
allocate_input()68 allocate_input ()
69 {
70   struct input_source *inp;
71   if (free_inputs)
72     {
73       inp = free_inputs;
74       free_inputs = inp->next;
75       inp->next = 0;
76       return inp;
77     }
78   inp = (struct input_source *) xmalloc (sizeof (struct input_source));
79   inp->next = 0;
80   inp->obstack = 0;
81   return inp;
82 }
83 
84 static inline void
free_input(inp)85 free_input (inp)
86      struct input_source *inp;
87 {
88   if (inp->obstack)
89     obstack_free (inp->obstack, inp->str);
90   inp->obstack = 0;
91   inp->str = 0;
92   inp->length = 0;
93   inp->next = free_inputs;
94   free_inputs = inp;
95 }
96 
97 static int putback_char = -1;
98 
99 /* Some of these external functions are declared inline in case this file
100    is included in cp-lex.c.  */
101 
102 inline
103 void
feed_input(str,len,delete)104 feed_input (str, len, delete)
105      char *str;
106      int len;
107      struct obstack *delete;
108 {
109   struct input_source *inp = allocate_input ();
110 
111   /* This shouldn't be necessary.  */
112   while (len && !str[len-1])
113     len--;
114 
115   inp->str = str;
116   inp->length = len;
117   inp->obstack = delete;
118   inp->offset = 0;
119   inp->next = input;
120   inp->filename = input_filename;
121   inp->lineno = lineno;
122   inp->input = save_pending_input ();
123   inp->putback_char = putback_char;
124   putback_char = -1;
125   input = inp;
126 }
127 
128 struct pending_input *to_be_restored; /* XXX */
129 extern int end_of_file;
130 
131 int
getch()132 getch ()
133 {
134   if (putback_char != -1)
135     {
136       int ch = putback_char;
137       putback_char = -1;
138       return ch;
139     }
140   if (input)
141     {
142       if (input->offset == input->length)
143 	{
144 	  struct input_source *inp = input;
145 	  my_friendly_assert (putback_char == -1, 223);
146 	  to_be_restored = inp->input;
147 	  input->offset++;
148 	  return EOF;
149 	}
150       else if (input->offset > input->length)
151 	{
152 	  struct input_source *inp = input;
153 
154 	  end_of_file = 0;
155 	  input = inp->next;
156 	  input_filename = inp->filename;
157 	  lineno = inp->lineno;
158 	  /* Get interface/implementation back in sync. */
159 	  extract_interface_info ();
160 	  putback_char = inp->putback_char;
161 	  free_input (inp);
162 	  return getch ();
163 	}
164       if (input)
165 	return input->str[input->offset++];
166     }
167   return getc (finput);
168 }
169 
170 inline
171 void
put_back(ch)172 put_back (ch)
173      int ch;
174 {
175   my_friendly_assert (putback_char == -1, 224);
176   putback_char = ch;
177 }
178 
179 inline
180 int
input_redirected()181 input_redirected ()
182 {
183   return input != 0;
184 }
185