/* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.jacorb.idl; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Stack; import java.util.logging.Level; /** * This class deals with IDL input files and their inclusion relationships. * * @author Gerald Brose */ public class GlobalInputStream { private static InputStream stream; private static Stack<Integer> lookahead_stack; private static boolean included; private static StringBuffer expandedText; private static int pos; private static boolean eof; private static File currentFile; private static String[] path_names; /** stack of information for lexical scopes */ static Stack<PositionInfo> positions; public static void init() { lookahead_stack = new Stack<Integer>(); included = false; expandedText = new StringBuffer(); pos = 0; eof = false; currentFile = null; positions = new Stack<PositionInfo>(); } public static void cleanUp() { stream = null; lookahead_stack = null; included = false; expandedText = null; pos = 0; eof = false; currentFile = null; path_names = null; } public static void setInput(String fname) throws java.io.IOException { currentFile = new File(fname); stream = new java.io.FileInputStream(currentFile); } /** * Test if this input stream (or rather the underlying IDL file) * is more recent (was modified at a later time than) another * file. (Used, e.g., to determine if code has been previosuly * generated from an IDL file). * * @param other the file to compare this stream against * @return true, if this stream's IDL file is more recent than the other file . */ public static boolean isMoreRecentThan(File other) { return (parser.forceOverwrite || (other.lastModified() < currentFile.lastModified())) ; } public static boolean includeState() { return included; } public static void insert(String str) { expandedText.insert(pos, str); } public static void include(String fname, int lookahead, boolean useIncludePath) throws FileNotFoundException { included = true; PositionInfo position = lexer.getPosition(); position.file = currentFile(); position.stream = stream; stream = find(fname, useIncludePath); positions.push(position); lookahead_stack.push(new Integer(lookahead)); if (parser.logger.isLoggable(Level.FINEST)) parser.logger.log(Level.FINEST, "Including " + fname); /* files form their own scopes, so we have to open a new one here */ } public static void setIncludePath(String path) { java.util.StringTokenizer strtok = new java.util.StringTokenizer(path, File.pathSeparator); int i; if (path_names == null) { path_names = new String[ strtok.countTokens() ]; i = 0; } else { i = path_names.length; String[] _path_names = new String[ strtok.countTokens() + path_names.length ]; for (int j = 0; j < path_names.length; j++) _path_names[ j ] = path_names[ j ]; path_names = _path_names; } while(strtok.hasMoreTokens()) { path_names[ i++ ] = strtok.nextToken(); } } /** * tries to locate and open a new file for "fname", * updates currentFile if successful */ private static FileInputStream find(String fname, boolean useIncludePath) throws FileNotFoundException { if (!useIncludePath) { if (fname.indexOf(File.separator) != 0) { String dir = null; try { dir = currentFile.getCanonicalPath(); if (dir.indexOf(File.separator) > -1) { dir = dir.substring(0, dir.lastIndexOf(File.separator)); } } catch(java.io.IOException ioe) { parser.logger.log(Level.SEVERE, "Caught error finding file ", ioe); } if (parser.logger.isLoggable(Level.FINEST)) parser.logger.log(Level.FINEST, "opening " + dir + File.separator + fname); currentFile = new File(dir + File.separator + fname); } else currentFile = new File(fname); try { return new FileInputStream(currentFile); } catch(java.io.IOException iof) { return find(fname, true); } } else { if (path_names == null) { org.jacorb.idl.parser.fatal_error("File " + fname + " not found in include path", null); } else { for (int i = 0; i < path_names.length; i++) { try { if (parser.logger.isLoggable(Level.FINEST)) parser.logger.log(Level.FINEST, "opening " + path_names[ i ] + File.separator + fname); currentFile = new File(path_names[ i ] + File.separator + fname); return new FileInputStream(currentFile); } catch(FileNotFoundException fnfex) { } } } org.jacorb.idl.parser.fatal_error("File " + fname + " not found in include path", null); return null; } } public static File currentFile() { return currentFile; } public static InputStream currentStream() { return stream; } public static int read() throws IOException { int ch = 0; // Might be the end of file for main file but still have an included file // to process. if (eof && positions.size() == 0) { return -1; } if (expandedText.length() > 0) { if (pos < expandedText.length()) ch = expandedText.charAt(pos++); if (pos == expandedText.length()) { expandedText = new StringBuffer(); pos = 0; } } else { ch = currentStream().read(); /* * if eof is reached, see whether we were reading * from the main input stream or from an include file. * If the latter, switch back to the main stream */ if (ch == -1) { // the following line was moved here to fix bug #385 currentStream().close(); if (included) { // undo effects of inhibition pragma parser.setInhibitionState(false); // return to last position in previous file PositionInfo positionInfo = positions.pop(); stream = positionInfo.stream; currentFile = positionInfo.file; ch = lookahead_stack.pop().intValue(); included = !(positions.empty()); if (parser.logger.isLoggable(Level.FINEST)) parser.logger.log(Level.FINEST, "returning to " + currentFile + " included: " + included); lexer.restorePosition(positionInfo); } else { eof = true; } } } return ch; } }