/** * */ package bixie; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import bixie.checker.ProgramAnalysis; import bixie.checker.reportprinter.BasicReportPrinter; import bixie.checker.reportprinter.ReportPrinter; import bixie.util.Log; import boogie.ProgramFactory; /** * @author schaef * */ public class Bixie { /** * */ public Bixie() { // TODO Auto-generated constructor stub } /** * @param args */ public static void main(String[] args) { bixie.Options options = bixie.Options.v(); CmdLineParser parser = new CmdLineParser(options); if (args.length == 0) { parser.printUsage(System.err); return; } try { parser.parseArgument(args); Bixie bixie = new Bixie(); if (options.getBoogieFile() != null && options.getJarFile() != null) { Log.error("Can only take either Java or Boogie input. Not both"); return; } else if (options.getBoogieFile() != null) { bixie.run(options.getBoogieFile(), options.getOutputFile()); } else { String cp = options.getClasspath(); if (cp != null && !cp.contains(options.getJarFile())) { cp += File.pathSeparatorChar + options.getJarFile(); } bixie.translateAndRun(options.getJarFile(), cp, options.getOutputFile()); } } catch (CmdLineException e) { bixie.util.Log.error(e.toString()); parser.printUsage(System.err); } catch (Throwable e) { bixie.util.Log.error(e.toString()); } } public void run(String input, String output) { bixie.Options.v().setOutputFile(output); if (input != null && input.endsWith(".bpl")) { try { ProgramFactory pf = new ProgramFactory(input); ReportPrinter jp = runChecker(pf); report2File(jp); } catch (Exception e) { // TODO Auto-generated catch block bixie.util.Log.error(e.toString()); } } else { bixie.util.Log.error("Not a valid Boogie file: " + input); } } protected void report2File(ReportPrinter reportPrinter) { try (PrintWriter out = new PrintWriter(new OutputStreamWriter( new FileOutputStream(bixie.Options.v().getOutputFile()), "UTF-8"));) { String str = reportPrinter.printSummary(); if (str!=null && !str.isEmpty()) { out.println(str); bixie.util.Log.info(str); } } catch (Exception e) { // TODO Auto-generated catch block bixie.util.Log.error(e.toString()); } } public void translateAndRun(String input, String classpath, String output) { ReportPrinter reportPrinter = translateAndRun(input, classpath); if (reportPrinter!=null) { bixie.Options.v().setOutputFile(output); report2File(reportPrinter); } else { Log.error("Could not generate report."); } } public ReportPrinter translateAndRun(String input, String classpath) { return translateAndRun(input, classpath, new BasicReportPrinter()); } public ReportPrinter translateAndRun(String input, String classpath, ReportPrinter reportPrinter) { bixie.util.Log.info("Translating"); org.joogie.Dispatcher.setClassPath(classpath); ProgramFactory pf = org.joogie.Dispatcher.run(input); if (pf == null) { bixie.util.Log.error("Internal Error: Parsing failed"); return null; } ReportPrinter jp = runChecker(pf, reportPrinter); return jp; } public ReportPrinter runChecker(ProgramFactory pf) { return runChecker(pf, new BasicReportPrinter()); } public ReportPrinter runChecker(ProgramFactory pf, ReportPrinter reportPrinter) { bixie.util.Log.info("Checking"); try { ProgramAnalysis.runFullProgramAnalysis(pf, reportPrinter); } catch (Exception e) { bixie.util.Log.error(e.toString()); } return reportPrinter; } }