/** * File: ToAssertions.java * Content: Separate program to convert the Debug.assert lines into JDK1.4 assertions * Author: LuisM Pena * Date: 6th February 2001 * Version: 0.60.00 * Last change: * Comments: * Lines with preprocess directives are translated into ;//@Prep-> * Are considered preprocess directives those starting with Debug. or Trace. * It also removes import sensei.util.Debug * This method is obviously not generic, but works perfectly in sensei * * **/ package preprocessors; import sensei.util.Parameters; import sensei.util.ParameterException; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Iterator; import java.util.Vector; /** * Separate program to add/remove debug directives **/ public class ToAssertions implements FileFilter { public ToAssertions(boolean recursive, boolean quiet) { this.recursive = recursive; this.quiet=quiet; processed = new HashMap(); } //*************************************************************************************// //**************************** PREPROCESS *********************************************// //*************************************************************************************// /** * Handles the arguments as a file or directory and add/removes the debug directives * Returns true if the processing is all right **/ public boolean preprocess(File arg) { boolean ret; if (arg.isDirectory()) ret=preprocessDirectory(arg); else if (arg.isFile()) ret=preprocessFile(arg); else ret=error(arg, "is not a valid directory or file"); return ret; } //*************************************************************************************// //**************************** PREPROCESS DIRECTORY ***********************************// //*************************************************************************************// /** * Handles the arguments as a directory and add/removes the debug directives on every * java file. * Returns true if the processing is all right **/ public boolean preprocessDirectory(File directory) { boolean ret=true; File files[]=directory.listFiles(this); for (int i=0; ret && i<files.length ; i++) ret=preprocess(files[i]); return ret; } //*************************************************************************************// //**************************** PREPROCESS FILE ****************************************// //*************************************************************************************// /** * Handles the arguments as a file and add/removes the debug directives * Returns true if the processing is all right **/ public boolean preprocessFile(File arg) { boolean ret=true; if (accept(arg)) { //rename it File renamed=new File(arg.getAbsoluteFile()+SecExtension); if (!arg.renameTo(renamed)) ret=error(arg,"can not be renamed into " + renamed.toString()); else { processed.put(renamed, arg); ret=preprocessFile(renamed, arg); } } return ret; } //*************************************************************************************// //**************************** PREPROCESS FILE ****************************************// //*************************************************************************************// /** * Preprocess the file specified into the target given **/ public boolean preprocessFile(File source, File target) { BufferedReader input = null; PrintWriter output = null; boolean ret=true; try { if (!quiet) System.out.print(target.getAbsoluteFile()); input = new BufferedReader(new FileReader(source)); output= new PrintWriter(new FileOutputStream(target)); int changes=0; String line = input.readLine(); while(line!=null) { if (isImportDebugDirective(line)) { changes++; } else { int index=isAssertDirective(line); if (index==-1) output.println(line); else { ++changes; output.println(translateAssertDirective(line, index)); } } line=input.readLine(); } if (!quiet) if (changes>0) System.out.println(" : " + changes + " lines changed"); else System.out.println(); } catch(IOException ex) { ret=error(target,ex.getMessage()); } finally { if (input!=null) try{input.close();}catch(IOException ex){} if (output!=null) output.close(); } return ret; } //*************************************************************************************// //**************************** IS ASSERT DIRECTIVE ************************************// //*************************************************************************************// /** * Returns different of -1 if it's an assert directive. Otherwise, returns the * position where it starts **/ public int isAssertDirective(String line) { int index=-1; String trimed = line.trim(); if (trimed.startsWith("Debug.assert")) index=line.indexOf("D"); return index; } //*************************************************************************************// //**************************** IS IMPORT DEBUG DIRECTIVE ******************************// //*************************************************************************************// /** * Returns true if the line is an import sensei.util.Debug directive **/ public boolean isImportDebugDirective(String line) { return (line.trim().startsWith("import") && (line.indexOf("sensei.util.Debug")!=-1)); } //*************************************************************************************// //**************************** TRANSLATE ASSERT DIRECTIVE *****************************// //*************************************************************************************// /** * Translates a Debug.assert directive into a JDK 1.4 assertion from a line. * It must be completely included on the same line! **/ public String translateAssertDirective(String line, int where) { int openPar = line.indexOf("(",where); if (openPar==-1) errorOnLine(line); String firstParam =getFirstParam(line, openPar+1); if (firstParam==null) errorOnLine(line); return line.substring(0,where)+"assert " + firstParam + ";"; } private void errorOnLine(String line) { System.out.println(line + " is not a valid DEBUG assertion"); System.exit(0); } private String getFirstParam(String read, int start){ int pos=start, len=read.length(); int openPar=0; while(pos<len) { char c=read.charAt(pos); if (c=='\\') { return null; //error! } else if (c=='\'') { pos=passCharacter(read, pos, '\'', len); if (pos==-1) { return null; } } else if (c=='\"') { pos=passCharacter(read, pos, '\"', len); if (pos==-1) { return null; } } else if (c=='(') { openPar++; } else if (c==')') { if (--openPar<0) return null; } else if (c==',' && openPar==0) { return read.substring(start,pos); } else if ((c=='/') && ((pos+1)<len)){ c=read.charAt(pos+1); if (c=='/') { return null; //comment?? } else if (c=='*') { if ((pos=passComment(read, pos+2, len))==-1) { return null; } } } ++pos; } return null; } private int passCharacter(String read, int pos, char pass, int len){ while(++pos<len) { char c=read.charAt(pos); if (c=='\\') { ++pos; //do not read next character } else if (c==pass) { return pos; } } return -1; } private int passComment(String read, int pos, int len){ while(pos<len) { char c=read.charAt(pos++); if (c=='*' && pos<len && read.charAt(pos)=='/') { return pos; } } return -1; } //*************************************************************************************// //**************************** ACCEPT *************************************************// //*************************************************************************************// /** * FileFilter method: only accept java files **/ public boolean accept(File file) { return (recursive && file.isDirectory()) || (file.isFile() && file.getName().toLowerCase().endsWith(".java")); } //*************************************************************************************// //**************************** ERROR **************************************************// //*************************************************************************************// /** * Displays an error on the error stream. returns false **/ boolean error(File file, String errorMessage) { System.out.println("\nError on " + file.toString() + " : " + errorMessage); recoverBackups(); return false; } //*************************************************************************************// //**************************** RECOVER BACKUPS ****************************************// //*************************************************************************************// /** * Recover the backups **/ void recoverBackups() { Iterator entries=processed.entrySet().iterator(); while(entries.hasNext()) { Map.Entry entry = (Map.Entry) (entries.next()); File backup=(File)(entry.getKey()); File original=(File)(entry.getValue()); original.delete(); if (!backup.renameTo(original)) System.out.println("I cannot rename back " + backup.toString() + " into " + original.toString()); } processed.clear(); } //*************************************************************************************// //**************************** REMOVE BACKUPS *****************************************// //*************************************************************************************// /** * Removes the backups **/ public void removeBackups() { Iterator entries=processed.keySet().iterator(); while(entries.hasNext()) { File backup = (File) (entries.next()); if (!backup.delete()) System.out.println("I cannot delete the backup " + backup.toString()); } } //*************************************************************************************// //**************************** MAIN ***************************************************// //*************************************************************************************// /** * Main function, just checks the arguments and passes it to the ToAssertions class **/ public static void main(String args[]) { try { Vector validParams=new Vector(); validParams.add(RecursiveParameter); validParams.add(NoBackupParameter); validParams.add(QuietParameter); Parameters param=new Parameters(args, validParams, new Vector(), 1, Integer.MAX_VALUE); ToAssertions prep = new ToAssertions( param.hasParameter(RecursiveParameter), param.hasParameter(QuietParameter) ); boolean ok=true; for (int i=0; ok && i < param.getArgumentsLength() ; i++) ok = prep.preprocess(new File(param.getArgument(i))); if (ok && param.hasParameter(NoBackupParameter)) prep.removeBackups(); } catch(ParameterException ex) { System.out.println(ex.getMessage()); System.out.println("Use: [-recursive] [-nobackup] [-quiet] file/directory [files/directories]"); } } boolean recursive, nobackup, quiet; HashMap processed; static final String RecursiveParameter="recursive"; static final String NoBackupParameter="nobackup"; static final String QuietParameter="quiet"; static final String SecExtension=".noprep"; }