1999-10-04 Mark Mitchell <mark@codesourcery.com>
[official-gcc.git] / gcc / cp / input.c
blobf8ab714aa83d54874128792942fb2521d2dae66e
1 /* Input handling for G++.
2 Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
3 Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
4 Enhanced by Michael Tiemann (tiemann@cygnus.com) to better support USE_CPPLIB
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* G++ needs to do enough saving and re-parsing of text that it is
24 necessary to abandon the simple FILE* model and use a mechanism where
25 we can pre-empt one input stream with another derived from saved text;
26 we may need to do this arbitrarily often, and cannot depend on having
27 the GNU library available, so FILE objects just don't cut it.
29 This file is written as a separate module, but can be included by
30 lex.c for very minor efficiency gains (primarily in function
31 inlining). */
33 #include "system.h"
35 #if !USE_CPPLIB
36 struct putback_buffer {
37 char *buffer;
38 int buffer_size;
39 int index;
42 static struct putback_buffer putback = {NULL, 0, -1};
43 #endif
45 struct input_source {
46 /* saved string */
47 char *str;
48 int length;
49 /* current position, when reading as input */
50 int offset;
51 /* linked list maintenance */
52 struct input_source *next;
53 /* values to restore after reading all of current string */
54 struct pending_input *input;
55 #if !USE_CPPLIB
56 char *filename;
57 int lineno;
58 struct putback_buffer putback;
59 #endif
62 static struct input_source *input, *free_inputs;
64 extern char *input_filename;
65 extern int lineno;
67 #if USE_CPPLIB
68 extern unsigned char *yy_cur, *yy_lim;
69 extern int yy_get_token ();
70 #endif
72 extern void feed_input PROTO((char *, int, char *, int));
73 extern void put_input PROTO((int));
74 extern void put_back PROTO((int));
75 extern int getch PROTO((void));
76 extern int input_redirected PROTO((void));
78 static inline struct input_source * allocate_input PROTO((void));
79 static inline void free_input PROTO((struct input_source *));
80 static inline void end_input PROTO((void));
82 static inline struct input_source *
83 allocate_input ()
85 struct input_source *inp;
86 if (free_inputs)
88 inp = free_inputs;
89 free_inputs = inp->next;
90 inp->next = 0;
91 return inp;
93 inp = (struct input_source *) xmalloc (sizeof (struct input_source));
94 inp->next = 0;
95 return inp;
98 static inline void
99 free_input (inp)
100 struct input_source *inp;
102 inp->str = 0;
103 inp->length = 0;
104 inp->next = free_inputs;
105 free_inputs = inp;
108 /* Some of these external functions are declared inline in case this file
109 is included in lex.c. */
111 inline
112 void
113 feed_input (str, len, file, line)
114 char *str;
115 int len;
116 char *file;
117 int line;
119 struct input_source *inp = allocate_input ();
121 /* This shouldn't be necessary. */
122 while (len && !str[len-1])
123 len--;
125 #if USE_CPPLIB
126 if (yy_lim > yy_cur)
127 /* If we've started reading the next token, we're hosed. The
128 token_getch stuff is supposed to prevent this from happening. */
129 my_friendly_abort (990710);
130 cpp_push_buffer (&parse_in, str, len);
131 CPP_BUFFER (&parse_in)->manual_pop = 1;
132 CPP_BUFFER (&parse_in)->nominal_fname
133 = CPP_BUFFER (&parse_in)->fname = file;
134 CPP_BUFFER (&parse_in)->lineno = parse_in.lineno = line;
135 #else
136 inp->str = str;
137 inp->length = len;
138 inp->offset = 0;
139 inp->putback = putback;
140 inp->filename = input_filename;
141 inp->lineno = lineno;
142 putback.buffer = NULL;
143 putback.buffer_size = 0;
144 putback.index = -1;
145 #endif
146 inp->next = input;
147 inp->input = save_pending_input ();
148 input = inp;
149 lineno = line;
150 input_filename = file;
153 extern int end_of_file;
155 static inline void
156 end_input ()
158 struct input_source *inp = input;
160 #if USE_CPPLIB
161 cpp_pop_buffer (&parse_in);
162 #else
163 putback = inp->putback;
164 input_filename = inp->filename;
165 lineno = inp->lineno;
166 #endif
168 end_of_file = 0;
169 input = inp->next;
170 /* Get interface/implementation back in sync. */
171 extract_interface_info ();
172 restore_pending_input (inp->input);
173 free_input (inp);
176 inline int
177 getch ()
179 #if USE_CPPLIB
180 return (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ());
181 #else
182 if (putback.index != -1)
184 int ch = putback.buffer[putback.index];
185 --putback.index;
186 return ch;
188 if (input)
190 if (input->offset >= input->length)
192 my_friendly_assert (putback.index == -1, 223);
193 ++(input->offset);
194 if (input->offset - input->length < 64)
195 return EOF;
197 /* We must be stuck in an error-handling rule; give up. */
198 end_input ();
199 return getch ();
201 return (unsigned char)input->str[input->offset++];
203 return getc (finput);
204 #endif
207 inline
208 void
209 put_back (ch)
210 int ch;
212 #if USE_CPPLIB
213 if (ch == EOF)
215 else if (yy_cur[-1] != ch)
216 my_friendly_abort (990709);
217 else
218 yy_cur--;
219 #else
220 if (ch != EOF)
222 if (putback.index == putback.buffer_size - 1)
224 putback.buffer_size += 16;
225 putback.buffer = xrealloc (putback.buffer, putback.buffer_size);
227 my_friendly_assert (putback.buffer != NULL, 224);
228 putback.buffer[++putback.index] = ch;
230 #endif
233 inline
235 input_redirected ()
237 #ifdef USE_CPPLIB
238 return CPP_BUFFER(&parse_in)->manual_pop;
239 #else
240 return input != 0;
241 #endif