bodewig 2003/08/14 07:52:42 Modified: docs/manual/OptionalTasks jjtree.html src/main/org/apache/tools/ant/taskdefs/optional/javacc JJTree.java Log: Make <jjtree>'s outputdirectory and outputfile attributes work as expected (i.e. consistent with the command line of jjtree). PR: 21526 Submitted by: Jene Jasper <jjasper at abz dot nl> Revision Changes Path 1.8 +346 -0 ant/docs/manual/OptionalTasks/jjtree.html Index: jjtree.html =================================================================== RCS file: /home/cvs/ant/docs/manual/OptionalTasks/jjtree.html,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- jjtree.html 23 Jul 2003 14:12:11 -0000 1.7 +++ jjtree.html 14 Aug 2003 14:52:42 -0000 1.8 @@ -187,9 +187,355 @@ grammar file, Parser.jj, file to build/src. The grammar option NODE_USES_PARSER is set to true when invoking JJTree. <br> + +<h3>Comparison output locations between command line JJTree and different Ant taskdef versions</h3> + +<table cellpadding="3" border="1"> +<tr> + <td><b>Command Line JJTree options</b> + <br> <i>and Generated Files</i> (working directory: <code>/tmp</code>)</td> + <td><b>Ant 1.5.3</b> versus command line</td> + <td><b>Ant 1.6</b> versus command line</td> +</tr> +<tr> + <td><pre><b>jjtree grammar.jjt</b> + /tmp/grammar.jj + /tmp/<generated>.java</pre> + </td> + <td>Same</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree relative/grammar.jjt</b> + /tmp/grammar.jj + /tmp/<generated>.java</pre> + </td> + <td><pre> +/tmp/relative/grammar.jj +/tmp/relative/<generated>.java</pre> + </td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree /tmp/absolute/grammar.jjt</b> + /tmp/grammar.jj + /tmp/<generated>.java</pre> + </td> + <td><pre> +/tmp/absolute/grammar.jj +/tmp/absolute/<generated>.java</pre> + </td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_DIRECTORY:relative grammar.jjt</b> + /tmp/relative/grammar.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Same</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b> + /tmp/relative/grammar.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Same</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b> + /tmp/relative/grammar.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Same</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b> + /tmp/absolute/grammar.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Same</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b> + /tmp/absolute/grammar.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Same</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b> + /tmp/absolute/grammar.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Same</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj grammar.jjt</b> + /tmp/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj relative/grammar.jjt</b> + /tmp/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj /tmp/absolute/grammar.jjt</b> + /tmp/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:relative grammar.jjt</b> + /tmp/relative/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b> + /tmp/relative/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b> + /tmp/relative/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b> + /tmp/absolute/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b> + /tmp/absolute/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b> + /tmp/absolute/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj relative/grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj /tmp/absolute/grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:relative grammar.jjt</b> + /tmp/relative/subdir/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b> + /tmp/relative/subdir/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b> + /tmp/relative/subdir/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b> + /tmp/absolute/subdir/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b> + /tmp/absolute/subdir/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b> + /tmp/absolute/subdir/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj relative/grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj /tmp/absolute/grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:<i><u>D:</u></i>/tmp/subdir/output.jj grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Not Supported *)</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:<i><u>D:</u></i>/tmp/subdir/output.jj relative/grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Not Supported *)</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:<i><u>D:</u></i>/tmp/subdir/output.jj /tmp/absolute/grammar.jjt</b> + /tmp/subdir/output.jj + /tmp/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Not Supported *)</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:relative grammar.jjt</b> + /tmp/relative/tmp/subdir/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b> + /tmp/relative/tmp/subdir/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b> + /tmp/relative/tmp/subdir/output.jj + /tmp/relative/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b> + /tmp/absolute/tmp/subdir/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b> + /tmp/absolute/tmp/subdir/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +<tr> + <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b> + /tmp/absolute/tmp/subdir/output.jj + /tmp/absolute/<generated>.java</pre> + </td> + <td>Not Supported</td> + <td>Same</td> +</tr> +</table> + +<p>*) <u>Footnote</u>: When running JJTree with the Ant taskdesk <i>jjtree</i> the option <code>-OUTPUT_DIRECTORY</code> must always +be set, because the project's basedir and the ant working directory might differ. So even if you don't specify the jjtree taskdef +<i>outputdirectory</i> JJTree will be called with the <code>-OUTPUT_DIRECTORY</code> set to the project's basedirectory. +But when the <code>-OUTPUT_DIRECTORY</code> is set, the <code>-OUTPUT_FILE</code> setting is handled as if relative to this +<code>-OUTPUT_DIRECTORY</code>. Thus when the <code>-OUTPUT_FILE</code> is absolute or contains a drive letter we have a +problem. +Therefore absolute <i>outputfile</i>s (when the <i>outputdirectory</i> isn't specified) are made relative to the default directory. +And for this reason <i>outputfile</i>s that contain a drive letter can't be supported.</p> + +<p>By the way: specifying a drive letter in the <code>-OUTPUT_FILE</code> when the <code>-OUTPUT_DIRECTORY</code> is set, also +results in strange behavior when running JJTree from the command line.</p> + +<br> <hr> <p align="center">Copyright © 2001-2003 Apache Software Foundation. All rights Reserved.</p> + + + </body> </html> 1.26 +93 -10 ant/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java Index: JJTree.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- JJTree.java 1 Aug 2003 10:08:12 -0000 1.25 +++ JJTree.java 14 Aug 2003 14:52:42 -0000 1.26 @@ -233,15 +233,15 @@ throw new BuildException("Invalid target: " + target); } - if (outputFile != null) { - cmdl.createArgument().setValue("-" + OUTPUT_FILE + ":" - + outputFile.replace('\\', '/')); - } - File javaFile = null; // use the directory containing the target as the output directory if (outputDirectory == null) { + // convert backslashes to slashes, otherwise jjtree will + // put this as comments and this seems to confuse javacc + cmdl.createArgument().setValue("-OUTPUT_DIRECTORY:" + + getDefaultOutputDirectory()); + javaFile = new File(createOutputFileName(target, outputFile, null)); } else { @@ -267,6 +267,12 @@ Project.MSG_VERBOSE); return; } + + if (outputFile != null) { + cmdl.createArgument().setValue("-" + OUTPUT_FILE + ":" + + outputFile.replace('\\', '/')); + } + cmdl.createArgument().setValue(target.getAbsolutePath()); cmdl.setClassname(JavaCC.getMainClass(javaccHome, @@ -300,6 +306,8 @@ private String createOutputFileName(File target, String optionalOutputFile, String outputDirectory) { + optionalOutputFile = validateOutputFile(optionalOutputFile, + outputDirectory); String jjtreeFile = target.getAbsolutePath().replace('\\','/'); if ((optionalOutputFile == null) || optionalOutputFile.equals("")) { @@ -326,11 +334,7 @@ } if ((outputDirectory == null) || outputDirectory.equals("")) { - if (isAbsolute(optionalOutputFile)) { - return optionalOutputFile.replace('\\','/'); - } else { - outputDirectory = getProject().getBaseDir().getAbsolutePath(); - } + outputDirectory = getDefaultOutputDirectory(); } return (outputDirectory + "/" + optionalOutputFile).replace('\\', '/'); @@ -338,5 +342,84 @@ private boolean isAbsolute(String fileName) { return (fileName.startsWith("/") || (new File(fileName).isAbsolute())); + } + + /** + * When running JJTree from an Ant taskdesk the -OUTPUT_DIRECTORY must + * always be set. But when -OUTPUT_DIRECTORY is set, -OUTPUT_FILE is + * handled as if relative of this -OUTPUT_DIRECTORY. Thus when the + * -OUTPUT_FILE is absolute or contains a drive letter we have a problem. + * + * @param outputFile + * @param outputDirectory + * @return + * @throws BuildException + */ + private String validateOutputFile(String outputFile, + String outputDirectory) + throws BuildException { + if (outputFile == null) { + return null; + } + + if ((outputDirectory == null) + && (outputFile.startsWith("/") || outputFile.startsWith("\\"))) { + String relativeOutputFile = makeOutputFileRelative(outputFile); + setOutputfile(relativeOutputFile); + + return relativeOutputFile; + } + + String root = getRoot(new File(outputFile)).getAbsolutePath(); + + if ((root.length() > 1) + && outputFile.startsWith(root.substring(0, root.length() - 1))) { + throw new BuildException("Drive letter in 'outputfile' not " + + "supported: " + outputFile); + } + + return outputFile; + } + + private String makeOutputFileRelative(String outputFile) { + StringBuffer relativePath = new StringBuffer(); + String defaultOutputDirectory = getDefaultOutputDirectory(); + int nextPos = defaultOutputDirectory.indexOf('/'); + int startPos = nextPos + 1; + + while (startPos > -1 && startPos < defaultOutputDirectory.length()) { + relativePath.append("/.."); + nextPos = defaultOutputDirectory.indexOf('/', startPos); + + if (nextPos == -1) { + startPos = nextPos; + } else { + startPos = nextPos + 1; + } + } + + relativePath.append(outputFile); + + return relativePath.toString(); + } + + private String getDefaultOutputDirectory() { + return getProject().getBaseDir().getAbsolutePath().replace('\\', '/'); + } + + /** + * Determine root directory for a given file. + * + * @param file + * @return file's root directory + */ + private File getRoot(File file) { + File root = file.getAbsoluteFile(); + + while (root.getParent() != null) { + root = root.getParentFile(); + } + + return root; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]