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
;