|
|
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.