10 #include <QStringList>
11 #include <QCoreApplication>
26 :
QObject(parent), mStream(nullptr)
47 if (!logReceiver)
return;
65 : mEngine(engine), mLineIndex(0), mNumberLines(0), mSaleaeDirectoryFilename(controller->get_saleae_directory_filename()),
66 mProcessLog(nullptr), mProcess(nullptr)
78 void SimulationProcess::abortOnError()
84 void SimulationProcess::openHtmlLog()
96 void SimulationProcess::runRemote()
100 QString saleaeFilesToCopy = finfo.fileName();
101 for (
int inx = 0; inx < sd.get_next_available_index(); inx++)
103 saleaeFilesToCopy +=
QString(
" digital_%1.bin").
arg(inx);
108 QString shellScriptName(localDir.absoluteFilePath(
"remote.sh"));
110 QString resultFile(
"waveform.vcd");
111 QFile ff(shellScriptName);
114 log_warning(
"simulation_plugin",
"cannot open remote script '{}' for writing", shellScriptName.toStdString());
115 return abortOnError();
117 ff.write(
"set -x\n");
118 ff.write(
"HOSTNAME=" + hostname.
toUtf8() +
"\n");
119 ff.write(
"LOCALDIR=" + localDir.absolutePath().toUtf8() +
"\n");
120 ff.write(
QString(
"if ssh ${HOSTNAME} mkdir -p /tmp/%1; then\n").arg(remoteDir).toUtf8());
121 ff.write(
QString(
" REMOTEDIR=/tmp/%1\n").arg(remoteDir).toUtf8());
123 ff.write(
QString(
" ssh ${HOSTNAME} mkdir %1\n").arg(remoteDir).toUtf8());
124 ff.write(
QString(
" REMOTEDIR=%1\n").arg(remoteDir).toUtf8());
126 ff.write(
"set -e\n");
127 ff.write(
"tar -czf - ${LOCALDIR} | ssh ${HOSTNAME} \"cd ${REMOTEDIR} ; tar -xzf -\"\n");
128 ff.write(
"ssh ${HOSTNAME} \"mkdir -p ${REMOTEDIR}${LOCALDIR}/saleae\"\n");
129 ff.write(
QString(
"cd %1; tar -czf - %2 | ssh ${HOSTNAME} \"cd ${REMOTEDIR}${LOCALDIR}/saleae ; tar -xzf -\"\n").arg(finfo.absolutePath()).
arg(saleaeFilesToCopy).
toUtf8());
131 for (
int i = 0; i < mNumberLines; i++)
133 QString remoteCmd(
"ssh ${HOSTNAME} \"cd ${REMOTEDIR}${LOCALDIR} ;");
134 for (
const std::string s : mEngine->
commandLine(i))
139 ff.write(remoteCmd.toUtf8());
141 ff.write(
QString(
"ssh %1 \"cd ${REMOTEDIR}%2 ; gzip -c %3\" | gzip -dc > %4\n").arg(hostname).arg(localDir.absolutePath()).
arg(resultFile).
arg(localDir.absoluteFilePath(resultFile)).
toUtf8());
147 args << shellScriptName;
149 if (!runProcess(
"bash", args))
150 return abortOnError();
153 return abortOnError();
158 void SimulationProcess::runLocal()
161 while (mLineIndex < mNumberLines)
167 for (
const std::string& s : mEngine->
commandLine(mLineIndex))
177 return abortOnError();
179 if (!runProcess(prog, args))
180 return abortOnError();
192 return abortOnError();
223 QString logCommand =
"<html><body bgcolor=\"#000000\">\n<h1><font color=\"#ffffff\">" + prog;
224 for (
const QString& arg : args)
225 logCommand +=
" " + arg;
226 logCommand +=
"</font></h1>\n";
233 [
this](
int exitCode,
QProcess::ExitStatus exitStatus){ this->handleFinished(exitCode,exitStatus); });
235 (*mProcessLog) << logCommand;
236 mProcessLog->
flush();
238 mProcess->
start(prog, args);
242 log_warning(
"simulation_plugin",
"Cannot start process '{}' with args '{}'",
244 if (prog ==
"verilator")
245 log_warning(
"simulation_plugin",
"You might want to check whether verilator has been installed on system");
259 if (!timeoutAfterSec.
isEmpty())
262 msecs = timeoutAfterSec.
toInt(&ok) * 1000;
263 if (!ok || msecs <= 0) msecs = -1;
265 log_warning(
"simulation_plugin",
"No QApplication running, event loop not entered, will poll for process to finish.");
268 (*mProcessLog) <<
"<p><font color=\"#ff4040\">Process timeout after 30 sec.</font></p>\n";
269 mProcessLog->
flush();
272 handleReadyReadStandardError();
273 handleReadyReadStandardOutput();
279 void SimulationProcess::handleReadyReadStandardError()
282 if (!mProcess)
return;
286 if (line.startsWith(
"%Error"))
287 errTxt +=
"<p><font color=\"#ff4040\">";
288 else if (line.startsWith(
"%Warning"))
289 errTxt +=
"<p><font color=\"#ffe050\">";
291 errTxt +=
"<p><font color=\"#ffffff\">";
296 (*mProcessLog) << errTxt;
299 void SimulationProcess::handleReadyReadStandardOutput()
302 if (!mProcess)
return;
306 outTxt +=
"<p><font color=\"#e0e0e0\">" +
QString::fromUtf8(toHtml(line)) +
"</font></p>\n";
309 (*mProcessLog) << outTxt;
315 handleReadyReadStandardError();
316 handleReadyReadStandardOutput();
318 (*mProcessLog) << endTxt;
319 mProcessLog->
flush();
321 if (exitCode != 0)
exit(exitCode);
void handleRunFinished(bool success)
The SaleaeDirectory class provides the API for the SALEAE directory file. The SALEAE directory file w...
std::string get_working_directory() const
virtual std::string get_engine_property(const std::string &key)
virtual int numberCommandLines() const =0
virtual std::vector< std::string > commandLine(int lineIndex) const =0
SimulationLogReceiver(QObject *parent=nullptr)
virtual void handleLog(const QString &txt)
SimulationProcess(NetlistSimulatorController *controller, SimulationEngineScripted *engine)
virtual ~SimulationProcess()
void processFinished(bool success)
virtual ~SimulationProcessLog()
void setLogReceiver(SimulationLogReceiver *logReceiver)
void operator<<(const QString &txt)
void processOutput(QString txt)
static QString sLogFilename
SimulationProcessLog(const QString &workdir, QObject *parent=nullptr)
#define log_warning(channel,...)
QList< QByteArray > split(char sep) const const
virtual bool open(QIODevice::OpenMode mode) override
void setFileName(const QString &name)
virtual void close() override
bool isOpen() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void finished(int exitCode)
QByteArray readAllStandardError()
QByteArray readAllStandardOutput()
void readyReadStandardError()
void readyReadStandardOutput()
void setWorkingDirectory(const QString &dir)
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode)
bool waitForFinished(int msecs)
bool waitForStarted(int msecs)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
QString fromUtf8(const char *str, int size)
bool isEmpty() const const
int toInt(bool *ok, int base) const const
std::string toStdString() const const
QByteArray toUtf8() const const
void exit(int returnCode)
QString toString() const const