Skip to content

Commit

Permalink
allow capture of stdout to file
Browse files Browse the repository at this point in the history
  • Loading branch information
mjoppich committed Mar 19, 2019
1 parent 29df8c8 commit e85057e
Show file tree
Hide file tree
Showing 7 changed files with 592 additions and 17 deletions.
139 changes: 139 additions & 0 deletions src/app/ExtendedProcFileBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#ifndef EXTENDEDFILEBUFFER_H
#define EXTENDEDFILEBUFFER_H

#include "ExtendedStdBuffer.h"
#include <src/Logging.h>

#include <QProcess>
#include <iostream>


class ExtendedProcFileBuffer : public QObject, public std::basic_streambuf<char> {
Q_OBJECT
public:

ExtendedProcFileBuffer(QProcess* pProcess, QProcess::ProcessChannel eChannel)
{

this->m_pParentProcess = new sParentProcess();
this->m_pParentProcess->pProcess = pProcess;
this->m_pParentProcess->eChannel = eChannel;

switch (eChannel)
{
default:

case QProcess::ProcessChannel::StandardOutput:

QObject::connect( pProcess, &QProcess::readyReadStandardOutput, this, &ExtendedProcFileBuffer::receiveProcData );


break;
case QProcess::ProcessChannel::StandardError :

QObject::connect( pProcess, &QProcess::readyReadStandardError, this, &ExtendedProcFileBuffer::receiveProcData );

break;

}

}

~ExtendedProcFileBuffer()
{

if (this->m_pParentProcess != NULL)
{
delete m_pParentProcess;
}

}

public slots:

virtual void receiveProcData()
{

if (this->m_pParentProcess == NULL)
{
LOGERROR("No parent process given!")
return;
}


QByteArray oArray;

switch (this->m_pParentProcess->eChannel)
{
default:

case QProcess::StandardOutput:

oArray = this->m_pParentProcess->pProcess->readAllStandardOutput();
break;

case QProcess::StandardError:

oArray = this->m_pParentProcess->pProcess->readAllStandardError();
break;
}


QString sString = QString(oArray);

emit sendText(sString);
}

public slots:
void transferText(QString sString)
{
emit sendText(sString);
}

signals:
void sendText(QString sString);

protected:
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
}
return v;
}

virtual std::streamsize xsputn(const char *p, std::streamsize n)
{

std::string sStdText(p, n);

if ((p[n] == 4) || (p[n] == 0))
{
sStdText.append("\n");
}

QString sText(sStdText.c_str());

this->transferText(sText);

return n;
}


protected:

struct sParentProcess
{
QProcess* pProcess;
QProcess::ProcessChannel eChannel;
};




sParentProcess* m_pParentProcess = NULL;

};


#endif // EXTENDEDFILEBUFFER_H
150 changes: 150 additions & 0 deletions src/app/ExtendedThreadFileBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#ifndef EXTENDEDTHREADFILEBUFFER_H
#define EXTENDEDTHREADFILEBUFFER_H

#include "ExecuteThread.h"
#include "ExtendedStdBuffer.h"
#include <src/Logging.h>

#include <QProcess>
#include <iostream>


class ExtendedThreadFileBuffer : public QObject, public std::basic_streambuf<char> {
Q_OBJECT
public:

ExtendedThreadFileBuffer(ExecuteThread* pThread, QProcess::ProcessChannel eChannel)
{

this->m_pParentThread = new sParentThread();
this->m_pParentThread->pThread = pThread;
this->m_pParentThread->eChannel = eChannel;

switch (eChannel)
{
default:

case QProcess::ProcessChannel::StandardOutput:

QObject::connect( pThread, &ExecuteThread::readyReadStandardOutput, this, &ExtendedThreadFileBuffer::receiveProcData );


break;
case QProcess::ProcessChannel::StandardError :

QObject::connect( pThread, &ExecuteThread::readyReadStandardError, this, &ExtendedThreadFileBuffer::receiveProcData );

break;

}
}

~ExtendedThreadFileBuffer()
{

if (this->m_pParentThread != NULL)
{
delete m_pParentThread;
m_pParentThread = NULL;
}

}
virtual void stopTransmissions()
{
m_bTransmissionAllowed = false;
}

public slots:

virtual void receiveProcData()
{

if (this->m_pParentThread == NULL)
{
LOGERROR("No parent process given!")
return;
}


QByteArray oArray;

switch (this->m_pParentThread->eChannel)
{
default:

case QProcess::StandardOutput:

oArray = this->m_pParentThread->pThread->readAllStandardOutput();
break;

case QProcess::StandardError:

oArray = this->m_pParentThread->pThread->readAllStandardError();
break;
}


QString sString = QString(oArray);


if (m_bTransmissionAllowed)
{
emit sendText(sString);
}

}

public slots:
void transferText(QString sString)
{
emit sendText(sString);
}

signals:
void sendText(QString sString);

protected:
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
}
return v;
}

