/*******************************************************************************
* This file is part of logisim-evolution.
*
* logisim-evolution is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* logisim-evolution 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 logisim-evolution. If not, see <http://www.gnu.org/licenses/>.
*
* Original code by Carl Burch (http://www.cburch.com), 2011.
* Subsequent modifications by :
* + Haute École Spécialisée Bernoise
* http://www.bfh.ch
* + Haute École du paysage, d'ingénierie et d'architecture de Genève
* http://hepia.hesge.ch/
* + Haute École d'Ingénierie et de Gestion du Canton de Vaud
* http://www.heig-vd.ch/
* The project is currently maintained by :
* + REDS Institute - HEIG-VD
* Yverdon-les-Bains, Switzerland
* http://reds.heig-vd.ch
*******************************************************************************/
package com.cburch.logisim.util;
import java.awt.Component;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import com.cburch.logisim.prefs.AppPreferences;
public final class Softwares {
private static boolean createWorkLibrary(File tmpDir, String questaPath,
StringBuffer result) throws IOException, InterruptedException {
BufferedReader reader = null;
if (new File(FileUtil.correctPath(tmpDir.getCanonicalPath()) + "work")
.exists())
return true;
try {
List<String> command = new ArrayList<String>();
command.add(FileUtil.correctPath(questaPath) + QUESTA_BIN[VLIB]);
command.add("work");
ProcessBuilder vlibBuilder = new ProcessBuilder(command);
vlibBuilder.directory(tmpDir);
Process vlib = vlibBuilder.start();
InputStream is = vlib.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
result.append(System.getProperty("line.separator"));
}
return vlib.waitFor() == 0;
} catch (IOException e) {
throw e;
} catch (InterruptedException e) {
throw e;
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException ex) {
Logger.getLogger(Softwares.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
public static String getQuestaPath() {
return getQuestaPath(null);
}
public static String getQuestaPath(Component parent) {
String prefPath = AppPreferences.QUESTA_PATH.get();
if (!validatePath(prefPath, QUESTA))
if ((prefPath = setQuestaPath()) == null)
return null;
return prefPath;
}
private static String[] loadQuesta() {
String[] questaProgs = { "vcom", "vsim", "vmap", "vlib" };
String osname = System.getProperty("os.name");
if (osname == null)
throw new IllegalArgumentException("no os.name");
else if (osname.toLowerCase().contains("windows"))
for (int i = 0; i < questaProgs.length; i++)
questaProgs[i] += ".exe";
return questaProgs;
}
public static String setQuestaPath() {
return setQuestaPath(null);
}
public static String setQuestaPath(Component parent) {
String path = null;
JFileChooser chooser = JFileChoosers.create();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setDialogTitle(Strings.get("questaDialogTitle"));
chooser.setApproveButtonText(Strings.get("questaDialogButton"));
int action = chooser.showOpenDialog(parent);
if (action == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
try {
path = file.getCanonicalPath();
} catch (IOException ex) {
JOptionPane.showMessageDialog(parent,
Strings.get("questaIoErrorMessage"),
Strings.get("questaErrorTitle"),
JOptionPane.ERROR_MESSAGE);
return null;
}
if (validatePath(path, QUESTA)) {
AppPreferences.QUESTA_PATH.set(path);
} else {
JOptionPane.showMessageDialog(parent,
Strings.get("questaErrorMessage"),
Strings.get("questaErrorTitle"),
JOptionPane.ERROR_MESSAGE);
return null;
}
}
return path;
}
private static boolean validatePath(String path, String software) {
String[] programs;
if (software.equals(QUESTA))
programs = QUESTA_BIN;
else
return false;
for (int i = 0; i < programs.length; i++) {
File test = new File(FileUtil.correctPath(path) + programs[i]);
if (!test.exists())
return false;
}
return true;
}
public static int validateVhdl(String vhdl, StringBuffer title,
StringBuffer result) {
if (!AppPreferences.QUESTA_VALIDATION.get())
return SUCCESS;
String questaPath = getQuestaPath();
BufferedReader reader = null;
File tmp = null;
if (questaPath == null) {
result.append(Strings.get("questaValidationAbordedMessage"));
title.append(Strings.get("questaValidationAbordedTitle"));
return ABORD;
}
try {
tmp = FileUtil.createTmpFile(vhdl, "tmp", ".vhd");
File tmpDir = new File(tmp.getParentFile().getCanonicalPath());
if (!createWorkLibrary(tmpDir, questaPath, result)) {
title.insert(0, Strings.get("questaLibraryErrorTitle"));
result.insert(0, System.getProperty("line.separator"));
result.insert(0, Strings.get("questaLibraryErrorMessage"));
return ERROR;
}
List<String> command = new ArrayList<String>();
command.add(FileUtil.correctPath(questaPath) + QUESTA_BIN[VCOM]);
command.add("-reportprogress");
command.add("300");
command.add("-93");
command.add("-work");
command.add("work");
command.add(tmp.getName());
ProcessBuilder questa = new ProcessBuilder(command);
questa.directory(tmpDir);
Process vcom = questa.start();
InputStream is = vcom.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
result.append(System.getProperty("line.separator"));
}
if (vcom.waitFor() != 0) {
title.insert(0, Strings.get("questaValidationFailedTitle"));
result.insert(0, System.getProperty("line.separator"));
result.insert(0, Strings.get("questaValidationFailedMessage"));
return ERROR;
}
} catch (IOException e) {
title.insert(0, Strings.get("questaValidationFailedTitle"));
result.replace(0, result.length(), e.getMessage());
result.insert(0, System.getProperty("line.separator"));
result.insert(0, Strings.get("questaValidationIoException"));
return ERROR;
} catch (InterruptedException e) {
title.insert(0, Strings.get("questaValidationFailedTitle"));
result.replace(0, result.length(), e.getMessage());
result.insert(0, System.getProperty("line.separator"));
result.insert(0, Strings.get("questaValidationInterrupted"));
return ERROR;
} finally {
try {
if (tmp != null)
tmp.deleteOnExit();
if (reader != null)
reader.close();
} catch (IOException ex) {
Logger.getLogger(Softwares.class.getName()).log(Level.SEVERE,
null, ex);
}
}
return SUCCESS;
}
public static final String QUESTA = "questaSim";
public static final String[] QUESTA_BIN = loadQuesta();
public static final int SUCCESS = 0;
public static final int ERROR = 1;
public static final int ABORD = 2;
public static final int VCOM = 0;
public static final int VSIM = 1;
public static final int VMAP = 2;
public static final int VLIB = 3;
private Softwares() {
}
}