]>
Commit | Line | Data |
---|---|---|
8d08fdba | 1 | /* Input handling for G++. |
8ecb1d92 | 2 | Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. |
8d08fdba MS |
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 | |
e9fa0c7c RK |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | |
8d08fdba MS |
21 | |
22 | /* G++ needs to do enough saving and re-parsing of text that it is | |
23 | necessary to abandon the simple FILE* model and use a mechanism where | |
24 | we can pre-empt one input stream with another derived from saved text; | |
25 | we may need to do this arbitrarily often, and cannot depend on having | |
26 | the GNU library available, so FILE objects just don't cut it. | |
27 | ||
28 | This file is written as a separate module, but can be included by | |
51c184be | 29 | lex.c for very minor efficiency gains (primarily in function |
8d08fdba MS |
30 | inlining). */ |
31 | ||
32 | #include <stdio.h> | |
8d08fdba MS |
33 | |
34 | extern FILE *finput; | |
35 | ||
8d08fdba MS |
36 | struct input_source { |
37 | /* saved string */ | |
38 | char *str; | |
39 | int length; | |
40 | /* current position, when reading as input */ | |
41 | int offset; | |
8d08fdba MS |
42 | /* linked list maintenance */ |
43 | struct input_source *next; | |
44 | /* values to restore after reading all of current string */ | |
45 | char *filename; | |
46 | int lineno; | |
47 | struct pending_input *input; | |
48 | int putback_char; | |
49 | }; | |
50 | ||
51 | static struct input_source *input, *free_inputs; | |
52 | ||
53 | extern char *input_filename; | |
54 | extern int lineno; | |
55 | ||
56 | #ifdef __GNUC__ | |
57 | #define inline __inline__ | |
58 | #else | |
59 | #define inline | |
60 | #endif | |
61 | ||
49c249e1 JM |
62 | extern void feed_input PROTO((char *, int)); |
63 | extern void put_input PROTO((int)); | |
64 | extern void put_back PROTO((int)); | |
65 | extern int getch PROTO((void)); | |
66 | extern int input_redirected PROTO((void)); | |
67 | ||
68 | static inline struct input_source * allocate_input PROTO((void)); | |
69 | static inline void free_input PROTO((struct input_source *)); | |
70 | static inline void end_input PROTO((void)); | |
71 | static inline int sub_getch PROTO((void)); | |
72 | ||
8d08fdba MS |
73 | static inline struct input_source * |
74 | allocate_input () | |
75 | { | |
76 | struct input_source *inp; | |
77 | if (free_inputs) | |
78 | { | |
79 | inp = free_inputs; | |
80 | free_inputs = inp->next; | |
81 | inp->next = 0; | |
82 | return inp; | |
83 | } | |
84 | inp = (struct input_source *) xmalloc (sizeof (struct input_source)); | |
85 | inp->next = 0; | |
8d08fdba MS |
86 | return inp; |
87 | } | |
88 | ||
89 | static inline void | |
90 | free_input (inp) | |
91 | struct input_source *inp; | |
92 | { | |
8d08fdba MS |
93 | inp->str = 0; |
94 | inp->length = 0; | |
95 | inp->next = free_inputs; | |
96 | free_inputs = inp; | |
97 | } | |
98 | ||
99 | static int putback_char = -1; | |
100 | ||
101 | /* Some of these external functions are declared inline in case this file | |
51c184be | 102 | is included in lex.c. */ |
8d08fdba MS |
103 | |
104 | inline | |
105 | void | |
42976354 | 106 | feed_input (str, len) |
8d08fdba MS |
107 | char *str; |
108 | int len; | |
8d08fdba MS |
109 | { |
110 | struct input_source *inp = allocate_input (); | |
111 | ||
112 | /* This shouldn't be necessary. */ | |
113 | while (len && !str[len-1]) | |
114 | len--; | |
115 | ||
116 | inp->str = str; | |
117 | inp->length = len; | |
8d08fdba MS |
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 | ||
42976354 BK |
131 | static inline void |
132 | end_input () | |
133 | { | |
134 | struct input_source *inp = input; | |
135 | ||
136 | end_of_file = 0; | |
137 | input = inp->next; | |
138 | input_filename = inp->filename; | |
139 | lineno = inp->lineno; | |
140 | /* Get interface/implementation back in sync. */ | |
141 | extract_interface_info (); | |
142 | putback_char = inp->putback_char; | |
143 | restore_pending_input (inp->input); | |
144 | free_input (inp); | |
145 | } | |
146 | ||
d18c083e MS |
147 | static inline int |
148 | sub_getch () | |
8d08fdba MS |
149 | { |
150 | if (putback_char != -1) | |
151 | { | |
152 | int ch = putback_char; | |
153 | putback_char = -1; | |
154 | return ch; | |
155 | } | |
156 | if (input) | |
157 | { | |
42976354 | 158 | if (input->offset >= input->length) |
8d08fdba | 159 | { |
8d08fdba | 160 | my_friendly_assert (putback_char == -1, 223); |
818045b6 JM |
161 | ++(input->offset); |
162 | if (input->offset - input->length < 64) | |
163 | return EOF; | |
164 | ||
165 | /* We must be stuck in an error-handling rule; give up. */ | |
166 | end_input (); | |
167 | return getch (); | |
8d08fdba | 168 | } |
42976354 | 169 | return (unsigned char)input->str[input->offset++]; |
8d08fdba MS |
170 | } |
171 | return getc (finput); | |
172 | } | |
173 | ||
174 | inline | |
175 | void | |
176 | put_back (ch) | |
177 | int ch; | |
178 | { | |
d18c083e MS |
179 | if (ch != EOF) |
180 | { | |
181 | my_friendly_assert (putback_char == -1, 224); | |
182 | putback_char = ch; | |
183 | } | |
184 | } | |
185 | ||
186 | extern int linemode; | |
187 | ||
188 | int | |
189 | getch () | |
190 | { | |
191 | int ch = sub_getch (); | |
192 | if (linemode && ch == '\n') | |
193 | { | |
194 | put_back (ch); | |
195 | ch = EOF; | |
196 | } | |
197 | return ch; | |
8d08fdba MS |
198 | } |
199 | ||
200 | inline | |
201 | int | |
202 | input_redirected () | |
203 | { | |
204 | return input != 0; | |
205 | } |