Return-Path: Mailing-List: contact ant-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list ant-dev@jakarta.apache.org Received: (qmail 47158 invoked from network); 26 Jun 2000 12:19:41 -0000 Received: from i-gate.softwired.ch (212.40.20.70) by locus.apache.org with SMTP; 26 Jun 2000 12:19:41 -0000 Received: from artus.ii.softwired.ch (camelot.softwired.ch [212.40.20.71]) by i-gate.softwired.ch (8.9.1/8.9.1) with ESMTP id OAA28307 for ; Mon, 26 Jun 2000 14:19:41 +0200 Received: from softwired-inc.com (owain.ii.softwired.ch [192.168.168.232]) by artus.ii.softwired.ch (8.9.3/8.9.3) with ESMTP id OAA07336 for ; Mon, 26 Jun 2000 14:19:39 +0200 Message-ID: <39574A9A.4010302@softwired-inc.com> Date: Mon, 26 Jun 2000 14:20:42 +0200 From: Thomas Haas User-Agent: Mozilla/5.0 (X11; U; Linux 2.2.14 i686; en-US; m16) Gecko/20000613 X-Accept-Language: en MIME-Version: 1.0 To: ant-dev@jakarta.apache.org Subject: Re: JavaCC tasks for ANT References: <39565F9C.545393C8@multiactive.com> Content-Type: multipart/mixed; boundary="------------080106060208060307000004" X-Spam-Rating: locus.apache.org 1.6.2 0/1000/N This is a multi-part message in MIME format. --------------080106060208060307000004 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Attached please find our implemenmtation of a JavaCC task. Our build file looks like the following: ... The variables tool.metamata.home, tool.metamata.workdir and lib.metamata are set like the following: tool.metamata.home: directory where metamata is installed with the following contents: freebies.key metamata.license lib/JavaCC.zip lib/freebies.jar lib/metamata.jar lib/metamatadebug.jar tool.metamata.workdir: some directory created and erased used by javacc to put temp. files in. lib.metamata: points to the jar ${tool.metamata.home}/lib/metamata.jar Features: javacc cleans up some files left behind javacc lik OO393.class and other stuff. javacc only rebuilds the .java files if the .jj files are newer Todo: Use file matching or multiple file arguments This is in production for 3 months now at our site. Feedback welcomed. - tom marius@multiactive.com (Marius Scurtescu) wrote: > > Hi all, > > I am writing you because while checking the ANT mailing > list archives I saw that you were interested in JavaCC > related tasks for ANT. > > Since running JJTree and JavaCC are time consuming my > main problem is running them only if the source grammar > file was touched. While you can get this quite easily > with a classic make utility, there is no support for > this in ANT. Do you have a solution for this? > > The way I run JavaCC is by using a "java" task to > run the main applications directly: > > > > > > > > > > > > > This will work assuming that JavaCC.zip is in your class path. > > To solve the time stamp based conditional task run I was > thinking to create a generic task that will add a property > based on time stamp comparison between two sets of files, the > inputs and outputs to some other task. This other task/targets > could then be run only if this property is set. > > Please let me know if all this makes sense in your opinion. > > Cheers, > Marius --------------080106060208060307000004 Content-Type: text/plain; name="JavaCC.java" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="JavaCC.java" /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.tools.ant.taskdefs.optional; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Path; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import java.io.File; import java.io.IOException; public class JavaCC extends Task { private Path userclasspath = new Path(); private File metahome = null; private File metaworkingdir = null; private File target = null; private boolean cleanupHack = false; private CommandlineJava cmdl = new CommandlineJava(); public void setMetamatahome(String metamatahome) { this.metahome = new File(metamatahome); } public void setWorkingdir(String workingdir) { this.metaworkingdir = new File(workingdir); } public void setTarget(String testcase) { target = new File(Path.translateFile(testcase)); } public Path createUserclasspath() { return userclasspath; } public void setCleanupHack(String value) { cleanupHack = project.toBoolean(value); } public JavaCC() { cmdl.setVm("java"); cmdl.setClassname("com.metamata.jj.MParse"); } public void execute() throws BuildException { if (target == null || !target.isFile()) { throw new BuildException("Invalid target: " + target); } final File javaFile = new File(target.toString().substring(0, target.toString().indexOf(".jj")) + ".java"); if (javaFile.exists() && target.lastModified() < javaFile.lastModified()) { project.log("Target is already build - skipping (" + target + ")"); return; } cmdl.createArgument().setValue(target.getAbsolutePath()); if (metahome == null || !metahome.isDirectory()) { throw new BuildException("Metamatahome not valid."); } if (metaworkingdir == null || !metaworkingdir.isDirectory()) { throw new BuildException("Workingdir not set."); } if (userclasspath == null) { throw new BuildException("Userclasspath not set."); } final Path classpath = cmdl.createClasspath(); classpath.createElement().setLocation(metahome.getAbsolutePath() + "/lib/metamatadebug.jar"); classpath.createElement().setLocation(metahome.getAbsolutePath() + "/lib/metamata.jar"); classpath.createElement().setLocation(metahome.getAbsolutePath() + "/lib/JavaCC.zip"); final Commandline.Argument arg = cmdl.createVmArgument(); arg.setValue("-mx140M"); arg.setValue("-Dmwp=" + metaworkingdir.getAbsolutePath()); arg.setValue("-Dmetamata.home=" + metahome.getAbsolutePath()); arg.setValue("-Dmetamata.java=java"); arg.setValue("-Dmetamata.java.options=-mx140M"); arg.setValue("-Dmetamata.java.options.classpath=-classpath"); arg.setValue("-Dmetamata.java.compiler=javac"); arg.setValue("-Dmetamata.java.compiler.options.0=-J-mx64M"); arg.setValue("-Dmetamata.java.compiler.options.classpath=-classpath"); arg.setValue("-Dmetamata.language=en"); arg.setValue("-Dmetamata.country=US"); arg.setValue("-Dmetamata.classpath=" + userclasspath); final Execute process = new Execute(new LogStreamHandler(project, " JavaCC", Project.MSG_INFO, "X JavaCC", Project.MSG_INFO), null); project.log(cmdl.toString(), Project.MSG_VERBOSE); process.setCommandline(cmdl.getCommandline()); try { try { if (process.execute() != 0) { throw new BuildException("JavaCC failed."); } } finally { if (cleanupHack) { final File oo393 = new File(javaFile.getParentFile(), "OO393.class"); if (oo393.exists()) { project.log("Removing stale file: " + oo393.getName()); oo393.delete(); } final File sunjj = new File(javaFile.getParentFile(), "__jj" + javaFile.getName().substring(0, javaFile.getName().indexOf(".java")) + ".sunjj"); if (sunjj.exists()) { project.log("Removing stale file: " + sunjj.getName()); sunjj.delete(); } } } } catch (IOException e) { throw new BuildException("Failed to launch JavaCC: " + e); } } } --------------080106060208060307000004 Content-Type: text/plain; name="Path.java" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Path.java" /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.tools.ant; import java.io.File; import java.util.Vector; import java.util.StringTokenizer; import java.text.CharacterIterator; import java.text.StringCharacterIterator; /** * This object represents a path as used by CLASSPATH or PATH * environment variable. * * * <sometask>
*   <somepath> *     <element location="/path/to/file.jar" /> *     <element path="/path/to/file2.jar:/path/to/class2;/path/to/class3" /> *     <element location="/path/to/file3.jar" /> *     <element location="/path/to/file4.jar" /> *   </somepath> * </sometask>
*
* * The object implemention sometask must provide a method called * createSomepath which returns an instance of Path. * Nested path definitions are handled by the Path object and must be labeled * path.

