|
|
1.1 root 1: /* Input handling for G++. 1.1.1.2 ! root 2: Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 1.1 root 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 1.1.1.2 ! root 19: the Free Software Foundation, 59 Temple Place - Suite 330, ! 20: Boston, MA 02111-1307, USA. */ 1.1 root 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 <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 lex.c. */ 102: 103: inline 104: void 105: feed_input (str, len, delete) 106: char *str; 107: int len; 108: struct obstack *delete; 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->obstack = delete; 119: inp->offset = 0; 120: inp->next = input; 121: inp->filename = input_filename; 122: inp->lineno = lineno; 123: inp->input = save_pending_input (); 124: inp->putback_char = putback_char; 125: putback_char = -1; 126: input = inp; 127: } 128: 129: struct pending_input *to_be_restored; /* XXX */ 130: extern int end_of_file; 131: 1.1.1.2 ! root 132: static inline int ! 133: sub_getch () 1.1 root 134: { 135: if (putback_char != -1) 136: { 137: int ch = putback_char; 138: putback_char = -1; 139: return ch; 140: } 141: if (input) 142: { 143: if (input->offset == input->length) 144: { 145: struct input_source *inp = input; 146: my_friendly_assert (putback_char == -1, 223); 147: to_be_restored = inp->input; 148: input->offset++; 149: return EOF; 150: } 151: else if (input->offset > input->length) 152: { 153: struct input_source *inp = input; 154: 155: end_of_file = 0; 156: input = inp->next; 157: input_filename = inp->filename; 158: lineno = inp->lineno; 159: /* Get interface/implementation back in sync. */ 160: extract_interface_info (); 161: putback_char = inp->putback_char; 162: free_input (inp); 163: return getch (); 164: } 165: if (input) 166: return input->str[input->offset++]; 167: } 168: return getc (finput); 169: } 170: 171: inline 172: void 173: put_back (ch) 174: int ch; 175: { 1.1.1.2 ! root 176: if (ch != EOF) ! 177: { ! 178: my_friendly_assert (putback_char == -1, 224); ! 179: putback_char = ch; ! 180: } ! 181: } ! 182: ! 183: extern int linemode; ! 184: ! 185: int ! 186: getch () ! 187: { ! 188: int ch = sub_getch (); ! 189: if (linemode && ch == '\n') ! 190: { ! 191: put_back (ch); ! 192: ch = EOF; ! 193: } ! 194: return ch; 1.1 root 195: } 196: 197: inline 198: int 199: input_redirected () 200: { 201: return input != 0; 202: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.