/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * JFlex Anttask * * Copyright (C) 2001 Rafal Mantiuk <Rafal.Mantiuk@bellstream.pl> * * Copyright (C) 2003 changes by Gerwin Klein <lsf@jflex.de> * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License. See the file * * COPYRIGHT for more information. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package JFlex.anttask; import org.apache.tools.ant.Task; import org.apache.tools.ant.BuildException; import JFlex.Main; import JFlex.Options; import java.io.*; /** * JFlex task class * * @author Rafal Mantiuk * @version JFlex 1.4.3, $Revision: 433 $, $Date: 2009-01-31 19:52:34 +1100 (Sat, 31 Jan 2009) $ */ public class JFlexTask extends Task { private File inputFile; // found out by looking into .flex file private String className = null; private String packageName = null; /** for javac-like dest dir behaviour */ private File destinationDir; /** the actual output directory (outputDir = destinationDir + package)) */ private File outputDir = null; public JFlexTask() { // ant default is different from the rest of JFlex setVerbose(false); Options.progress = false; } public void execute() throws BuildException { try { if (inputFile == null) throw new BuildException("Input file needed. Use <jflex file=\"your_scanner.flex\"/>"); if (!inputFile.canRead()) throw new BuildException("Cannot read input file "+inputFile); try { findPackageAndClass(); normalizeOutdir(); File destFile = new File(outputDir, className + ".java"); if (inputFile.lastModified() > destFile.lastModified()) { Main.generate(inputFile); if (!Options.verbose) System.out.println("Generated: " + destFile.getName()); } } catch (IOException e1) { throw new BuildException("IOException: " + e1.toString()); } } catch (JFlex.GeneratorException e) { throw new BuildException("JFlex: generation failed!"); } } /** * Peek into .flex file to get package and class name * * @throws IOException if there is a problem reading the .flex file */ public void findPackageAndClass() throws IOException { // find name of the package and class in jflex source file packageName = null; className = null; LineNumberReader reader = new LineNumberReader(new FileReader(inputFile)); while (className == null || packageName == null) { String line = reader.readLine(); if (line == null) break; if (packageName == null) { int index = line.indexOf("package"); if (index >= 0) { index += 7; int end = line.indexOf(';', index); if (end >= index) { packageName = line.substring(index, end); packageName = packageName.trim(); } } } if (className == null) { int index = line.indexOf("%class"); if (index >= 0) { index += 6; className = line.substring(index); className = className.trim(); } } } // package name may be null, but class name not if (className == null) className = "Yylex"; } /** * Sets the actual output directory if not already set. * * Uses javac logic to determine output dir = dest dir + package name * If not destdir has been set, output dir = parent of input file * * Assumes that package name is already set. */ public void normalizeOutdir() { if (outputDir != null) return; // find out what the destination directory is. Append packageName to dest dir. File destDir; // this is not the default the jflex logic, but javac-like if (destinationDir != null) { if (packageName == null) { destDir = destinationDir; } else { String path = packageName.replace('.', File.separatorChar); destDir = new File(destinationDir,path); } } else { //save parser to the same dir as .flex destDir = new File(inputFile.getParent()); } setOutdir(destDir); } /** * @return package name of input file * * @see JFlexTask.findPackageAndClass */ public String getPackage() { return packageName; } /** * @return class name of input file * * @see JFlexTask.findPackageAndClass */ public String getClassName() { return className; } public void setDestdir(File destinationDir) { this.destinationDir = destinationDir; } public void setOutdir(File outDir) { this.outputDir = outDir; Options.setDir(outputDir); } public void setFile(File file) { this.inputFile = file; } public void setGenerateDot(boolean genDot) { setDot(genDot); } public void setTimeStatistics(boolean displayTime) { Options.time = displayTime; } public void setTime(boolean displayTime) { setTimeStatistics(displayTime); } public void setVerbose(boolean verbose) { Options.verbose = verbose; } public void setSkeleton(File skeleton) { Options.setSkeleton(skeleton); } public void setSkel(File skeleton) { setSkeleton(skeleton); } public void setSkipMinimization(boolean skipMin) { setNomin(skipMin); } public void setNomin(boolean b) { Options.no_minimize = b; } public void setNobak(boolean b) { Options.no_backup = b; } public void setSwitch(boolean b) { if (b) { Options.gen_method = Options.SWITCH; } else { Options.gen_method = Options.PACK; } } public void setTable(boolean b) { if (b) { Options.gen_method = Options.TABLE; } else { Options.gen_method = Options.PACK; } } public void setPack(boolean b) { if (b) { Options.gen_method = Options.PACK; } else { Options.gen_method = Options.SWITCH; } } public void setDot(boolean b) { Options.dot = b; } public void setDump(boolean b) { Options.dump = b; } public void setJLex(boolean b) { Options.jlex = b; } }