Skip to content

Commit

Permalink
Some code refactoring: Now using an enum to set the output format ins…
Browse files Browse the repository at this point in the history
…tead of separate flags.
  • Loading branch information
lordmulder committed Mar 25, 2013
1 parent 1cfb029 commit 4ce9c3e
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 137 deletions.
227 changes: 120 additions & 107 deletions src/LogProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ static const int CHANNEL_SYSMSG = 8;
//Helper
#define SAFE_DEL(X) do { if(X) { delete (X); X = NULL; } } while (0)

// ===================================================
// Constructor & Destructor
// ===================================================

/*
* Constructor
*/
Expand All @@ -54,13 +58,19 @@ CLogProcessor::CLogProcessor(QFile &logFile)
m_logStdout(true),
m_logStderr(true),
m_simplify(true),
m_verbose(true),
m_htmlOutput(false),
m_logIsEmpty(false),
m_logFormat(LOG_FORMAT_VERBOSE),
m_logInitialized(false),
m_logFinished(false),
m_logIsEmpty(logFile.size() == 0),
m_exitCode(-1)
{
//Sanity check
if(!(logFile.isOpen() && logFile.isWritable()))
{
throw "Log file not open for writing!";
}

//Create process
m_process = new QProcess();

//Setup process
Expand All @@ -86,7 +96,6 @@ CLogProcessor::CLogProcessor(QFile &logFile)

//Assign the log file
m_logFile = new QTextStream(&logFile);
m_logIsEmpty = (logFile.size() == 0);
m_logFile->setCodec(QTextCodec::codecForName("UTF-8"));
m_logFile->setGenerateByteOrderMark(m_logIsEmpty);

Expand Down Expand Up @@ -115,6 +124,10 @@ CLogProcessor::~CLogProcessor(void)
SAFE_DEL(m_codecStdinp);
}

// ===================================================
// Public Methods
// ===================================================

/*
* Start the process
*/
Expand Down Expand Up @@ -188,6 +201,9 @@ int CLogProcessor::exec(void)
}
}

// ===================================================
// Slots
// ===================================================
/*
* Force process to quit ASAP
*/
Expand Down Expand Up @@ -271,6 +287,75 @@ void CLogProcessor::readFromStdinp(void)
}
}

/*
* Process has finished
*/
void CLogProcessor::processFinished(int exitCode)
{
//Just to be sure (?)
m_process->waitForFinished();

//Process pending outputs
readFromStdout();
readFromStderr();

//Flush buffer contents
flushBuffers();

//Now return the exit code
m_exitCode = exitCode;
logString(QString().sprintf("Process has terminated (exit code: 0x%08X)", exitCode), CHANNEL_SYSMSG);
finishLog();

m_eventLoop->exit(m_exitCode);
}

/*
* STDIN reader has finished
*/
void CLogProcessor::readerFinished(void)
{
//Process pending outputs
readFromStdinp();

//Flush buffer contents
flushBuffers();

//Now return the exit code
logString("No more data available from STDIN (process has terminated)", CHANNEL_SYSMSG);
finishLog();

m_eventLoop->exit(0);
}

// ===================================================
// Private Methods
// ===================================================

/*
* FLush any pending data from buffer
*/
void CLogProcessor::flushBuffers(void)
{
if(m_logStdout && (!m_bufferStdout.isEmpty()))
{
logString(m_simplify ? m_bufferStdout.simplified() : m_bufferStdout, CHANNEL_STDOUT);
m_bufferStdout.clear();
}

if(m_logStderr && (!m_bufferStderr.isEmpty()))
{
logString(m_simplify ? m_bufferStderr.simplified() : m_bufferStderr, CHANNEL_STDERR);
m_bufferStderr.clear();
}

if(!m_bufferStdinp.isEmpty())
{
logString(m_simplify ? m_bufferStdinp.simplified() : m_bufferStdinp, CHANNEL_STDOUT);
m_bufferStdinp.clear();
}
}