virtual std::streamsize xsputn(const char *p, std::streamsize n)
{

std::string sStdText(p, n);

if ((p[n] == 4) || (p[n] == 0))
{
sStdText.append("\n");
}

QString sText(sStdText.c_str());

this->transferText(sText);

return n;
}



protected:

struct sParentThread
{
ExecuteThread* pThread;
QProcess::ProcessChannel eChannel;
};


bool m_bTransmissionAllowed = true;

sParentThread* m_pParentThread = NULL;

};


#endif // EXTENDEDTHREADFILEBUFFER_H
3 changes: 2 additions & 1 deletion src/bioGUIapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,10 @@ void bioGUIapp::runProgram(std::string& sProgramToRun)

m_pExecThread = new ExecutionRunThread(m_pWindowParser, pParseExecution, sProgramToRun, this);
bioGUIapp* pApp = this;
ExecutionRunThread* pExecThread = m_pExecThread;

this->connect(m_pExecThread, &QThread::started, m_pExecThread, &ExecutionRunThread::startExecution);
this->connect(m_pExecThread, &ExecutionRunThread::executionFinished, [pApp] () {
this->connect(m_pExecThread, &ExecutionRunThread::executionFinished, [pApp, pExecThread] () {

pApp->programFinished();

Expand Down
4 changes: 2 additions & 2 deletions src/parsing/nodes/ExecutionExecutableNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@

class bioGUIapp;

class ExecutionExecutableNode : public QObject, public ExecutionNode
class ExecutionExecutableNode : public ExecutionNode
{
Q_OBJECT

public:

ExecutionExecutableNode(QDomElement* pElement)
: QObject(NULL), ExecutionNode(pElement)
: ExecutionNode(pElement)
{
m_sProgramName = this->getDomElementAttribute(pElement, "program", "").toStdString();
}
Expand Down
16 changes: 10 additions & 6 deletions src/parsing/nodes/ExecutionExecuteNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,26 @@ class ExecutionExecuteNode : public ExecutionExecutableNode {

if (pProcess != NULL)
{
ExecutionNode* pNode = m_vChildren.at(i);
ExecutionOutputNode* pOutNode = dynamic_cast<ExecutionOutputNode*>( pNode );

if (ExecutionOutputNode* pOutPutnode = dynamic_cast<ExecutionOutputNode*>( m_vChildren.at(i) ))
if (pOutNode)
{
sReturn = sReturn + pOutPutnode->evaluateDeferred(pID2Node, pInputID2Value, pInputID2FunctionWidget, pProcess, pThread, bDeferred);
sReturn = sReturn + pOutNode->evaluateDeferred(pID2Node, pInputID2Value, pInputID2FunctionWidget, pProcess, pThread, bDeferred);
} else {
sReturn = sReturn + m_vChildren.at(i)->evaluate(pID2Node, pInputID2Value, pInputID2FunctionWidget);
sReturn = sReturn + pNode->evaluate(pID2Node, pInputID2Value, pInputID2FunctionWidget);

}

} else {
ExecutionNode* pNode = m_vChildren.at(i);
ExecutionOutputNode* pOutNode = dynamic_cast<ExecutionOutputNode*>( pNode );

if (ExecutionOutputNode* pOutPutnode = dynamic_cast<ExecutionOutputNode*>( m_vChildren.at(i) ))
if (pOutNode)
{
sReturn = sReturn + pOutPutnode->evaluateDeferred(pID2Node, pInputID2Value, pInputID2FunctionWidget, pProcess, pThread, bDeferred);
sReturn = sReturn + pOutNode->evaluateDeferred(pID2Node, pInputID2Value, pInputID2FunctionWidget, pProcess, pThread, bDeferred);
} else {
sReturn = sReturn + m_vChildren.at(i)->evaluate(pID2Node, pInputID2Value, pInputID2FunctionWidget);
sReturn = sReturn + pNode->evaluate(pID2Node, pInputID2Value, pInputID2FunctionWidget);

}

Expand Down
9 changes: 8 additions & 1 deletion src/parsing/nodes/ExecutionNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@


#include <QDomElement>
#include <QObject>
#include <QWidget>
#include <vector>
#include <map>
Expand Down Expand Up @@ -57,10 +58,16 @@ class ExecutionNodeException : public std::exception
};
*/

class ExecutionNode {
class ExecutionNode : public QObject {

public:

ExecutionNode()
: QObject(NULL)
{

}

enum NODE_TYPE {

STRING = 0,
Expand Down

0 comments on commit e85057e

Please sign in to comment.