* * The path element takes a parameter path which will be parsed * and split into single elements. It will usually be used * to define a path from an environment variable. * * @author Thomas.Haas@softwired-inc.com */ public class Path { final static boolean DETECT_DOS = (File.pathSeparatorChar == ';'); private Vector definition = new Vector(); /** * Adds a element definition to the path. * @param location the location of the element to add (must not be * null nor empty. **/ public void setLocation(String location) { if (location != null && location.length() > 0) { definition.addElement(translateFile(location)); } } /** * Parses a path definition and creates single PatheElements. * @param path the path definition. */ public void setPath(String path) { final Vector elements = translatePath(path); for (int i=0; i < elements.size(); i++) { definition.addElement(elements.elementAt(i)); } } public Path createElement() { return this; } /** * Returns all path elements defined by this and netsed path objects. * @return list of path elements. */ public String[] list() { final String[] result = new String[definition.size()]; definition.copyInto(result); return result; } /** * Returns a textual representation of the path, which can be used as * CLASSPATH or PATH environment variable definition. * @return a textual representation of the path. */ public String toString() { final String[] list = list(); // empty path return empty string if (list.length == 0) return ""; // path containing one or more elements final StringBuffer result = new StringBuffer(list[0].toString()); for (int i=1; i < list.length; i++) { result.append(File.pathSeparatorChar); result.append(list[i]); } return result.toString(); } public static Vector translatePath(String source) { final Vector result = new Vector(); if (source == null) return result; final StringBuffer path = new StringBuffer(source); int start = 0; for (int i=0; i < path.length(); i++) { if (!translateFileSep(path, i)) { if (endOfElement(path, start, i)) { // EMPTY ELEMENT DETECTION if (start < i) { result.addElement(path.substring(start, i)); } start = i+1; } } } if (start < (path.length())) { result.addElement(path.substring(start)); } return result; } public static String translateFile(String source) { if (source == null) return ""; final StringBuffer result = new StringBuffer(source); for (int i=0; i < result.length(); i++) { translateFileSep(result, i); } return result.toString(); } protected static boolean translateFileSep(StringBuffer buffer, int pos) { if (buffer.charAt(pos) == '/' || buffer.charAt(pos) == '\\') { buffer.setCharAt(pos, File.separatorChar); return true; } return false; } protected static boolean endOfElement(StringBuffer buffer, int start, int pos) { final char c = buffer.charAt(pos); // DOS PATH DETECTION: SECOND CHARACTER IN ELEMENT IS : if (DETECT_DOS && c == ':' && (pos - start) == 1) { return false; } // PATH SEPERATOR DETECTION ON ':' AND ';' AND CURRENT PLATFORM return c == ':' || c == ';' || c == File.pathSeparatorChar; } } --------------080106060208060307000004--