OSDN Git Service

try again
[pf3gnuchains/gcc-fork.git] / gcc / cp / input.c
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
5
6 This file is part of GNU CC.
7
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.
12
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.
17
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.  */
22
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.
28
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).  */
32
33 #include "system.h"
34
35 #if !USE_CPPLIB
36 struct putback_buffer {
37   char *buffer;
38   int   buffer_size;
39   int   index;
40 };
41
42 static struct putback_buffer putback = {NULL, 0, -1};
43 #endif
44
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
60 };
61
62 static struct input_source *input, *free_inputs;
63
64 extern char *input_filename;
65 extern int lineno;
66
67 #if USE_CPPLIB
68 extern unsigned char *yy_cur, *yy_lim;
69 extern int yy_get_token ();
70 #endif
71
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));
77
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));
81
82 static inline struct input_source *
83 allocate_input ()
84 {
85   struct input_source *inp;
86   if (free_inputs)
87     {
88       inp = free_inputs;
89       free_inputs = inp->next;
90       inp->next = 0;
91       return inp;
92     }
93   inp = (struct input_source *) xmalloc (sizeof (struct input_source));
94   inp->next = 0;
95   return inp;
96 }
97
98 static inline void
99 free_input (inp)
100      struct input_source *inp;
101 {
102   inp->str = 0;
103   inp->length = 0;
104   inp->next = free_inputs;
105   free_inputs = inp;
106 }
107
108 /* Some of these external functions are declared inline in case this file
109    is included in lex.c.  */
110
111 inline
112 void
113 feed_input (str, len, file, line)
114      char *str;
115      int len;
116      char *file;
117      int line;
118 {
119   struct input_source *inp = allocate_input ();
120
121   /* This shouldn't be necessary.  */
122   while (len && !str[len-1])
123     len--;
124
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;
151 }
152
153 extern int end_of_file;
154
155 static inline void
156 end_input ()
157 {
158   struct input_source *inp = input;
159
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
167
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);
174 }
175
176 inline int
177 getch ()
178 {
179 #if USE_CPPLIB
180   return (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ());
181 #else
182   if (putback.index != -1)
183     {
184       int ch = putback.buffer[putback.index];
185       --putback.index;
186       return ch;
187     }
188   if (input)
189     {
190       if (input->offset >= input->length)
191         {
192           my_friendly_assert (putback.index == -1, 223);
193           ++(input->offset);
194           if (input->offset - input->length < 64)
195             return EOF;
196
197           /* We must be stuck in an error-handling rule; give up.  */
198           end_input ();
199           return getch ();
200         }
201       return (unsigned char)input->str[input->offset++];
202     }
203   return getc (finput);
204 #endif
205 }
206
207 inline
208 void
209 put_back (ch)
210      int ch;
211 {
212 #if USE_CPPLIB
213   if (ch == EOF)
214     ;
215   else if (yy_cur[-1] != ch)
216     my_friendly_abort (990709);
217   else
218     yy_cur--;
219 #else
220   if (ch != EOF)
221     {
222       if (putback.index == putback.buffer_size - 1)
223         {
224           putback.buffer_size += 16;
225           putback.buffer = xrealloc (putback.buffer, putback.buffer_size);
226         }
227       my_friendly_assert (putback.buffer != NULL, 224);
228       putback.buffer[++putback.index] = ch;
229     }
230 #endif
231 }
232
233 inline
234 int
235 input_redirected ()
236 {
237 #ifdef USE_CPPLIB
238   return CPP_BUFFER(&parse_in)->manual_pop;
239 #else
240   return input != 0;
241 #endif
242 }