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