package Compiler;
import gov.nasa.jpf.Config;
import gov.nasa.jpf.JPF;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import main.PseuCoCo;
import GUI.Output;
public class DeadlockCheck {
private static File includeDirFile = new File(CompilerUtils.getIncludeDirectory());
private static String includeDir = CompilerUtils.getIncludeDirectory();
public static void run(final String path) {
boolean success= true;
File exportDir= new File(CompilerUtils.DEFAULT_EXPORT_DIRECTORY);
if (!exportDir.exists()) {
success= exportDir.mkdirs();
}
if (!success) {
Output.con.println("Failed to create export directory for compilation");
return;
}
success= compilePseucoProject(new String[] {"-i", new File(path).getAbsolutePath(), "-e", CompilerUtils.DEFAULT_EXPORT_DIRECTORY});
if (!success) {
Output.con.println("Verification failed while compiling PseuCo code");
return;
} else {
Output.con.println("PseuCo code compiled");
}
success= compileJavaProject();
if (!success) {
Output.con.println("Verification failed while compiling exported Java code");
return;
} else {
Output.con.println("Java code compiled");
}
success= exportJavaJAR();
if (!success) {
Output.con.println("Verification failed while exporting JAR file");
return;
} else {
Output.con.println("Java code exported to JAR");
}
success= runJPF();
if (!success) {
Output.con.println("Error running JPF verifier");
return;
}
}
private static boolean runJPF() {
// Config conf= JPF.createConfig(new String[] {"+classpath= " + CompilerUtils.DEFAULT_EXPORT_DIRECTORY + File.separator + "compiledpseuco.jar", "include.Main"});
// JPF jpf= new JPF(conf);
// jpf.run();
JPF.main(new String[] {"+classpath= " + CompilerUtils.DEFAULT_EXPORT_DIRECTORY + File.separator + "compiledpseuco.jar", "include.Main"});
/*
if (jpf.foundErrors()) {
return false;
} else {
return true;
}
*/
return true;
}
private static boolean exportJavaJAR() {
boolean success= true;
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, "include.Main");
try {
JarOutputStream target = new JarOutputStream(new FileOutputStream(new File(CompilerUtils.DEFAULT_EXPORT_DIRECTORY + File.separator + "compiledpseuco.jar")), manifest);
File javaDir= new File(CompilerUtils.DEFAULT_EXPORT_DIRECTORY);
File[] files= javaDir.listFiles();
for (File file : files) {
if (file.isFile() && file.getAbsolutePath().toLowerCase().endsWith("class")) {
JarEntry entry= new JarEntry(CompilerUtils.DEFAULT_EXPORT_PACKAGE + File.separator + file.getName());
entry.setTime(file.lastModified());
target.putNextEntry(entry);
BufferedInputStream reader = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[1024];
while (true)
{
int count = reader.read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
target.closeEntry();
reader.close();
}
}
target.close();
} catch (IOException e) {
success= false;
}
return success;
}
private static boolean compileJavaProject() {
boolean success= false;
File javaDir= new File(CompilerUtils.DEFAULT_EXPORT_DIRECTORY);
File[] files= javaDir.listFiles();
JavaCompiler compiler= ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits= fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files));
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
success = task.call();
if (!success) {
for (Diagnostic<? extends JavaFileObject> diag : diagnostics.getDiagnostics()) {
Output.conerr.println(diag.toString());
}
return success;
}
return true;
}
private static boolean compilePseucoProject(final String[] compileArgs) {
boolean success= true;
try {
CompilerUtils.del(includeDirFile);
CompilerUtils.unZipIt(CompilerUtils.INCLUDE_DEBUG_FILE, includeDir);
CompilerUtils.del(new File(compileArgs[3]));
new File(compileArgs[3]).mkdir();
Output.con.println("Starting PseuCo Compiler...");
Thread compilerThread = new Thread("PseuCo compiler"){
@Override
public void run() {
this.setName("SUCCESS");
try{
PseuCoCo.main(compileArgs);
} catch (Exception e) {
CompilerUtils.handleException(e);
// Horrible way to return a value
this.setName("FAILED");
}
}
};
compilerThread.start();
compilerThread.join();
if (compilerThread.getName().equals("FAILED"))
success= false;
} catch (Exception e) {
CompilerUtils.handleException(e);
} finally {
CompilerUtils.del(includeDirFile);
if (success)
Output.con.println("Compilation complete");
else
Output.con.println("Compilation failed");
}
return success;
}
}