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)
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
36 struct putback_buffer {
42 static struct putback_buffer putback = {NULL, 0, -1};
49 /* current position, when reading as input */
51 /* linked list maintenance */
52 struct input_source *next;
53 /* values to restore after reading all of current string */
54 struct pending_input *input;
58 struct putback_buffer putback;
62 static struct input_source *input, *free_inputs;
64 extern char *input_filename;
68 extern unsigned char *yy_cur, *yy_lim;
69 extern int yy_get_token ();
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 *
85 struct input_source *inp;
89 free_inputs = inp->next;
93 inp = (struct input_source *) xmalloc (sizeof (struct input_source));
100 struct input_source *inp;
104 inp->next = free_inputs;
108 /* Some of these external functions are declared inline in case this file
109 is included in lex.c. */
113 feed_input (str, len, file, line)
119 struct input_source *inp = allocate_input ();
121 /* This shouldn't be necessary. */
122 while (len && !str[len-1])
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;
139 inp->putback = putback;
140 inp->filename = input_filename;
141 inp->lineno = lineno;
142 putback.buffer = NULL;
143 putback.buffer_size = 0;
147 inp->input = save_pending_input ();
150 input_filename = file;
153 extern int end_of_file;
158 struct input_source *inp = input;
161 cpp_pop_buffer (&parse_in);
163 putback = inp->putback;
164 input_filename = inp->filename;
165 lineno = inp->lineno;
170 /* Get interface/implementation back in sync. */
171 extract_interface_info ();
172 restore_pending_input (inp->input);
180 return (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ());
182 if (putback.index != -1)
184 int ch = putback.buffer[putback.index];
190 if (input->offset >= input->length)
192 my_friendly_assert (putback.index == -1, 223);
194 if (input->offset - input->length < 64)
197 /* We must be stuck in an error-handling rule; give up. */
201 return (unsigned char)input->str[input->offset++];
203 return getc (finput);
215 else if (yy_cur[-1] != ch)
216 my_friendly_abort (990709);
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;
238 return CPP_BUFFER(&parse_in)->manual_pop;