mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-19 09:54:49 -04:00
added model.close() to model usages. Cleanup of generated temp folders.
This commit is contained in:
parent
b40023b01a
commit
5c9003e59d
@ -6,6 +6,8 @@
|
||||
package de.neemann.digital.core.extern;
|
||||
|
||||
import de.neemann.digital.lang.Lang;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@ -17,6 +19,7 @@ import java.util.Arrays;
|
||||
* Helper to start and wait for a process.
|
||||
*/
|
||||
public final class ProcessStarter {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ProcessStarter.class);
|
||||
|
||||
private ProcessStarter() {
|
||||
}
|
||||
@ -38,7 +41,7 @@ public final class ProcessStarter {
|
||||
try {
|
||||
p = pb.start();
|
||||
} catch (IOException e) {
|
||||
throw new IOException(Lang.get("err_couldNotStartProcess_N", Arrays.toString(args)));
|
||||
throw new CouldNotStartProcessException(Lang.get("err_couldNotStartProcess_N", Arrays.toString(args)));
|
||||
}
|
||||
ReaderThread rt = new ReaderThread(p.getInputStream());
|
||||
rt.start();
|
||||
@ -99,11 +102,10 @@ public final class ProcessStarter {
|
||||
for (File f : list) {
|
||||
if (f.isDirectory())
|
||||
removeFolder(f);
|
||||
else
|
||||
f.delete();
|
||||
else if (!f.delete()) LOGGER.warn("file " + f + " could not be deleted!");
|
||||
}
|
||||
}
|
||||
dir.delete();
|
||||
if (!dir.delete()) LOGGER.warn("dir " + dir + " could not be deleted!");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,4 +133,12 @@ public final class ProcessStarter {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if process could not be started
|
||||
*/
|
||||
public static final class CouldNotStartProcessException extends IOException {
|
||||
private CouldNotStartProcessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ package de.neemann.digital.core.extern.handler;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.ObservableValues;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.LinkedList;
|
||||
@ -22,6 +24,7 @@ import java.util.LinkedList;
|
||||
* The last bit needs to be followed by an end of line character.
|
||||
*/
|
||||
public class StdIOInterface implements ProcessInterface {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(StdIOInterface.class);
|
||||
private static final String PREFIX = "Digital:";
|
||||
private static final int MAX_CONSOLE_LINES = 30;
|
||||
private static final long TIMEOUT = 5000;
|
||||
@ -69,6 +72,7 @@ public class StdIOInterface implements ProcessInterface {
|
||||
consoleOut = new LinkedList<>();
|
||||
terminated = false;
|
||||
thread = new Thread(() -> {
|
||||
LOGGER.debug("reader-thread started");
|
||||
try {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
@ -91,6 +95,7 @@ public class StdIOInterface implements ProcessInterface {
|
||||
terminated = true;
|
||||
lock.notify();
|
||||
}
|
||||
LOGGER.debug("reader-thread terminated");
|
||||
});
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
|
@ -544,7 +544,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
|
||||
// check model for errors
|
||||
try {
|
||||
new ModelCreator(circuitComponent.getCircuit(), library).createModel(false);
|
||||
new ModelCreator(circuitComponent.getCircuit(), library).createModel(false).close();
|
||||
} catch (PinException | NodeException | ElementNotFoundException e) {
|
||||
showErrorWithoutARunningModel(Lang.get("msg_modelHasErrors"), e);
|
||||
return;
|
||||
@ -924,14 +924,18 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
Model model = new ModelCreator(circuitComponent.getCircuit(), library).createModel(false);
|
||||
model.setWindowPosManager(windowPosManager);
|
||||
SpeedTest speedTest = new SpeedTest(model);
|
||||
String frequency = format.format(speedTest.calculate() / 1000);
|
||||
circuitComponent.getCircuit().clearState();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
windowPosManager.closeAll();
|
||||
JOptionPane.showMessageDialog(Main.this, Lang.get("msg_frequency_N", frequency));
|
||||
});
|
||||
try {
|
||||
model.setWindowPosManager(windowPosManager);
|
||||
SpeedTest speedTest = new SpeedTest(model);
|
||||
String frequency = format.format(speedTest.calculate() / 1000);
|
||||
circuitComponent.getCircuit().clearState();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
windowPosManager.closeAll();
|
||||
JOptionPane.showMessageDialog(Main.this, Lang.get("msg_frequency_N", frequency));
|
||||
});
|
||||
} finally {
|
||||
model.close();
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
showErrorWithoutARunningModel(Lang.get("msg_speedTestError"), e1);
|
||||
}
|
||||
@ -1036,17 +1040,20 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
Model model = new ModelCreator(circuitComponent.getCircuit(), library).createModel(false);
|
||||
|
||||
if (model.isInvalidSignal())
|
||||
new ErrorMessage(Lang.get("msg_invalidSignalsAnalysed")).show(Main.this);
|
||||
else
|
||||
new TableDialog(Main.this,
|
||||
new ModelAnalyser(model).analyse(),
|
||||
library,
|
||||
shapeFactory,
|
||||
getBaseFileName())
|
||||
.setVisible(true);
|
||||
ensureModelIsStopped();
|
||||
try {
|
||||
if (model.isInvalidSignal())
|
||||
new ErrorMessage(Lang.get("msg_invalidSignalsAnalysed")).show(Main.this);
|
||||
else
|
||||
new TableDialog(Main.this,
|
||||
new ModelAnalyser(model).analyse(),
|
||||
library,
|
||||
shapeFactory,
|
||||
getBaseFileName())
|
||||
.setVisible(true);
|
||||
ensureModelIsStopped();
|
||||
} finally {
|
||||
model.close();
|
||||
}
|
||||
} catch (PinException | NodeException | AnalyseException | ElementNotFoundException | BacktrackException | RuntimeException e1) {
|
||||
showErrorWithoutARunningModel(Lang.get("msg_analyseErr"), e1);
|
||||
}
|
||||
@ -1081,16 +1088,20 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
private void orderMeasurements() {
|
||||
try {
|
||||
Model m = new ModelCreator(circuitComponent.getCircuit(), library).createModel(false);
|
||||
ensureModelIsStopped();
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
for (Signal s : m.getSignals())
|
||||
names.add(s.getName());
|
||||
new OrderMerger<String, String>(circuitComponent.getCircuit().getMeasurementOrdering()).order(names);
|
||||
ElementOrderer.ListOrder<String> o = new ElementOrderer.ListOrder<>(names);
|
||||
if (new ElementOrderer<>(Main.this, Lang.get("menu_orderMeasurements"), o)
|
||||
.addOkButton()
|
||||
.showDialog()) {
|
||||
circuitComponent.modify(new ModifyMeasurementOrdering(names));
|
||||
try {
|
||||
ensureModelIsStopped();
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
for (Signal s : m.getSignals())
|
||||
names.add(s.getName());
|
||||
new OrderMerger<String, String>(circuitComponent.getCircuit().getMeasurementOrdering()).order(names);
|
||||
ElementOrderer.ListOrder<String> o = new ElementOrderer.ListOrder<>(names);
|
||||
if (new ElementOrderer<>(Main.this, Lang.get("menu_orderMeasurements"), o)
|
||||
.addOkButton()
|
||||
.showDialog()) {
|
||||
circuitComponent.modify(new ModifyMeasurementOrdering(names));
|
||||
}
|
||||
} finally {
|
||||
m.close();
|
||||
}
|
||||
} catch (NodeException | PinException | ElementNotFoundException | RuntimeException e) {
|
||||
showErrorWithoutARunningModel(Lang.get("msg_errorCreatingModel"), e);
|
||||
|
@ -787,13 +787,16 @@ public final class EditorFactory {
|
||||
try {
|
||||
CircuitComponent circuitComponent = main.getCircuitComponent();
|
||||
Model model = new ModelCreator(circuitComponent.getCircuit(), circuitComponent.getLibrary()).createModel(false);
|
||||
|
||||
romEditorDialog = new ROMEditorDialog(
|
||||
getAttributeDialog(),
|
||||
model,
|
||||
romManager);
|
||||
if (romEditorDialog.showDialog())
|
||||
romManager = romEditorDialog.getROMManager();
|
||||
try {
|
||||
romEditorDialog = new ROMEditorDialog(
|
||||
getAttributeDialog(),
|
||||
model,
|
||||
romManager);
|
||||
if (romEditorDialog.showDialog())
|
||||
romManager = romEditorDialog.getROMManager();
|
||||
} finally {
|
||||
model.close();
|
||||
}
|
||||
} catch (ElementNotFoundException | PinException | NodeException e) {
|
||||
new ErrorMessage(Lang.get("msg_errorCreatingModel")).addCause(e).show(getAttributeDialog());
|
||||
}
|
||||
|
@ -115,30 +115,34 @@ public class ValueTableDialog extends JDialog {
|
||||
int errorTabIndex = -1;
|
||||
for (TestSet ts : tsl) {
|
||||
Model model = new ModelCreator(circuit, library).createModel(false);
|
||||
try {
|
||||
|
||||
TestExecutor testExecutor = new TestExecutor(ts.data).create(model);
|
||||
TestExecutor testExecutor = new TestExecutor(ts.data).create(model);
|
||||
|
||||
if (testExecutor.getException() != null)
|
||||
SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorWhileExecutingTests_N0", ts.name)).addCause(testExecutor.getException()).setComponent(this));
|
||||
if (testExecutor.getException() != null)
|
||||
SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorWhileExecutingTests_N0", ts.name)).addCause(testExecutor.getException()).setComponent(this));
|
||||
|
||||
String tabName;
|
||||
Icon tabIcon;
|
||||
if (testExecutor.allPassed()) {
|
||||
tabName = Lang.get("msg_test_N_Passed", ts.name);
|
||||
tabIcon = ICON_PASSED;
|
||||
} else {
|
||||
tabName = Lang.get("msg_test_N_Failed", ts.name);
|
||||
tabIcon = ICON_FAILED;
|
||||
errorTabIndex = i;
|
||||
String tabName;
|
||||
Icon tabIcon;
|
||||
if (testExecutor.allPassed()) {
|
||||
tabName = Lang.get("msg_test_N_Passed", ts.name);
|
||||
tabIcon = ICON_PASSED;
|
||||
} else {
|
||||
tabName = Lang.get("msg_test_N_Failed", ts.name);
|
||||
tabIcon = ICON_FAILED;
|
||||
errorTabIndex = i;
|
||||
}
|
||||
if (testExecutor.toManyResults())
|
||||
tabName += " " + Lang.get("msg_test_missingLines");
|
||||
|
||||
tp.addTab(tabName, tabIcon, new JScrollPane(createTable(testExecutor.getResult())));
|
||||
if (testExecutor.toManyResults())
|
||||
tp.setToolTipTextAt(i, new LineBreaker().toHTML().breakLines(Lang.get("msg_test_missingLines_tt")));
|
||||
resultTableData.add(testExecutor.getResult());
|
||||
i++;
|
||||
} finally {
|
||||
model.close();
|
||||
}
|
||||
if (testExecutor.toManyResults())
|
||||
tabName += " " + Lang.get("msg_test_missingLines");
|
||||
|
||||
tp.addTab(tabName, tabIcon, new JScrollPane(createTable(testExecutor.getResult())));
|
||||
if (testExecutor.toManyResults())
|
||||
tp.setToolTipTextAt(i, new LineBreaker().toHTML().breakLines(Lang.get("msg_test_missingLines_tt")));
|
||||
resultTableData.add(testExecutor.getResult());
|
||||
i++;
|
||||
}
|
||||
if (errorTabIndex >= 0)
|
||||
tp.setSelectedIndex(errorTabIndex);
|
||||
|
@ -72,6 +72,7 @@ public class BuilderExpressionCreatorTest extends TestCase {
|
||||
|
||||
private void check(Model m) throws AnalyseException, NodeException, BacktrackException, PinException {
|
||||
TruthTable tt = new ModelAnalyser(m).analyse();
|
||||
m.close();
|
||||
assertEquals(1,tt.getResultCount());
|
||||
BoolTable r = tt.getResult(0);
|
||||
assertEquals(4, r.size());
|
||||
@ -79,6 +80,7 @@ public class BuilderExpressionCreatorTest extends TestCase {
|
||||
assertEquals(ThreeStateValue.one ,r.get(1));
|
||||
assertEquals(ThreeStateValue.one ,r.get(2));
|
||||
assertEquals(ThreeStateValue.zero ,r.get(3));
|
||||
|
||||
}
|
||||
|
||||
private Model create(ExpressionListenerStore els, ExpressionModifier modifier) throws ExpressionException, FormatterException, ElementNotFoundException, PinException, NodeException {
|
||||
|
@ -7,6 +7,7 @@ package de.neemann.digital.hdl.vhdl;
|
||||
|
||||
import de.neemann.digital.core.ExceptionWithOrigin;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.extern.ProcessStarter;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.hdl.model.HDLException;
|
||||
@ -96,19 +97,18 @@ public class TestInSimulator extends TestCase {
|
||||
private void check(File file) throws PinException, NodeException, ElementNotFoundException, IOException, FileScanner.SkipAllException, HDLException {
|
||||
ToBreakRunner br = new ToBreakRunner(file);
|
||||
File dir = Files.createTempDirectory("digital_vhdl_" + getTime() + "_").toFile();
|
||||
File vhdlFile = new File(dir, file.getName().replace('.', '_') + ".vhdl");
|
||||
CodePrinter out = new CodePrinter(vhdlFile);
|
||||
try (VHDLGenerator vhdl = new VHDLGenerator(br.getLibrary(), out)) {
|
||||
vhdl.omitClockDividers().export(br.getCircuit());
|
||||
VHDLTestBenchCreator tb = vhdl.getTestBenches();
|
||||
out.close();
|
||||
runGHDL(vhdlFile, tb.getTestFileWritten());
|
||||
try {
|
||||
File vhdlFile = new File(dir, file.getName().replace('.', '_') + ".vhdl");
|
||||
CodePrinter out = new CodePrinter(vhdlFile);
|
||||
try (VHDLGenerator vhdl = new VHDLGenerator(br.getLibrary(), out)) {
|
||||
vhdl.omitClockDividers().export(br.getCircuit());
|
||||
VHDLTestBenchCreator tb = vhdl.getTestBenches();
|
||||
out.close();
|
||||
runGHDL(vhdlFile, tb.getTestFileWritten());
|
||||
}
|
||||
} finally {
|
||||
ProcessStarter.removeFolder(dir);
|
||||
}
|
||||
File[] filesInDir = dir.listFiles();
|
||||
if (filesInDir != null)
|
||||
for (File f : filesInDir)
|
||||
if (!f.delete()) LOGGER.warn("file " + f + " could not be deleted!");
|
||||
if (!dir.delete()) LOGGER.warn("dir " + dir + " could not be deleted!");
|
||||
}
|
||||
|
||||
private void runGHDL(File vhdlFile, ArrayList<File> testFileWritten) throws IOException, FileScanner.SkipAllException, HDLException {
|
||||
@ -135,29 +135,11 @@ public class TestInSimulator extends TestCase {
|
||||
}
|
||||
|
||||
private String startProcess(File dir, String... args) throws IOException, FileScanner.SkipAllException {
|
||||
//System.out.println("start " + Arrays.toString(args));
|
||||
ProcessBuilder pb = new ProcessBuilder(args).redirectErrorStream(true).directory(dir);
|
||||
Process p;
|
||||
try {
|
||||
p = pb.start();
|
||||
} catch (IOException e) {
|
||||
return ProcessStarter.start(dir, args);
|
||||
} catch (ProcessStarter.CouldNotStartProcessException e) {
|
||||
throw new FileScanner.SkipAllException("ghdl (https://github.com/tgingold/ghdl) is not installed! Add ghdl binary to the system path or set system property 'ghdl' to ghdl binary");
|
||||
}
|
||||
ReaderThread rt = new ReaderThread(p.getInputStream());
|
||||
rt.start();
|
||||
try {
|
||||
int exitValue = p.waitFor();
|
||||
rt.join();
|
||||
|
||||
String output = rt.toString();
|
||||
|
||||
if (exitValue != 0)
|
||||
throw new IOException("exit value not null: " + exitValue + "\n" + output);
|
||||
|
||||
return output;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getTime() {
|
||||
@ -165,35 +147,4 @@ public class TestInSimulator extends TestCase {
|
||||
return f.format(new Date());
|
||||
}
|
||||
|
||||
private static final class ReaderThread extends Thread {
|
||||
private final ByteArrayOutputStream baos;
|
||||
private final InputStream in;
|
||||
|
||||
private ReaderThread(InputStream in) {
|
||||
this.in = in;
|
||||
baos = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
try {
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
while ((len = in.read(buffer)) > 0)
|
||||
baos.write(buffer, 0, len);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// do nothing, simply end the thread
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return baos.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,35 +65,43 @@ public class TestExamples extends TestCase {
|
||||
} else
|
||||
throw e;
|
||||
}
|
||||
|
||||
boolean isLib = dig.getPath().replace('\\', '/').contains("/lib/");
|
||||
|
||||
assertTrue("wrong locked mode", isLib == br.getCircuit().getAttributes().get(Keys.LOCKED_MODE));
|
||||
|
||||
try {
|
||||
for (VisualElement el : br.getCircuit().getElements())
|
||||
if (el.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION)) {
|
||||
|
||||
String label = el.getElementAttributes().getCleanLabel();
|
||||
TestCaseDescription td = el.getElementAttributes().get(TestCaseElement.TESTDATA);
|
||||
boolean isLib = dig.getPath().replace('\\', '/').contains("/lib/");
|
||||
|
||||
Model model = new ModelCreator(br.getCircuit(), br.getLibrary()).createModel(false);
|
||||
TestExecutor tr = new TestExecutor(td).create(model);
|
||||
assertTrue("wrong locked mode", isLib == br.getCircuit().getAttributes().get(Keys.LOCKED_MODE));
|
||||
|
||||
if (label.contains("Failing"))
|
||||
assertFalse(dig.getName() + ":" + label, tr.allPassed());
|
||||
else
|
||||
assertTrue(dig.getName() + ":" + label, tr.allPassed());
|
||||
try {
|
||||
for (VisualElement el : br.getCircuit().getElements())
|
||||
if (el.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION)) {
|
||||
|
||||
testCasesInFiles++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (shouldFail) {
|
||||
return;
|
||||
} else
|
||||
throw e;
|
||||
String label = el.getElementAttributes().getCleanLabel();
|
||||
TestCaseDescription td = el.getElementAttributes().get(TestCaseElement.TESTDATA);
|
||||
|
||||
Model model = new ModelCreator(br.getCircuit(), br.getLibrary()).createModel(false);
|
||||
try {
|
||||
TestExecutor tr = new TestExecutor(td).create(model);
|
||||
|
||||
if (label.contains("Failing"))
|
||||
assertFalse(dig.getName() + ":" + label, tr.allPassed());
|
||||
else
|
||||
assertTrue(dig.getName() + ":" + label, tr.allPassed());
|
||||
|
||||
testCasesInFiles++;
|
||||
} finally {
|
||||
model.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (shouldFail) {
|
||||
return;
|
||||
} else
|
||||
throw e;
|
||||
}
|
||||
|
||||
assertFalse("File should fail but doesn't!", shouldFail);
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
|
||||
assertFalse("File should fail but doesn't!", shouldFail);
|
||||
}
|
||||
}
|
||||
|
@ -139,4 +139,9 @@ public class ToBreakRunner {
|
||||
public ElementLibrary getLibrary() {
|
||||
return library;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (model != null)
|
||||
model.close();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user