/*
* Process data (decode and tokenize)
*/
Expand Down Expand Up @@ -322,8 +407,8 @@ void CLogProcessor::logString(const QString &data, const int channel)
return;
}

//Do not any empty strings!
if(data.isEmpty() || ((!m_verbose) && (channel == CHANNEL_SYSMSG)))
//Do not log any empty strings!
if(data.isEmpty() || ((m_logFormat == LOG_FORMAT_PLAIN) && (channel == CHANNEL_SYSMSG)))
{
return;
}
Expand All @@ -341,41 +426,40 @@ void CLogProcessor::logString(const QString &data, const int channel)
}
}

QChar chan;
QChar chanId;

switch(channel)
{
case CHANNEL_STDOUT:
chan = 'O';
chanId = 'O';
break;
case CHANNEL_STDERR:
chan = 'E';
chanId = 'E';
break;
case CHANNEL_STDINP:
chan = 'I';
chanId = 'I';
break;
case CHANNEL_SYSMSG:
chan = 'S';
chanId = 'S';
break;
default:
throw "Bad selection!";
}

static const QString format_date("yyyy-MM-dd");
static const QString format_time("hh:mm:ss");
static const QString format_date("yyyy-MM-dd"), format_time("hh:mm:ss");
QDateTime time = (m_logFormat == LOG_FORMAT_PLAIN) ? QDateTime() : QDateTime::currentDateTime();

if(m_htmlOutput)
{
QDateTime time = QDateTime::currentDateTime();
m_logFile->operator<<(QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td></tr>\r\n").arg(chan, time.toString(format_date), time.toString(format_time), escape(data)));
}
else if(m_verbose)
{
QDateTime time = QDateTime::currentDateTime();
m_logFile->operator<<(QString("[%1] [%2] [%3] %4\r\n").arg(chan, time.toString(format_date), time.toString(format_time), data));
}
else
switch(m_logFormat)
{
case LOG_FORMAT_VERBOSE:
m_logFile->operator<<(QString("[%1] [%2] [%3] %4\r\n").arg(chanId, time.toString(format_date), time.toString(format_time), data));
break;
case LOG_FORMAT_PLAIN:
m_logFile->operator<<(QString("%1\r\n").arg(data));
break;
case LOG_FORMAT_HTML:
QDateTime time = QDateTime::currentDateTime();
m_logFile->operator<<(QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td></tr>\r\n").arg(chanId, time.toString(format_date), time.toString(format_time), escape(data)));
}
}

Expand All @@ -389,18 +473,15 @@ void CLogProcessor::initializeLog(void)
return;
}

if(m_htmlOutput)
if((m_logFormat == LOG_FORMAT_HTML) && m_logIsEmpty)
{
m_logFile->operator<<("<!DOCTYPE html>\r\n");
m_logFile->operator<<("<html><head><title>Log File</title></head><body><table style=\"font-family:monospace\" border>\r\n");
m_logFile->operator<<("<tr><td>&nbsp;</td><td><b>Date</b></td><td><b>Time</b></td><td><b>Log Message</b></td></tr>\r\n");
}
else
if((m_logFormat == LOG_FORMAT_VERBOSE) && (!m_logIsEmpty))
{
if(!m_logIsEmpty)
{
logString("---", CHANNEL_SYSMSG);
}
logString("-----", CHANNEL_SYSMSG);
}

m_logInitialized = true;
Expand All @@ -416,79 +497,17 @@ void CLogProcessor::finishLog(void)
return;
}

if(m_htmlOutput)
if((m_logFormat == LOG_FORMAT_HTML) && m_logIsEmpty)
{
m_logFile->operator<<("</table></body></html>\r\n");
}

m_logFinished = true;
}


