1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright  2000-2004 The Apache Software Foundation
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Licensed under the Apache License, Version 2.0 (the "License");
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  you may not use this file except in compliance with the License.
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  You may obtain a copy of the License at
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      http://www.apache.org/licenses/LICENSE-2.0
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Unless required by applicable law or agreed to in writing, software
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  distributed under the License is distributed on an "AS IS" BASIS,
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  See the License for the specific language governing permissions and
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  limitations under the License.
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2006-12-29: Modified to work for antlr3 by J�rgen Pfundt
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2007-01-04: Some minor correction after checking code with findBugs tool
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2007-02-10: Adapted the grammar type recognition to the changed naming
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              conventions for Tree Parser
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2007-10-17: Options "trace", "traceLexer", "traceParser" and "glib" emit
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              warnings when being used.
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              Added recognition of "parser grammar T".
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              Added options "nocollapse", "noprune".
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              ANTLR option "depend" is being used to resolve build dependencies.
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2007-11-15: Embedded Classpath statement had not been observed
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              with option depend="true" (Reported by Mats Behre)
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2008-03-31: Support the option conversiontimeout. (Jim Idle)
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2007-12-31: With option "depend=true" proceed even if first pass failed so
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              that ANTLR can spit out its errors
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2008-08-09: Inspecting environment variable ANTLR_HOME to detect and add
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              antlr- and stringtemplate libraries to the classpath
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2008-08-09: Removed routine checkGenerateFile. It got feeble with the
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              introduction of composed grammars, e.g. "import T.g" and after
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              a short struggle it started it's journey to /dev/null.
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              From now one it is always antlr itself via the depend option
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              which decides about dependecies
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2008-08-19: Dependency check for composed grammars added.
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *              Might need some further improvements.
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.apache.tools.ant.antlr;
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.regex.*;
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.io.*;
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.Map;
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.BuildException;
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.DirectoryScanner;
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.Project;
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.Task;
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.taskdefs.Execute;
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.taskdefs.LogOutputStream;
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.taskdefs.PumpStreamHandler;
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.taskdefs.Redirector;
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.types.Commandline;
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.types.CommandlineJava;
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.types.Path;
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.util.JavaEnvUtils;
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.util.LoaderUtils;
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.util.TeeOutputStream;
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.apache.tools.ant.util.FileUtils;
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/**
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Invokes the ANTLR3 Translator generator on a grammar file.
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class ANTLR3 extends Task {
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private CommandlineJava commandline = new CommandlineJava();
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** the file to process */
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private File target = null;
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** where to output the result */
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private File outputDirectory = null;
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** location of token files */
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private File libDirectory = null;
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** an optional super grammar file */
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private File superGrammar;
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** depend */
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean depend = false;
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** fork */
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean fork;
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** name of output style for messages */
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private String messageFormatName;
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** optional flag to print out a diagnostic file */
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean diagnostic;
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** optional flag to add methods */
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean trace;
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** optional flag to add trace methods to the parser only */
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean traceParser;
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** optional flag to add trace methods to the lexer only */
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean traceLexer;
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** working directory */
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private File workingdir = null;
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** captures ANTLR's output */
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private ByteArrayOutputStream bos = new ByteArrayOutputStream();
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** The debug attribute */
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean debug;
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** The report attribute */
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean report;
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** The print attribute */
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean print;
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** The profile attribute */
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean profile;
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** The nfa attribute */
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean nfa;
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** The dfa attribute */
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean dfa;
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** multi threaded analysis */
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean multiThreaded;
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** collapse incident edges into DFA states */
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean nocollapse;
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** test lookahead against EBNF block exit branches */
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean noprune;
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** put tags at start/stop of all templates in output */
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean dbgST;
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** print AST */
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean grammarTree;
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** Instance of a utility class to use for file operations. */
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private FileUtils fileUtils;
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Whether to override the default conversion timeout with -Xconversiontimeout nnnn
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private String conversiontimeout;
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public ANTLR3() {
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        commandline.setVm(JavaEnvUtils.getJreExecutable("java"));
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        commandline.setClassname("org.antlr.Tool");
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        fileUtils = FileUtils.getFileUtils();
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * The grammar file to process.
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setTarget(File targetFile) {
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log("Setting target to: " + targetFile.toString(), Project.MSG_VERBOSE);
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.target = targetFile;
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * The directory to write the generated files to.
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setOutputdirectory(File outputDirectoryFile) {
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log("Setting output directory to: " + outputDirectoryFile.toString(), Project.MSG_VERBOSE);
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.outputDirectory = outputDirectoryFile;
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * The directory to write the generated files to.
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public File getOutputdirectory() {
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return outputDirectory;
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * The token files output directory.
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setLibdirectory(File libDirectoryFile) {
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log("Setting lib directory to: " + libDirectoryFile.toString(), Project.MSG_VERBOSE);
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.libDirectory = libDirectoryFile;
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * The output style for messages.
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setMessageformat(String name) {
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log("Setting message-format to: " + name, Project.MSG_VERBOSE);
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.messageFormatName = name;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets an optional super grammar file
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @deprecated
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setGlib(File superGrammarFile) {
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.superGrammar = superGrammarFile;
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets a flag to enable ParseView debugging
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setDebug(boolean enable) {
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.debug = enable;
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets a flag to enable report statistics
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setReport(boolean enable) {
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.report = enable;
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets a flag to print out the grammar without actions
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setPrint(boolean enable) {
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.print = enable;
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets a flag to enable profiling
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setProfile(boolean enable) {
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.profile = enable;
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets a flag to enable nfa generation
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setNfa(boolean enable) {
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.nfa = enable;
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets a flag to enable nfa generation
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setDfa(boolean enable) {
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.dfa = enable;
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Run the analysis multithreaded
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @param enable
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setMultithreaded(boolean enable) {
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        multiThreaded = enable;
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * collapse incident edges into DFA states
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @param enable
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setNocollapse(boolean enable) {
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        nocollapse = enable;
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * test lookahead against EBNF block exit branches
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @param enable
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setNoprune(boolean enable) {
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        noprune = enable;
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * test lookahead against EBNF block exit branches
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @param enable
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setDbgST(boolean enable) {
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        dbgST = enable;
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * override the default conversion timeout with -Xconversiontimeout nnnn
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @param conversiontimeoutString
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setConversiontimeout(String conversiontimeoutString) {
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log("Setting conversiontimeout to: " + conversiontimeoutString, Project.MSG_VERBOSE);
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try {
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int timeout = Integer.valueOf(conversiontimeoutString);
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            this.conversiontimeout = conversiontimeoutString;
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } catch (NumberFormatException e) {
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Option ConversionTimeOut ignored due to illegal value: '" + conversiontimeoutString + "'", Project.MSG_ERR);
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Set a flag to enable printing of the grammar tree
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setGrammartree(boolean enable) {
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammarTree = enable;
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Set a flag to enable dependency checking by ANTLR itself
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * The depend option is always used implicitely inside the antlr3 task
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @deprecated
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setDepend(boolean s) {
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.depend = s;
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Sets a flag to emit diagnostic text
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setDiagnostic(boolean enable) {
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        diagnostic = enable;
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * If true, enables all tracing.
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @deprecated
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setTrace(boolean enable) {
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        trace = enable;
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * If true, enables parser tracing.
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @deprecated
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setTraceParser(boolean enable) {
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        traceParser = enable;
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * If true, enables lexer tracing.
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @deprecated
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setTraceLexer(boolean enable) {
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        traceLexer = enable;
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // we are forced to fork ANTLR since there is a call
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // to System.exit() and there is nothing we can do
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // right now to avoid this. :-( (SBa)
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // I'm not removing this method to keep backward compatibility
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @ant.attribute ignore="true"
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setFork(boolean s) {
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.fork = s;
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * The working directory of the process
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setDir(File d) {
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this.workingdir = d;
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Adds a classpath to be set
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * because a directory might be given for Antlr debug.
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public Path createClasspath() {
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return commandline.createClasspath(getProject()).createPath();
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Adds a new JVM argument.
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @return  create a new JVM argument so that any argument can be passed to the JVM.
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * @see #setFork(boolean)
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public Commandline.Argument createJvmarg() {
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return commandline.createVmArgument();
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Adds the jars or directories containing Antlr and associates.
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * This should make the forked JVM work without having to
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * specify it directly.
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Override
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void init() throws BuildException {
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /* Inquire environment variables */
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Map<String, String> variables = System.getenv();
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /* Get value for key "ANTLR_HOME" which should hopefully point to
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * the directory where the current version of antlr3 is installed */
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String antlrHome = variables.get("ANTLR_HOME");
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (antlrHome != null) {
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            /* Environment variable ANTLR_HOME has been defined.
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             * Now add all antlr and stringtemplate libraries to the
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             * classpath */
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            addAntlrJarsToClasspath(antlrHome + "/lib");
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        addClasspathEntry("/antlr/ANTLRGrammarParseBehavior.class", "AntLR2");
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        addClasspathEntry("/org/antlr/tool/ANTLRParser.class", "AntLR3");
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        addClasspathEntry("/org/antlr/stringtemplate/StringTemplate.class", "Stringtemplate");
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * Search for the given resource and add the directory or archive
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * that contains it to the classpath.
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * <p>Doesn't work for archives in JDK 1.1 as the URL returned by
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * getResource doesn't contain the name of the archive.</p>
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    protected void addClasspathEntry(String resource, String msg) {
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /*
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * pre Ant 1.6 this method used to call getClass().getResource
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * while Ant 1.6 will call ClassLoader.getResource().
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * The difference is that Class.getResource expects a leading
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * slash for "absolute" resources and will strip it before
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * delegating to ClassLoader.getResource - so we now have to
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * emulate Class's behavior.
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (resource.startsWith("/")) {
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            resource = resource.substring(1);
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } else {
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            resource = "org/apache/tools/ant/taskdefs/optional/" + resource;
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        File f = LoaderUtils.getResourceSource(getClass().getClassLoader(), resource);
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (f != null) {
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Found via classpath: " + f.getAbsolutePath(), Project.MSG_VERBOSE);
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            createClasspath().setLocation(f);
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } else {
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Couldn\'t find resource " + resource + " for library " + msg + " in external classpath", Project.MSG_VERBOSE);
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * If the environment variable ANTLR_HOME is defined and points
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * to the installation directory of antlr3 then look for all antlr-*.jar and
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * stringtemplate-*.jar files in the lib directory and add them
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * to the classpath.
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * This feature should make working with eclipse or netbeans projects a
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * little bit easier. As wildcards are being used for the version part
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * of the jar-archives it makes the task independent of
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * new releases. Just let ANTLR_HOME point to the new installation
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * directory.
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private void addAntlrJarsToClasspath(String antlrLibDir) {
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String[] includes = {"antlr-*.jar", "stringtemplate-*.jar"};
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        DirectoryScanner ds = new DirectoryScanner();
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ds.setIncludes(includes);
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ds.setBasedir(new File(antlrLibDir));
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ds.setCaseSensitive(true);
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ds.scan();
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String separator = System.getProperty("file.separator");
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String[] files = ds.getIncludedFiles();
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for (String file : files) {
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            File f = new File(antlrLibDir + separator + file);
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Found via ANTLR_HOME: " + f.getAbsolutePath(), Project.MSG_VERBOSE);
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            createClasspath().setLocation(f);
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Override
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void execute() throws BuildException {
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        validateAttributes();
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Use ANTLR itself to resolve dependencies and decide whether
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // to invoke ANTLR for compilation
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (dependencyCheck()) {
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            populateAttributes();
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue(target.toString());
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log(commandline.describeCommand(), Project.MSG_VERBOSE);
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int err = 0;
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            try {
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                err = run(commandline.getCommandline(), new LogOutputStream(this, Project.MSG_INFO), new LogOutputStream(this, Project.MSG_WARN));
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } catch (IOException e) {
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new BuildException(e, getLocation());
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } finally {
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                try {
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    bos.close();
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                } catch (IOException e) {
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    // ignore
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (err != 0) {
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new BuildException("ANTLR returned: " + err, getLocation());
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } else {
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Pattern p = Pattern.compile("error\\([0-9]+\\):");
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Matcher m = p.matcher(bos.toString());
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (m.find()) {
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    throw new BuildException("ANTLR signaled an error.", getLocation());
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } else {
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            try {
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                log("All dependencies of grammar file \'" + target.getCanonicalPath() + "\' are up to date.", Project.MSG_VERBOSE);
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } catch (IOException ex) {
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                log("All dependencies of grammar file \'" + target.toString() + "\' are up to date.", Project.MSG_VERBOSE);
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /**
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * A refactored method for populating all the command line arguments based
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     * on the user-specified attributes.
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private void populateAttributes() {
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        commandline.createArgument().setValue("-o");
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        commandline.createArgument().setValue(outputDirectory.toString());
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        commandline.createArgument().setValue("-lib");
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        commandline.createArgument().setValue(libDirectory.toString());
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (superGrammar != null) {
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Option 'glib' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (diagnostic) {
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-diagnostic");
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (depend) {
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Option 'depend' is implicitely always used by ANTLR v3. Option can safely be omitted!", Project.MSG_WARN);
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (trace) {
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Option 'trace' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (traceParser) {
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Option 'traceParser' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (traceLexer) {
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Option 'traceLexer' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (debug) {
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-debug");
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (report) {
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-report");
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (print) {
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-print");
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (profile) {
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-profile");
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (messageFormatName != null) {
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-message-format");
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue(messageFormatName);
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (nfa) {
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-nfa");
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (dfa) {
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-dfa");
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (multiThreaded) {
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-Xmultithreaded");
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (nocollapse) {
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-Xnocollapse");
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (noprune) {
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-Xnoprune");
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (dbgST) {
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-XdbgST");
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (conversiontimeout != null) {
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-Xconversiontimeout");
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue(conversiontimeout);
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (grammarTree) {
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            commandline.createArgument().setValue("-Xgrtree");
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private void validateAttributes() throws BuildException {
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (target == null) {
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("No target grammar, lexer grammar or tree parser specified!");
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } else if (!target.isFile()) {
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("Target: " + target + " is not a file!");
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // if no output directory is specified, use the target's directory
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (outputDirectory == null) {
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            setOutputdirectory(new File(target.getParent()));
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (!outputDirectory.isDirectory()) {
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("Invalid output directory: " + outputDirectory);
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (workingdir != null && !workingdir.isDirectory()) {
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("Invalid working directory: " + workingdir);
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // if no libDirectory is specified, use the target's directory
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (libDirectory == null) {
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            setLibdirectory(new File(target.getParent()));
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (!libDirectory.isDirectory()) {
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("Invalid lib directory: " + libDirectory);
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private boolean dependencyCheck() throws BuildException {
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // using "antlr -o <OutputDirectory> -lib <LibDirectory> -depend <T>"
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // to get the list of dependencies
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        CommandlineJava cmdline;
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try {
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            cmdline = (CommandlineJava) commandline.clone();
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } catch (java.lang.CloneNotSupportedException e) {
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("Clone of commandline failed: " + e);
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cmdline.createArgument().setValue("-depend");
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cmdline.createArgument().setValue("-o");
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cmdline.createArgument().setValue(outputDirectory.toString());
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cmdline.createArgument().setValue("-lib");
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cmdline.createArgument().setValue(libDirectory.toString());
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cmdline.createArgument().setValue(target.toString());
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log(cmdline.describeCommand(), Project.MSG_VERBOSE);
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // redirect output generated by ANTLR to temporary file
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Redirector r = new Redirector(this);
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        File f;
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try {
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            f = File.createTempFile("depend", null, getOutputdirectory());
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            f.deleteOnExit();
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Write dependencies for '" + target.toString() + "' to file '" + f.getCanonicalPath() + "'", Project.MSG_VERBOSE);
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r.setOutput(f);
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r.setAlwaysLog(false);
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r.createStreams();
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } catch (IOException e) {
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("Redirection of output failed: " + e);
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // execute antlr -depend ...
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        int err = 0;
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try {
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            err = run(cmdline.getCommandline(), r.getOutputStream(), null);
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } catch (IOException e) {
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            try {
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                r.complete();
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                log("Redirection of output terminated.", Project.MSG_VERBOSE);
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } catch (IOException ex) {
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                log("Termination of output redirection failed: " + ex, Project.MSG_ERR);
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException(e, getLocation());
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } finally {
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            try {
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                bos.close();
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } catch (IOException e) {
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // ignore
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try {
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r.complete();
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Redirection of output terminated.", Project.MSG_VERBOSE);
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } catch (IOException e) {
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Termination of output redirection failed: " + e, Project.MSG_ERR);
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (err != 0) {
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (f.exists()) {
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                f.delete();
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (cmdline.getClasspath() == null) {
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                log("Antlr libraries not found in external classpath or embedded classpath statement ", Project.MSG_ERR);
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Dependency check failed. ANTLR returned: " + err, Project.MSG_ERR);
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return true;
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } else {
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Pattern p = Pattern.compile("error\\([0-9]+\\):");
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Matcher m = p.matcher(bos.toString());
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (m.find()) {
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (f.exists()) {
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    f.delete();
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // On error always recompile
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return true;
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        boolean compile = false;
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // open temporary file
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        BufferedReader in = null;
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try {
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            in = new BufferedReader(new FileReader(f));
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } catch (IOException e) {
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            try {
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (in != null) {
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    in.close();
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } catch (IOException ex) {
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new BuildException("Could not close file\'" + f.toString() + "\'.");
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (f.exists()) {
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                f.delete();
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            try {
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new BuildException("Could not open \'" + f.getCanonicalPath() + "\' for reading.");
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } catch (IOException ex) {
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new BuildException("Could not open \'" + f.toString() + "\' for reading.");
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // evaluate dependencies in temporary file
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String s;
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try {
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            while ((s = in.readLine()) != null) {
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                String a;
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                String b;
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // As the separator string in lines emitted by the depend option
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // is either " : " or ": " trim is invoked for the first file name of a line
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                int to = s.indexOf(": ");
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (to >= 0) {
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    a = s.substring(0, to).trim();
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    File lhs = new File(a);
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if (!lhs.isFile()) {
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        log("File '" + a + "' is not a regular file", Project.MSG_VERBOSE);
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        String name = lhs.getName();
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        String[] parts = splitRightHandSide(name, "\\u002E");
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        if (parts.length <= 1) {
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            a += ".java";
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            lhs = new File(a);
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            if (lhs.isFile()) {
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                log("File '" + a + "' is a regular file last modified at " + lhs.lastModified(), Project.MSG_VERBOSE);
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            }
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        }
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    b = s.substring(to + ": ".length());
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    String[] names = splitRightHandSide(b, ", ?");
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    File aFile = new File(a);
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    for (String name : names) {
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        File bFile = new File(name);
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        log("File '" + a + "' depends on file '" + name + "'", Project.MSG_VERBOSE);
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        log("File '" + a + "' modified at " + aFile.lastModified(), Project.MSG_VERBOSE);
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        log("File '" + name + "' modified at " + bFile.lastModified(), Project.MSG_VERBOSE);
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        if (fileUtils.isUpToDate(aFile, bFile)) {
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            log("Compiling " + target + " as '" + name + "' is newer than '" + a + "'", Project.MSG_VERBOSE);
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            // Feeling not quite comfortable with touching the file
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            fileUtils.setFileLastModified(aFile, -1);
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            log("Touching file '" + a + "'", Project.MSG_VERBOSE);
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            compile = true;
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            break;
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        }
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if (compile) {
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        break;
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            in.close();
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } catch (IOException e) {
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (f.exists()) {
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                f.delete();
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            throw new BuildException("Error reading file '" + f.toString() + "'");
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (f.exists()) {
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            f.delete();
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return compile;
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private String[] splitRightHandSide(String fileNames, String pattern) {
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String[] names = fileNames.split(pattern);
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for (String name : names) {
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log("Split right hand side '" + name + "'", Project.MSG_VERBOSE);
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return names;
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** execute in a forked VM */
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    private int run(String[] command, OutputStream out, OutputStream err) throws IOException {
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        PumpStreamHandler psh;
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (err == null) {
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            psh = new PumpStreamHandler(out, bos);
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        } else {
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            psh = new PumpStreamHandler(out, new TeeOutputStream(err, bos));
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Execute exe = new Execute(psh, null);
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        exe.setAntRun(getProject());
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (workingdir != null) {
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            exe.setWorkingDirectory(workingdir);
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        exe.setCommandline(command);
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return exe.execute();
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
777