OSDN Git Service

(handle_braces): Rework last change.
[pf3gnuchains/gcc-fork.git] / gcc / cp / input.c
1 /* Input handling for G++.
2    Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
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
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
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
29    lex.c for very minor efficiency gains (primarily in function
30    inlining).  */
31
32 #include <stdio.h>
33 #include "obstack.h"
34
35 extern FILE *finput;
36
37 struct pending_input *save_pending_input ();
38 void restore_pending_input ();
39
40 struct input_source {
41   /* saved string */
42   char *str;
43   int length;
44   /* current position, when reading as input */
45   int offset;
46   /* obstack to free this input string from when finished, if any */
47   struct obstack *obstack;
48   /* linked list maintenance */
49   struct input_source *next;
50   /* values to restore after reading all of current string */
51   char *filename;
52   int lineno;
53   struct pending_input *input;
54   int putback_char;
55 };
56
57 static struct input_source *input, *free_inputs;
58
59 extern char *input_filename;
60 extern int lineno;
61
62 #ifdef __GNUC__
63 #define inline __inline__
64 #else
65 #define inline
66 #endif
67
68 static inline struct input_source *
69 allocate_input ()
70 {
71   struct input_source *inp;
72   if (free_inputs)
73     {
74       inp = free_inputs;
75       free_inputs = inp->next;
76       inp->next = 0;
77       return inp;
78     }
79   inp = (struct input_source *) xmalloc (sizeof (struct input_source));
80   inp->next = 0;
81   inp->obstack = 0;
82   return inp;
83 }
84
85 static inline void
86 free_input (inp)
87      struct input_source *inp;
88 {
89   if (inp->obstack)
90     obstack_free (inp->obstack, inp->str);
91   inp->obstack = 0;
92   inp->str = 0;
93   inp->length = 0;
94   inp->next = free_inputs;
95   free_inputs = inp;
96 }
97
98 static int putback_char = -1;
99
100 /* Some of these external functions are declared inline in case this file
101    is included in lex.c.  */
102
103 inline
104 void
105 feed_input (str, len, delete)
106      char *str;
107      int len;
108      struct obstack *delete;
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;
118   inp->obstack = delete;
119   inp->offset = 0;
120   inp->next = input;
121   inp->filename = input_filename;
122   inp->lineno = lineno;
123   inp->input = save_pending_input ();
124   inp->putback_char = putback_char;
125   putback_char = -1;
126   input = inp;
127 }
128
129 struct pending_input *to_be_restored; /* XXX */
130 extern int end_of_file;
131
132 static inline int
133 sub_getch ()
134 {
135   if (putback_char != -1)
136     {
137       int ch = putback_char;
138       putback_char = -1;
139       return ch;
140     }
141   if (input)
142     {
143       if (input->offset == input->length)
144         {
145           struct input_source *inp = input;
146           my_friendly_assert (putback_char == -1, 223);
147           to_be_restored = inp->input;
148           input->offset++;
149           return EOF;
150         }
151       else if (input->offset > input->length)
152         {
153           struct input_source *inp = input;
154
155           end_of_file = 0;
156           input = inp->next;
157           input_filename = inp->filename;
158           lineno = inp->lineno;
159           /* Get interface/implementation back in sync.  */
160           extract_interface_info ();
161           putback_char = inp->putback_char;
162           free_input (inp);
163           return getch ();
164         }
165       if (input)
166         return (unsigned char)input->str[input->offset++];
167     }
168   return getc (finput);
169 }
170
171 inline
172 void
173 put_back (ch)
174      int ch;
175 {
176   if (ch != EOF)
177     {
178       my_friendly_assert (putback_char == -1, 224);
179       putback_char = ch;
180     }
181 }
182
183 extern int linemode;
184
185 int
186 getch ()
187 {
188   int ch = sub_getch ();
189   if (linemode && ch == '\n')
190     {
191       put_back (ch);
192       ch = EOF;
193     }
194   return ch;
195 }
196
197 inline
198 int
199 input_redirected ()
200 {
201   return input != 0;
202 }