| /* |
| * Copyright 2000-2004 The Apache Software Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * 2006-12-29: Modified to work for antlr3 by Jürgen Pfundt |
| * 2007-01-04: Some minor correction after checking code with findBugs tool |
| * 2007-02-10: Adapted the grammar type recognition to the changed naming |
| * conventions for Tree Parser |
| * 2007-10-17: Options "trace", "traceLexer", "traceParser" and "glib" emit |
| * warnings when being used. |
| * Added recognition of "parser grammar T". |
| * Added options "nocollapse", "noprune". |
| * ANTLR option "depend" is being used to resolve build dependencies. |
| * 2007-11-15: Embedded Classpath statement had not been observed |
| * with option depend="true" (Reported by Mats Behre) |
| * 2008-03-31: Support the option conversiontimeout. (Jim Idle) |
| * 2007-12-31: With option "depend=true" proceed even if first pass failed so |
| * that ANTLR can spit out its errors |
| * 2008-08-09: Inspecting environment variable ANTLR_HOME to detect and add |
| * antlr- and stringtemplate libraries to the classpath |
| * 2008-08-09: Removed routine checkGenerateFile. It got feeble with the |
| * introduction of composed grammars, e.g. "import T.g" and after |
| * a short struggle it started it's journey to /dev/null. |
| * From now one it is always antlr itself via the depend option |
| * which decides about dependecies |
| * 2008-08-19: Dependency check for composed grammars added. |
| * Might need some further improvements. |
| */ |
| package org.apache.tools.ant.antlr; |
| |
| import java.util.regex.*; |
| import java.io.*; |
| import java.util.Map; |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.DirectoryScanner; |
| import org.apache.tools.ant.Project; |
| import org.apache.tools.ant.Task; |
| import org.apache.tools.ant.taskdefs.Execute; |
| import org.apache.tools.ant.taskdefs.LogOutputStream; |
| import org.apache.tools.ant.taskdefs.PumpStreamHandler; |
| import org.apache.tools.ant.taskdefs.Redirector; |
| import org.apache.tools.ant.types.Commandline; |
| import org.apache.tools.ant.types.CommandlineJava; |
| import org.apache.tools.ant.types.Path; |
| import org.apache.tools.ant.util.JavaEnvUtils; |
| import org.apache.tools.ant.util.LoaderUtils; |
| import org.apache.tools.ant.util.TeeOutputStream; |
| import org.apache.tools.ant.util.FileUtils; |
| |
| /** |
| * Invokes the ANTLR3 Translator generator on a grammar file. |
| * |
| */ |
| public class ANTLR3 extends Task { |
| |
| private CommandlineJava commandline = new CommandlineJava(); |
| /** the file to process */ |
| private File target = null; |
| /** where to output the result */ |
| private File outputDirectory = null; |
| /** location of token files */ |
| private File libDirectory = null; |
| /** an optional super grammar file */ |
| private File superGrammar; |
| /** depend */ |
| private boolean depend = false; |
| /** fork */ |
| private boolean fork; |
| /** name of output style for messages */ |
| private String messageFormatName; |
| /** optional flag to print out a diagnostic file */ |
| private boolean diagnostic; |
| /** optional flag to add methods */ |
| private boolean trace; |
| /** optional flag to add trace methods to the parser only */ |
| private boolean traceParser; |
| /** optional flag to add trace methods to the lexer only */ |
| private boolean traceLexer; |
| /** working directory */ |
| private File workingdir = null; |
| /** captures ANTLR's output */ |
| private ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| /** The debug attribute */ |
| private boolean debug; |
| /** The report attribute */ |
| private boolean report; |
| /** The print attribute */ |
| private boolean print; |
| /** The profile attribute */ |
| private boolean profile; |
| /** The nfa attribute */ |
| private boolean nfa; |
| /** The dfa attribute */ |
| private boolean dfa; |
| /** multi threaded analysis */ |
| private boolean multiThreaded; |
| /** collapse incident edges into DFA states */ |
| private boolean nocollapse; |
| /** test lookahead against EBNF block exit branches */ |
| private boolean noprune; |
| /** put tags at start/stop of all templates in output */ |
| private boolean dbgST; |
| /** print AST */ |
| private boolean grammarTree; |
| /** Instance of a utility class to use for file operations. */ |
| private FileUtils fileUtils; |
| /** |
| * Whether to override the default conversion timeout with -Xconversiontimeout nnnn |
| */ |
| private String conversiontimeout; |
| |
| public ANTLR3() { |
| commandline.setVm(JavaEnvUtils.getJreExecutable("java")); |
| commandline.setClassname("org.antlr.Tool"); |
| fileUtils = FileUtils.getFileUtils(); |
| } |
| |
| /** |
| * The grammar file to process. |
| */ |
| public void setTarget(File targetFile) { |
| log("Setting target to: " + targetFile.toString(), Project.MSG_VERBOSE); |
| this.target = targetFile; |
| } |
| |
| /** |
| * The directory to write the generated files to. |
| */ |
| public void setOutputdirectory(File outputDirectoryFile) { |
| log("Setting output directory to: " + outputDirectoryFile.toString(), Project.MSG_VERBOSE); |
| this.outputDirectory = outputDirectoryFile; |
| } |
| |
| /** |
| * The directory to write the generated files to. |
| */ |
| public File getOutputdirectory() { |
| return outputDirectory; |
| } |
| |
| /** |
| * The token files output directory. |
| */ |
| public void setLibdirectory(File libDirectoryFile) { |
| log("Setting lib directory to: " + libDirectoryFile.toString(), Project.MSG_VERBOSE); |
| this.libDirectory = libDirectoryFile; |
| } |
| |
| /** |
| * The output style for messages. |
| */ |
| public void setMessageformat(String name) { |
| log("Setting message-format to: " + name, Project.MSG_VERBOSE); |
| this.messageFormatName = name; |
| } |
| |
| /** |
| * Sets an optional super grammar file |
| * @deprecated |
| */ |
| public void setGlib(File superGrammarFile) { |
| this.superGrammar = superGrammarFile; |
| } |
| |
| /** |
| * Sets a flag to enable ParseView debugging |
| */ |
| public void setDebug(boolean enable) { |
| this.debug = enable; |
| } |
| |
| /** |
| * Sets a flag to enable report statistics |
| */ |
| public void setReport(boolean enable) { |
| this.report = enable; |
| } |
| |
| /** |
| * Sets a flag to print out the grammar without actions |
| */ |
| public void setPrint(boolean enable) { |
| this.print = enable; |
| } |
| |
| /** |
| * Sets a flag to enable profiling |
| */ |
| public void setProfile(boolean enable) { |
| this.profile = enable; |
| } |
| |
| /** |
| * Sets a flag to enable nfa generation |
| */ |
| public void setNfa(boolean enable) { |
| this.nfa = enable; |
| } |
| |
| /** |
| * Sets a flag to enable nfa generation |
| */ |
| public void setDfa(boolean enable) { |
| this.dfa = enable; |
| } |
| |
| /** |
| * Run the analysis multithreaded |
| * @param enable |
| */ |
| public void setMultithreaded(boolean enable) { |
| multiThreaded = enable; |
| } |
| |
| /** |
| * collapse incident edges into DFA states |
| * @param enable |
| */ |
| public void setNocollapse(boolean enable) { |
| nocollapse = enable; |
| } |
| |
| /** |
| * test lookahead against EBNF block exit branches |
| * @param enable |
| */ |
| public void setNoprune(boolean enable) { |
| noprune = enable; |
| } |
| |
| /** |
| * test lookahead against EBNF block exit branches |
| * @param enable |
| */ |
| public void setDbgST(boolean enable) { |
| dbgST = enable; |
| } |
| |
| /** |
| * override the default conversion timeout with -Xconversiontimeout nnnn |
| * @param conversiontimeoutString |
| */ |
| public void setConversiontimeout(String conversiontimeoutString) { |
| log("Setting conversiontimeout to: " + conversiontimeoutString, Project.MSG_VERBOSE); |
| try { |
| int timeout = Integer.valueOf(conversiontimeoutString); |
| this.conversiontimeout = conversiontimeoutString; |
| } catch (NumberFormatException e) { |
| log("Option ConversionTimeOut ignored due to illegal value: '" + conversiontimeoutString + "'", Project.MSG_ERR); |
| } |
| } |
| |
| /** |
| * Set a flag to enable printing of the grammar tree |
| */ |
| public void setGrammartree(boolean enable) { |
| grammarTree = enable; |
| } |
| |
| /** |
| * Set a flag to enable dependency checking by ANTLR itself |
| * The depend option is always used implicitely inside the antlr3 task |
| * @deprecated |
| */ |
| public void setDepend(boolean s) { |
| this.depend = s; |
| } |
| |
| /** |
| * Sets a flag to emit diagnostic text |
| */ |
| public void setDiagnostic(boolean enable) { |
| diagnostic = enable; |
| } |
| |
| /** |
| * If true, enables all tracing. |
| * @deprecated |
| */ |
| public void setTrace(boolean enable) { |
| trace = enable; |
| } |
| |
| /** |
| * If true, enables parser tracing. |
| * @deprecated |
| */ |
| public void setTraceParser(boolean enable) { |
| traceParser = enable; |
| } |
| |
| /** |
| * If true, enables lexer tracing. |
| * @deprecated |
| */ |
| public void setTraceLexer(boolean enable) { |
| traceLexer = enable; |
| } |
| |
| // we are forced to fork ANTLR since there is a call |
| // to System.exit() and there is nothing we can do |
| // right now to avoid this. :-( (SBa) |
| // I'm not removing this method to keep backward compatibility |
| /** |
| * @ant.attribute ignore="true" |
| */ |
| public void setFork(boolean s) { |
| this.fork = s; |
| } |
| |
| /** |
| * The working directory of the process |
| */ |
| public void setDir(File d) { |
| this.workingdir = d; |
| } |
| |
| /** |
| * Adds a classpath to be set |
| * because a directory might be given for Antlr debug. |
| */ |
| public Path createClasspath() { |
| return commandline.createClasspath(getProject()).createPath(); |
| } |
| |
| /** |
| * Adds a new JVM argument. |
| * @return create a new JVM argument so that any argument can be passed to the JVM. |
| * @see #setFork(boolean) |
| */ |
| public Commandline.Argument createJvmarg() { |
| return commandline.createVmArgument(); |
| } |
| |
| /** |
| * Adds the jars or directories containing Antlr and associates. |
| * This should make the forked JVM work without having to |
| * specify it directly. |
| */ |
| @Override |
| public void init() throws BuildException { |
| /* Inquire environment variables */ |
| Map<String, String> variables = System.getenv(); |
| /* Get value for key "ANTLR_HOME" which should hopefully point to |
| * the directory where the current version of antlr3 is installed */ |
| String antlrHome = variables.get("ANTLR_HOME"); |
| if (antlrHome != null) { |
| /* Environment variable ANTLR_HOME has been defined. |
| * Now add all antlr and stringtemplate libraries to the |
| * classpath */ |
| addAntlrJarsToClasspath(antlrHome + "/lib"); |
| } |
| addClasspathEntry("/antlr/ANTLRGrammarParseBehavior.class", "AntLR2"); |
| addClasspathEntry("/org/antlr/tool/ANTLRParser.class", "AntLR3"); |
| addClasspathEntry("/org/antlr/stringtemplate/StringTemplate.class", "Stringtemplate"); |
| |
| |
| } |
| |
| /** |
| * Search for the given resource and add the directory or archive |
| * that contains it to the classpath. |
| * |
| * <p>Doesn't work for archives in JDK 1.1 as the URL returned by |
| * getResource doesn't contain the name of the archive.</p> |
| */ |
| protected void addClasspathEntry(String resource, String msg) { |
| /* |
| * pre Ant 1.6 this method used to call getClass().getResource |
| * while Ant 1.6 will call ClassLoader.getResource(). |
| * |
| * The difference is that Class.getResource expects a leading |
| * slash for "absolute" resources and will strip it before |
| * delegating to ClassLoader.getResource - so we now have to |
| * emulate Class's behavior. |
| */ |
| if (resource.startsWith("/")) { |
| resource = resource.substring(1); |
| } else { |
| resource = "org/apache/tools/ant/taskdefs/optional/" + resource; |
| } |
| |
| File f = LoaderUtils.getResourceSource(getClass().getClassLoader(), resource); |
| if (f != null) { |
| log("Found via classpath: " + f.getAbsolutePath(), Project.MSG_VERBOSE); |
| createClasspath().setLocation(f); |
| } else { |
| log("Couldn\'t find resource " + resource + " for library " + msg + " in external classpath", Project.MSG_VERBOSE); |
| } |
| } |
| |
| /** |
| * If the environment variable ANTLR_HOME is defined and points |
| * to the installation directory of antlr3 then look for all antlr-*.jar and |
| * stringtemplate-*.jar files in the lib directory and add them |
| * to the classpath. |
| * This feature should make working with eclipse or netbeans projects a |
| * little bit easier. As wildcards are being used for the version part |
| * of the jar-archives it makes the task independent of |
| * new releases. Just let ANTLR_HOME point to the new installation |
| * directory. |
| */ |
| private void addAntlrJarsToClasspath(String antlrLibDir) { |
| String[] includes = {"antlr-*.jar", "stringtemplate-*.jar"}; |
| |
| DirectoryScanner ds = new DirectoryScanner(); |
| ds.setIncludes(includes); |
| ds.setBasedir(new File(antlrLibDir)); |
| ds.setCaseSensitive(true); |
| ds.scan(); |
| |
| String separator = System.getProperty("file.separator"); |
| String[] files = ds.getIncludedFiles(); |
| for (String file : files) { |
| File f = new File(antlrLibDir + separator + file); |
| log("Found via ANTLR_HOME: " + f.getAbsolutePath(), Project.MSG_VERBOSE); |
| createClasspath().setLocation(f); |
| } |
| } |
| |
| @Override |
| public void execute() throws BuildException { |
| |
| validateAttributes(); |
| |
| // Use ANTLR itself to resolve dependencies and decide whether |
| // to invoke ANTLR for compilation |
| if (dependencyCheck()) { |
| populateAttributes(); |
| commandline.createArgument().setValue(target.toString()); |
| |
| log(commandline.describeCommand(), Project.MSG_VERBOSE); |
| int err = 0; |
| try { |
| err = run(commandline.getCommandline(), new LogOutputStream(this, Project.MSG_INFO), new LogOutputStream(this, Project.MSG_WARN)); |
| } catch (IOException e) { |
| throw new BuildException(e, getLocation()); |
| } finally { |
| try { |
| bos.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| |
| if (err != 0) { |
| throw new BuildException("ANTLR returned: " + err, getLocation()); |
| } else { |
| Pattern p = Pattern.compile("error\\([0-9]+\\):"); |
| Matcher m = p.matcher(bos.toString()); |
| if (m.find()) { |
| throw new BuildException("ANTLR signaled an error.", getLocation()); |
| } |
| } |
| } else { |
| try { |
| log("All dependencies of grammar file \'" + target.getCanonicalPath() + "\' are up to date.", Project.MSG_VERBOSE); |
| } catch (IOException ex) { |
| log("All dependencies of grammar file \'" + target.toString() + "\' are up to date.", Project.MSG_VERBOSE); |
| } |
| } |
| } |
| |
| /** |
| * A refactored method for populating all the command line arguments based |
| * on the user-specified attributes. |
| */ |
| private void populateAttributes() { |
| |
| commandline.createArgument().setValue("-o"); |
| commandline.createArgument().setValue(outputDirectory.toString()); |
| |
| commandline.createArgument().setValue("-lib"); |
| commandline.createArgument().setValue(libDirectory.toString()); |
| |
| if (superGrammar != null) { |
| log("Option 'glib' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN); |
| } |
| |
| if (diagnostic) { |
| commandline.createArgument().setValue("-diagnostic"); |
| } |
| if (depend) { |
| log("Option 'depend' is implicitely always used by ANTLR v3. Option can safely be omitted!", Project.MSG_WARN); |
| } |
| if (trace) { |
| log("Option 'trace' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN); |
| } |
| if (traceParser) { |
| log("Option 'traceParser' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN); |
| } |
| if (traceLexer) { |
| log("Option 'traceLexer' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN); |
| } |
| if (debug) { |
| commandline.createArgument().setValue("-debug"); |
| } |
| if (report) { |
| commandline.createArgument().setValue("-report"); |
| } |
| if (print) { |
| commandline.createArgument().setValue("-print"); |
| } |
| if (profile) { |
| commandline.createArgument().setValue("-profile"); |
| } |
| if (messageFormatName != null) { |
| commandline.createArgument().setValue("-message-format"); |
| commandline.createArgument().setValue(messageFormatName); |
| } |
| if (nfa) { |
| commandline.createArgument().setValue("-nfa"); |
| } |
| if (dfa) { |
| commandline.createArgument().setValue("-dfa"); |
| } |
| if (multiThreaded) { |
| commandline.createArgument().setValue("-Xmultithreaded"); |
| } |
| if (nocollapse) { |
| commandline.createArgument().setValue("-Xnocollapse"); |
| } |
| if (noprune) { |
| commandline.createArgument().setValue("-Xnoprune"); |
| } |
| if (dbgST) { |
| commandline.createArgument().setValue("-XdbgST"); |
| } |
| if (conversiontimeout != null) { |
| commandline.createArgument().setValue("-Xconversiontimeout"); |
| commandline.createArgument().setValue(conversiontimeout); |
| } |
| if (grammarTree) { |
| commandline.createArgument().setValue("-Xgrtree"); |
| } |
| } |
| |
| private void validateAttributes() throws BuildException { |
| |
| if (target == null) { |
| throw new BuildException("No target grammar, lexer grammar or tree parser specified!"); |
| } else if (!target.isFile()) { |
| throw new BuildException("Target: " + target + " is not a file!"); |
| } |
| |
| // if no output directory is specified, use the target's directory |
| if (outputDirectory == null) { |
| setOutputdirectory(new File(target.getParent())); |
| } |
| |
| if (!outputDirectory.isDirectory()) { |
| throw new BuildException("Invalid output directory: " + outputDirectory); |
| } |
| |
| if (workingdir != null && !workingdir.isDirectory()) { |
| throw new BuildException("Invalid working directory: " + workingdir); |
| } |
| |
| // if no libDirectory is specified, use the target's directory |
| if (libDirectory == null) { |
| setLibdirectory(new File(target.getParent())); |
| } |
| |
| if (!libDirectory.isDirectory()) { |
| throw new BuildException("Invalid lib directory: " + libDirectory); |
| } |
| } |
| |
| private boolean dependencyCheck() throws BuildException { |
| // using "antlr -o <OutputDirectory> -lib <LibDirectory> -depend <T>" |
| // to get the list of dependencies |
| CommandlineJava cmdline; |
| try { |
| cmdline = (CommandlineJava) commandline.clone(); |
| } catch (java.lang.CloneNotSupportedException e) { |
| throw new BuildException("Clone of commandline failed: " + e); |
| } |
| |
| cmdline.createArgument().setValue("-depend"); |
| cmdline.createArgument().setValue("-o"); |
| cmdline.createArgument().setValue(outputDirectory.toString()); |
| cmdline.createArgument().setValue("-lib"); |
| cmdline.createArgument().setValue(libDirectory.toString()); |
| cmdline.createArgument().setValue(target.toString()); |
| |
| log(cmdline.describeCommand(), Project.MSG_VERBOSE); |
| |
| // redirect output generated by ANTLR to temporary file |
| Redirector r = new Redirector(this); |
| File f; |
| try { |
| f = File.createTempFile("depend", null, getOutputdirectory()); |
| f.deleteOnExit(); |
| log("Write dependencies for '" + target.toString() + "' to file '" + f.getCanonicalPath() + "'", Project.MSG_VERBOSE); |
| r.setOutput(f); |
| r.setAlwaysLog(false); |
| r.createStreams(); |
| } catch (IOException e) { |
| throw new BuildException("Redirection of output failed: " + e); |
| } |
| |
| // execute antlr -depend ... |
| int err = 0; |
| try { |
| err = run(cmdline.getCommandline(), r.getOutputStream(), null); |
| } catch (IOException e) { |
| try { |
| r.complete(); |
| log("Redirection of output terminated.", Project.MSG_VERBOSE); |
| } catch (IOException ex) { |
| log("Termination of output redirection failed: " + ex, Project.MSG_ERR); |
| } |
| throw new BuildException(e, getLocation()); |
| } finally { |
| try { |
| bos.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| |
| try { |
| r.complete(); |
| log("Redirection of output terminated.", Project.MSG_VERBOSE); |
| } catch (IOException e) { |
| log("Termination of output redirection failed: " + e, Project.MSG_ERR); |
| } |
| |
| if (err != 0) { |
| if (f.exists()) { |
| f.delete(); |
| } |
| if (cmdline.getClasspath() == null) { |
| log("Antlr libraries not found in external classpath or embedded classpath statement ", Project.MSG_ERR); |
| } |
| log("Dependency check failed. ANTLR returned: " + err, Project.MSG_ERR); |
| return true; |
| } else { |
| Pattern p = Pattern.compile("error\\([0-9]+\\):"); |
| Matcher m = p.matcher(bos.toString()); |
| if (m.find()) { |
| if (f.exists()) { |
| f.delete(); |
| } |
| // On error always recompile |
| return true; |
| } |
| } |
| |
| boolean compile = false; |
| |
| // open temporary file |
| BufferedReader in = null; |
| try { |
| in = new BufferedReader(new FileReader(f)); |
| } catch (IOException e) { |
| try { |
| if (in != null) { |
| in.close(); |
| } |
| } catch (IOException ex) { |
| throw new BuildException("Could not close file\'" + f.toString() + "\'."); |
| } |
| if (f.exists()) { |
| f.delete(); |
| } |
| try { |
| throw new BuildException("Could not open \'" + f.getCanonicalPath() + "\' for reading."); |
| } catch (IOException ex) { |
| throw new BuildException("Could not open \'" + f.toString() + "\' for reading."); |
| } |
| } |
| |
| // evaluate dependencies in temporary file |
| String s; |
| |
| try { |
| while ((s = in.readLine()) != null) { |
| String a; |
| String b; |
| // As the separator string in lines emitted by the depend option |
| // is either " : " or ": " trim is invoked for the first file name of a line |
| int to = s.indexOf(": "); |
| if (to >= 0) { |
| a = s.substring(0, to).trim(); |
| File lhs = new File(a); |
| if (!lhs.isFile()) { |
| log("File '" + a + "' is not a regular file", Project.MSG_VERBOSE); |
| String name = lhs.getName(); |
| String[] parts = splitRightHandSide(name, "\\u002E"); |
| if (parts.length <= 1) { |
| a += ".java"; |
| lhs = new File(a); |
| if (lhs.isFile()) { |
| log("File '" + a + "' is a regular file last modified at " + lhs.lastModified(), Project.MSG_VERBOSE); |
| } |
| } |
| } |
| |
| b = s.substring(to + ": ".length()); |
| String[] names = splitRightHandSide(b, ", ?"); |
| File aFile = new File(a); |
| for (String name : names) { |
| File bFile = new File(name); |
| log("File '" + a + "' depends on file '" + name + "'", Project.MSG_VERBOSE); |
| log("File '" + a + "' modified at " + aFile.lastModified(), Project.MSG_VERBOSE); |
| log("File '" + name + "' modified at " + bFile.lastModified(), Project.MSG_VERBOSE); |
| if (fileUtils.isUpToDate(aFile, bFile)) { |
| log("Compiling " + target + " as '" + name + "' is newer than '" + a + "'", Project.MSG_VERBOSE); |
| // Feeling not quite comfortable with touching the file |
| fileUtils.setFileLastModified(aFile, -1); |
| log("Touching file '" + a + "'", Project.MSG_VERBOSE); |
| compile = true; |
| break; |
| } |
| } |
| if (compile) { |
| break; |
| } |
| } |
| } |
| in.close(); |
| } catch (IOException e) { |
| if (f.exists()) { |
| f.delete(); |
| } |
| throw new BuildException("Error reading file '" + f.toString() + "'"); |
| } |
| |
| if (f.exists()) { |
| f.delete(); |
| } |
| |
| return compile; |
| } |
| |
| private String[] splitRightHandSide(String fileNames, String pattern) { |
| String[] names = fileNames.split(pattern); |
| for (String name : names) { |
| log("Split right hand side '" + name + "'", Project.MSG_VERBOSE); |
| } |
| return names; |
| } |
| |
| /** execute in a forked VM */ |
| private int run(String[] command, OutputStream out, OutputStream err) throws IOException { |
| PumpStreamHandler psh; |
| if (err == null) { |
| psh = new PumpStreamHandler(out, bos); |
| } else { |
| psh = new PumpStreamHandler(out, new TeeOutputStream(err, bos)); |
| } |
| |
| Execute exe = new Execute(psh, null); |
| |
| exe.setAntRun(getProject()); |
| if (workingdir != null) { |
| exe.setWorkingDirectory(workingdir); |
| } |
| |
| exe.setCommandline(command); |
| |
| return exe.execute(); |
| } |
| } |