|
|
1.1 root 1: /* Input handling for G++.
2: Written by Ken Raeburn of Watchmaker Computing.
3: Copyright (C) 1992 Free Software Foundation, Inc.
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 <assert.h>
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 cp-lex.c. */
102:
103: inline
104: void
105: feed_input (str, len, delete)
106: char *str;
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: assert (putback_char == -1);
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: assert (putback_char == -1);
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.