OSDN Git Service

* alpha.md (addsi3, subsi3): No new temporaries once cse is
[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 "system.h"
33
34 extern FILE *finput;
35
36 struct input_source {
37   /* saved string */
38   char *str;
39   int length;
40   /* current position, when reading as input */
41   int offset;
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
62 #if USE_CPPLIB
63 extern unsigned char *yy_cur, *yy_lim;
64 extern int yy_get_token ();
65 #define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
66 #else
67 #define GETC() getc (finput)
68 #endif
69
70 extern void feed_input PROTO((char *, int));
71 extern void put_input PROTO((int));
72 extern void put_back PROTO((int));
73 extern int getch PROTO((void));
74 extern int input_redirected PROTO((void));
75
76 static inline struct input_source * allocate_input PROTO((void));
77 static inline void free_input PROTO((struct input_source *));
78 static inline void end_input PROTO((void));
79 static inline int sub_getch PROTO((void));
80
81 static inline struct input_source *
82 allocate_input ()
83 {
84   struct input_source *inp;
85   if (free_inputs)
86     {
87       inp = free_inputs;
88       free_inputs = inp->next;
89       inp->next = 0;
90       return inp;
91     }
92   inp = (struct input_source *) xmalloc (sizeof (struct input_source));
93   inp->next = 0;
94   return inp;
95 }
96
97 static inline void
98 free_input (inp)
99      struct input_source *inp;
100 {
101   inp->str = 0;
102   inp->length = 0;
103   inp->next = free_inputs;
104   free_inputs = inp;
105 }
106
107 static int putback_char = -1;
108
109 /* Some of these external functions are declared inline in case this file
110    is included in lex.c.  */
111
112 inline
113 void
114 feed_input (str, len)
115      char *str;
116      int len;
117 {
118   struct input_source *inp = allocate_input ();
119
120   /* This shouldn't be necessary.  */
121   while (len && !str[len-1])
122     len--;
123
124   inp->str = str;
125   inp->length = len;
126   inp->offset = 0;
127   inp->next = input;
128   inp->filename = input_filename;
129   inp->lineno = lineno;
130   inp->input = save_pending_input ();
131   inp->putback_char = putback_char;
132   putback_char = -1;
133   input = inp;
134 }
135
136 struct pending_input *to_be_restored; /* XXX */
137 extern int end_of_file;
138
139 static inline void
140 end_input ()
141 {
142   struct input_source *inp = input;
143
144   end_of_file = 0;
145   input = inp->next;
146   input_filename = inp->filename;
147   lineno = inp->lineno;
148   /* Get interface/implementation back in sync.  */
149   extract_interface_info ();
150   putback_char = inp->putback_char;
151   restore_pending_input (inp->input);
152   free_input (inp);
153 }
154
155 static inline int
156 sub_getch ()
157 {
158   if (putback_char != -1)
159     {
160       int ch = putback_char;
161       putback_char = -1;
162       return ch;
163     }
164   if (input)
165     {
166       if (input->offset >= input->length)
167         {
168           my_friendly_assert (putback_char == -1, 223);
169           ++(input->offset);
170           if (input->offset - input->length < 64)
171             return EOF;
172
173           /* We must be stuck in an error-handling rule; give up.  */
174           end_input ();
175           return getch ();
176         }
177       return (unsigned char)input->str[input->offset++];
178     }
179   return GETC ();
180 }
181
182 inline
183 void
184 put_back (ch)
185      int ch;
186 {
187   if (ch != EOF)
188     {
189       my_friendly_assert (putback_char == -1, 224);
190       putback_char = ch;
191     }
192 }
193
194 extern int linemode;
195
196 int
197 getch ()
198 {
199   int ch = sub_getch ();
200   if (linemode && ch == '\n')
201     {
202       put_back (ch);
203       ch = EOF;
204     }
205   return ch;
206 }
207
208 inline
209 int
210 input_redirected ()
211 {
212   return input != 0;
213 }