001: /*
002: * JacORB - a free Java ORB
003: *
004: * Copyright (C) 1997-2004 Gerald Brose.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Library General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Library General Public License for more details.
015: *
016: * You should have received a copy of the GNU Library General Public
017: * License along with this library; if not, write to the Free
018: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
019: */
020:
021: package org.jacorb.idl;
022:
023: import java.io.*;
024: import java.util.Stack;
025:
026: /**
027: * This class deals with IDL input files and their inclusion relationships.
028: *
029: * @author Gerald Brose <mailto:gerald.brose@acm.org>
030: * @version $Id: GlobalInputStream.java,v 1.22 2004/05/06 12:39:58 nicolas Exp $
031: */
032:
033: public class GlobalInputStream {
034: private static InputStream stream;
035: private static Stack lookahead_stack;
036: private static boolean included;
037: private static StringBuffer expandedText;
038: private static int pos;
039: private static boolean eof;
040: private static File currentFile;
041: private static String[] path_names;
042: private static org.apache.log.Logger logger;
043:
044: /** stack of information for lexical scopes */
045: static java.util.Stack positions;
046:
047: public static void init() {
048: lookahead_stack = new Stack();
049: included = false;
050: expandedText = new StringBuffer();
051: pos = 0;
052: eof = false;
053: currentFile = null;
054: positions = new java.util.Stack();
055: logger = parser.getLogger();
056: }
057:
058: public static void setInput(String fname)
059: throws java.io.IOException {
060: currentFile = new File(fname);
061: stream = new java.io.FileInputStream(currentFile);
062: }
063:
064: /**
065: * Test if this input stream (or rather the underlying IDL file)
066: * is more recent (was modified at a later time than) another
067: * file. (Used, e.g., to determine if code has been previosuly
068: * generated from an IDL file).
069: *
070: * @param other the file to compare this stream against
071: * @return true, if this stream's IDL file is more recent than the other file .
072: */
073:
074: public static boolean isMoreRecentThan(File other) {
075: return (parser.forceOverwrite || (other.lastModified() < currentFile
076: .lastModified()));
077: }
078:
079: public static boolean includeState() {
080: return included;
081: }
082:
083: public static void insert(String str) {
084: expandedText.insert(pos, str);
085: }
086:
087: public static void include(String fname, int lookahead,
088: boolean useIncludePath) throws FileNotFoundException {
089: included = true;
090: PositionInfo position = lexer.getPosition();
091: position.file = currentFile();
092: position.stream = stream;
093:
094: stream = find(fname, useIncludePath);
095:
096: positions.push(position);
097: lookahead_stack.push(new Integer(lookahead));
098:
099: if (logger.isInfoEnabled())
100: logger.info("Including " + fname);
101: /* files form their own scopes, so we have to open a new one here */
102: }
103:
104: public static void setIncludePath(String path) {
105: java.util.StringTokenizer strtok = new java.util.StringTokenizer(
106: path, File.pathSeparator);
107:
108: int i;
109: if (path_names == null) {
110: path_names = new String[strtok.countTokens()];
111: i = 0;
112: } else {
113: i = path_names.length;
114:
115: String[] _path_names = new String[strtok.countTokens()
116: + path_names.length];
117: for (int j = 0; j < path_names.length; j++)
118: _path_names[j] = path_names[j];
119: path_names = _path_names;
120: }
121:
122: while (strtok.hasMoreTokens()) {
123: path_names[i++] = strtok.nextToken();
124: }
125: }
126:
127: /**
128: * tries to locate and open a new file for "fname",
129: * updates currentFile if successful
130: */
131:
132: private static FileInputStream find(String fname,
133: boolean useIncludePath) throws FileNotFoundException {
134: if (!useIncludePath) {
135: if (fname.indexOf(File.separator) != 0) {
136: String dir = null;
137: try {
138: dir = currentFile.getCanonicalPath();
139: if (dir.indexOf(File.separator) > -1) {
140: dir = dir.substring(0, dir
141: .lastIndexOf(File.separator));
142: }
143: } catch (java.io.IOException ioe) {
144: logger.error("Caught error finding file ", ioe);
145: }
146:
147: if (logger.isInfoEnabled())
148: logger.info("opening " + dir + File.separator
149: + fname);
150: currentFile = new File(dir + File.separator + fname);
151: } else
152: currentFile = new File(fname);
153:
154: try {
155: return new FileInputStream(currentFile);
156: } catch (java.io.IOException iof) {
157: return find(fname, true);
158: }
159: } else {
160: if (path_names == null) {
161: org.jacorb.idl.parser.fatal_error("File " + fname
162: + " not found in include path", null);
163: } else {
164: for (int i = 0; i < path_names.length; i++) {
165: try {
166: if (logger.isInfoEnabled())
167: logger.info("opening " + path_names[i]
168: + File.separator + fname);
169:
170: currentFile = new File(path_names[i]
171: + File.separator + fname);
172: return new FileInputStream(currentFile);
173: } catch (FileNotFoundException fnfex) {
174: }
175: }
176: }
177:
178: org.jacorb.idl.parser.fatal_error("File " + fname
179: + " not found in include path", null);
180: return null;
181: }
182: }
183:
184: public static File currentFile() {
185: return currentFile;
186: }
187:
188: public static InputStream currentStream() {
189: return stream;
190: }
191:
192: public static int read() throws IOException {
193: int ch = 0;
194:
195: // Might be the end of file for main file but still have an included file
196: // to process.
197: if (eof && positions.size() == 0) {
198: return -1;
199: }
200:
201: if (expandedText.length() > 0) {
202: if (pos < expandedText.length())
203: ch = (int) expandedText.charAt(pos++);
204: if (pos == expandedText.length()) {
205: expandedText = new StringBuffer();
206: pos = 0;
207: }
208: } else {
209: ch = currentStream().read();
210:
211: /*
212: * if eof is reached, see whether we were reading
213: * from the main input stream or from an include file.
214: * If the latter, switch back to the main stream
215: */
216:
217: if (ch == -1) {
218: // the following line was moved here to fix bug #385
219: currentStream().close();
220: if (included) {
221:
222: // undo effects of inhibition pragma
223: parser.setInhibitionState(false);
224:
225: // return to last position in previous file
226: PositionInfo positionInfo = (PositionInfo) positions
227: .pop();
228: stream = positionInfo.stream;
229: currentFile = positionInfo.file;
230: ch = ((Integer) lookahead_stack.pop()).intValue();
231:
232: included = !(positions.empty());
233:
234: if (logger.isInfoEnabled())
235: logger.info("returning to " + currentFile
236: + " included: " + included);
237:
238: lexer.restorePosition(positionInfo);
239: } else {
240: eof = true;
241: }
242: }
243: }
244: return ch;
245: }
246:
247: }
|