|
|
1.1 root 1: /* Input handling for G++.
2: Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3: Written by Ken Raeburn ([email protected]) 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: /* G++ needs to do enough saving and re-parsing of text that it is
22: necessary to abandon the simple FILE* model and use a mechanism where
23: we can pre-empt one input stream with another derived from saved text;
24: we may need to do this arbitrarily often, and cannot depend on having
25: the GNU library available, so FILE objects just don't cut it.
26:
27: This file is written as a separate module, but can be included by
28: cp-lex.c for very minor efficiency gains (primarily in function
29: inlining). */
30:
31: #include <stdio.h>
32: #include "obstack.h"
33:
34: extern FILE *finput;
35:
36: struct pending_input *save_pending_input ();
37: void restore_pending_input ();
38:
39: struct input_source {
40: /* saved string */
41: char *str;
42: int length;
43: /* current position, when reading as input */
44: int offset;
45: /* obstack to free this input string from when finished, if any */
46: struct obstack *obstack;
47: /* linked list maintenance */
48: struct input_source *next;
49: /* values to restore after reading all of current string */
50: char *filename;
51: int lineno;
52: struct pending_input *input;
53: int putback_char;
54: };
55:
56: static struct input_source *input, *free_inputs;
57:
58: extern char *input_filename;
59: extern int lineno;
60:
61: #ifdef __GNUC__
62: #define inline __inline__
63: #else
64: #define inline
65: #endif
66:
67: static inline struct input_source *
68: allocate_input ()
69: {
70: struct input_source *inp;
71: if (free_inputs)
72: {
73: inp = free_inputs;
74: free_inputs = inp->next;
75: inp->next = 0;
76: return inp;
77: }
78: inp = (struct input_source *) xmalloc (sizeof (struct input_source));
79: inp->next = 0;
80: inp->obstack = 0;
81: return inp;
82: }
83:
84: static inline void
85: free_input (inp)
86: struct input_source *inp;
87: {
88: if (inp->obstack)
89: obstack_free (inp->obstack, inp->str);
90: inp->obstack = 0;
91: inp->str = 0;
92: inp->length = 0;
93: inp->next = free_inputs;
94: free_inputs = inp;
95: }
96:
97: static int putback_char = -1;
98:
99: /* Some of these external functions are declared inline in case this file
100: is included in cp-lex.c. */
101:
102: inline
103: void
104: feed_input (str, len, delete)
105: char *str;
106: int len;
107: struct obstack *delete;
108: {
109: struct input_source *inp = allocate_input ();
110:
111: /* This shouldn't be necessary. */
112: while (len && !str[len-1])
113: len--;
114:
115: inp->str = str;
116: inp->length = len;
117: inp->obstack = delete;
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: int
132: getch ()
133: {
134: if (putback_char != -1)
135: {
136: int ch = putback_char;
137: putback_char = -1;
138: return ch;
139: }
140: if (input)
141: {
142: if (input->offset == input->length)
143: {
144: struct input_source *inp = input;
145: my_friendly_assert (putback_char == -1, 223);
146: to_be_restored = inp->input;
147: input->offset++;
148: return EOF;
149: }
150: else if (input->offset > input->length)
151: {
152: struct input_source *inp = input;
153:
154: end_of_file = 0;
155: input = inp->next;
156: input_filename = inp->filename;
157: lineno = inp->lineno;
158: /* Get interface/implementation back in sync. */
159: extract_interface_info ();
160: putback_char = inp->putback_char;
161: free_input (inp);
162: return getch ();
163: }
164: if (input)
165: return input->str[input->offset++];
166: }
167: return getc (finput);
168: }
169:
170: inline
171: void
172: put_back (ch)
173: int ch;
174: {
175: my_friendly_assert (putback_char == -1, 224);
176: putback_char = ch;
177: }
178:
179: inline
180: int
181: input_redirected ()
182: {
183: return input != 0;
184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.