OSDN Git Service

* config/linux.h (ASM_COMMENT_START): Remove from here,
[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 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
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;
86   return inp;
87 }
88
89 static inline void
90 free_input (inp)
91      struct input_source *inp;
92 {
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
102    is included in lex.c.  */
103
104 inline
105 void
106 feed_input (str, len)
107      char *str;
108      int len;
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->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
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
147 static inline int
148 sub_getch ()
149 {
150   if (putback_char != -1)
151     {
152       int ch = putback_char;
153       putback_char = -1;
154       return ch;
155     }
156   if (input)
157     {
158       if (input->offset >= input->length)
159         {
160           my_friendly_assert (putback_char == -1, 223);
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 ();
168         }
169       return (unsigned char)input->str[input->offset++];
170     }
171   return getc (finput);
172 }
173
174 inline
175 void
176 put_back (ch)
177      int ch;
178 {
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;
198 }
199
200 inline
201 int
202 input_redirected ()
203 {
204   return input != 0;
205 }