/*
* Process has finished
*/
void CLogProcessor::processFinished(int exitCode)
{
//Just to be sure (?)
m_process->waitForFinished();

//Process pending outputs
readFromStdout();
readFromStderr();

//Flush buffer contents
flushBuffers();

//Now return the exit code
m_exitCode = exitCode;
logString(QString().sprintf("Process has terminated (exit code: 0x%08X)", exitCode), CHANNEL_SYSMSG);
finishLog();

m_eventLoop->exit(m_exitCode);
}

/*
* STDIN reader has finished
*/
void CLogProcessor::readerFinished(void)
{
//Process pending outputs
readFromStdinp();

//Flush buffer contents
flushBuffers();

//Now return the exit code
logString("No more data available from STDIN (process has terminated)", CHANNEL_SYSMSG);
finishLog();

m_eventLoop->exit(0);
}

/*
* FLush any pending data from buffer
*/
void CLogProcessor::flushBuffers(void)
{
if(m_logStdout && (!m_bufferStdout.isEmpty()))
{
logString(m_simplify ? m_bufferStdout.simplified() : m_bufferStdout, CHANNEL_STDOUT);
m_bufferStdout.clear();
}

if(m_logStderr && (!m_bufferStderr.isEmpty()))
{
logString(m_simplify ? m_bufferStderr.simplified() : m_bufferStderr, CHANNEL_STDERR);
m_bufferStderr.clear();
}

if(!m_bufferStdinp.isEmpty())
{
logString(m_simplify ? m_bufferStdinp.simplified() : m_bufferStdinp, CHANNEL_STDOUT);
m_bufferStdinp.clear();
}
}
// ===================================================
// Setter methods
// ===================================================

/*
* Set which streams to capture
Expand All @@ -510,10 +529,9 @@ void CLogProcessor::setSimplifyStrings(const bool simplify)
/*
* Set verbose logging mode
*/
void CLogProcessor::setVerboseOutput(const bool verbose)
void CLogProcessor::setOutputFormat(const Format format)
{
m_verbose = verbose;
if(!verbose) m_htmlOutput = false;
m_logFormat = format;
}

/*
Expand Down Expand Up @@ -569,14 +587,9 @@ bool CLogProcessor::setTextCodecs(const char *inputCodec, const char *outputCode
return true;
}

/*
* Set html output
*/
void CLogProcessor::setHtmlOutput(const bool htmlOutput)
{
m_htmlOutput = htmlOutput;
if(htmlOutput) m_verbose = true;
}
// ===================================================
// Misc Stuff
// ===================================================

/*
* Escape (some) HTML characters
Expand Down
22 changes: 17 additions & 5 deletions src/LogProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,28 @@ class CLogProcessor : public QObject
CLogProcessor(QFile &logFile);
~CLogProcessor(void);

//Start logging
bool startProcess(const QString &program, const QStringList &arguments);
bool startStdinProcessing(void);

//Event processing
int exec(void);

//Types
typedef enum
{
LOG_FORMAT_PLAIN = 0,
LOG_FORMAT_VERBOSE = 1,
LOG_FORMAT_HTML = 2
}
Format;

//Setter methods
void setCaptureStreams(const bool captureStdout, const bool captureStderr);
void setSimplifyStrings(const bool simplify);
void setVerboseOutput(const bool verbose);
void setFilterStrings(const QString &regExpKeep, const QString &regExpSkip);
bool setTextCodecs(const char *inputCodec, const char *outputCodec);
void setHtmlOutput(const bool htmlOutput);
void setOutputFormat(const Format format);

public slots:
void forceQuit(const bool silent = false);
Expand Down Expand Up @@ -80,9 +91,10 @@ private slots:
bool m_logStdout;
bool m_logStderr;
bool m_simplify;
bool m_logIsEmpty;
bool m_verbose;
bool m_htmlOutput;

const bool m_logIsEmpty;

Format m_logFormat;

QTextDecoder *m_codecStdout;
QTextDecoder *m_codecStderr;
Expand Down
Loading

0 comments on commit 4ce9c3e

Please sign in to comment.