|
|
1.1 root 1: /* Input handling for G++. 1.1.1.3 ! root 2: Copyright (C) 1992, 1993 Free Software Foundation, Inc. ! 3: Written by Ken Raeburn ([email protected]) while at Watchmaker Computing. 1.1 root 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; 1.1.1.2 root 106: int len; 1.1 root 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; 1.1.1.2 root 145: my_friendly_assert (putback_char == -1, 223); 1.1 root 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: { 1.1.1.2 root 175: my_friendly_assert (putback_char == -1, 224); 1.1 root 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.