|
From: <sv...@va...> - 2010-01-27 22:55:06
|
Author: cerion
Date: 2010-01-27 22:54:53 +0000 (Wed, 27 Jan 2010)
New Revision: 472
Log:
Vk now supports running a valgrind process.
That process' stdout/err are forwarded to vk's stdout/err respectively.
However, stdin is not forwarded. If this is a problem for people, we'll deal with it then.
Still needs lots of errorchecks, +++.
Added:
branches/valkyrie_qt4port/utils/vk_logpoller.cpp
branches/valkyrie_qt4port/utils/vk_logpoller.h
Modified:
branches/valkyrie_qt4port/mainwindow.cpp
branches/valkyrie_qt4port/mainwindow.h
branches/valkyrie_qt4port/objects/helgrind_object.h
branches/valkyrie_qt4port/objects/memcheck_object.cpp
branches/valkyrie_qt4port/objects/memcheck_object.h
branches/valkyrie_qt4port/objects/tool_object.cpp
branches/valkyrie_qt4port/objects/tool_object.h
branches/valkyrie_qt4port/objects/valkyrie_object.cpp
branches/valkyrie_qt4port/objects/valkyrie_object.h
branches/valkyrie_qt4port/toolview/vglogview.cpp
branches/valkyrie_qt4port/toolview/vglogview.h
branches/valkyrie_qt4port/utils/vk_utils.h
branches/valkyrie_qt4port/valkyrie.pro
Modified: branches/valkyrie_qt4port/mainwindow.cpp
===================================================================
--- branches/valkyrie_qt4port/mainwindow.cpp 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/mainwindow.cpp 2010-01-27 22:54:53 UTC (rev 472)
@@ -33,6 +33,7 @@
#include "help/help_context.h"
#include "help/help_urls.h"
#include "options/vk_option.h"
+#include "objects/tool_object.h"
#include "utils/vk_config.h"
#include "utils/vk_messages.h"
#include "utils/vk_utils.h"
@@ -399,12 +400,13 @@
nextView = nextTool->createView( this );
vk_assert( nextView != 0 );
-
/* TODO
- connect( nextTool, SIGNAL(running(bool)),
- this, SLOT(updateButtons(bool)) );
- connect( nextTool, SIGNAL(message(QString)),
- this, SLOT(setStatus(QString)) );
+ connect( nextTool, SIGNAL(running(bool)),
+ this, SLOT(updateButtons(bool)) );
+*/
+ connect( nextTool, SIGNAL(message(QString)),
+ this, SLOT(setStatus(QString)) );
+/* TODO
connect( this, SIGNAL(toolbarLabelsToggled(bool)),
nextView, SLOT(toggleToolbarLabels(bool)) );
*/
@@ -421,6 +423,7 @@
toolViewStack->raiseView( nextView );
setToggles( toolId );
+ updateVgFlags();
}
@@ -567,6 +570,27 @@
/*!
+ Called by this->showToolView(),
+ and optionsDlg::flagsChanged() signal
+*/
+void MainWindow::updateVgFlags()
+{
+ // update valkyrie's flags: if there's a visible ToolView
+ if ( toolViewStack->isVisible() )
+ valkyrie->updateVgFlags( toolViewStack->currentToolId() );
+
+//TODO: maybe.
+#if 0
+ // update flags display
+ if ( m_flagsLabel->isVisible() ) {
+ showFlagsWidget( true );
+ }
+#endif
+}
+
+
+
+/*!
Calls showToolView() for a chosen valgrind tool.
This slot is called by a trigger of the tool actionGroup, which is
@@ -604,12 +628,16 @@
optionsDialog->activateWindow();
#else
VkOptionsDialog optionsDlg( this );
+
+ // let the flags widget know that flags may have been modified
+ connect( &optionsDlg, SIGNAL(flagsChanged()),
+ this, SLOT(updateVgFlags()) );
+
optionsDlg.exec();
#endif
}
-
/*!
Run the valgrind tool process.
*/
@@ -623,7 +651,7 @@
vk_assert( procId >= 0 );
// don't come in here if there's no current view
- if ( toolViewStack->isVisible() == 0 ) {
+ if ( !toolViewStack->isVisible() ) {
//This should never happen... assert?
cerr << "Error: No toolview visible!" << endl;
return;
@@ -666,23 +694,25 @@
actProcess_Run->setEnabled( false );
actProcess_Stop->setEnabled( true );
-#if 0
- /* don't come in here if there's no current view */
- if ( m_viewStack->visible() == 0 )
+ // don't come in here if there's no current view
+ if ( !toolViewStack->isVisible() )
return;
/* valkyrie may have been started with no executable
specified. if so, show prefsWindow + msgbox */
- if ( vkConfig->rdEntry("binary","valkyrie").isEmpty() ) {
+ if ( vkConfig->value( "valkyrie/binary").toString().isEmpty() ) {
+//TODO
+ cerr << "Error: no binary specified!" << endl;
+#if 0
showOptionsWindow( Valkyrie::ID_VALKYRIE );
- vkInfo( m_optionsWin, "Run Valgrind",
+ vkInfo( optionsWin, "Run Valgrind",
"Please enter the path to the executable "
"you wish to run, together with any arguments");
+#endif
return;
}
- run( VkRunState::VALGRIND );
-#endif
+ runTool( TOOL::PROC_VALGRIND );
}
Modified: branches/valkyrie_qt4port/mainwindow.h
===================================================================
--- branches/valkyrie_qt4port/mainwindow.h 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/mainwindow.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -73,6 +73,7 @@
void openAboutVk();
void openAboutLicense();
void openAboutSupport();
+ void updateVgFlags();
private:
Valkyrie* valkyrie;
Modified: branches/valkyrie_qt4port/objects/helgrind_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/helgrind_object.h 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/objects/helgrind_object.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -55,8 +55,10 @@
int checkOptArg( int optid, QString& argval );
VkOptionsPage* createVkOptionsPage();
- bool start( int procId, QStringList vgflags ) { return true; }
+ bool start( int procId, QStringList vgflags ) { return false; }
void stop() {}
+
+ bool runValgrind( QStringList vgflags ) { return false; }
};
Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-01-27 22:54:53 UTC (rev 472)
@@ -24,29 +24,33 @@
#include "objects/valkyrie_object.h"
#include "utils/vk_config.h"
#include "utils/vk_messages.h"
+#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc.
#include "utils/vglogreader.h"
#include "options/vk_option.h" // PERROR* and friends
//#include "vk_file_utils.h" // FileCopy()
-#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc.
#include <QApplication>
+#include <QDir>
+#include <QTimer>
+#define TIMEOUT_STOPPROC 2000 // msec until stop process
+#define TIMEOUT_KILLPROC 2000 // msec until kill process (after tried to stop)
+
+
/*!
class Memcheck
*/
Memcheck::Memcheck()
: ToolObject( "memcheck", VGTOOL::ID_MEMCHECK )
{
-#if 0
/* init vars */
- m_fileSaved = true;
- m_vgproc = 0;
- m_vgreader = 0;
- m_logpoller = new VkLogPoller( this, "memcheck logpoller" );
- connect( m_logpoller, SIGNAL(logUpdated()),
+ fileSaved = true;
+ vgproc = 0;
+ vgreader = 0;
+ logpoller = new VkLogPoller( this, "memcheck logpoller" );
+ connect( logpoller, SIGNAL(logUpdated()),
this, SLOT(readVgLog()) );
-#endif
setupOptions();
}
@@ -54,26 +58,25 @@
Memcheck::~Memcheck()
{
-#if 0
- if (m_vgproc) {
- m_vgproc->disconnect(); /* so no signal calling processDone() */
- if (m_vgproc->isRunning()) {
- m_vgproc->stop();
+ if (vgproc) {
+ vgproc->disconnect(); // so no signal calling processDone()
+ if ( vgproc->state() != QProcess::NotRunning ) {
+ vgproc->terminate();
+ //TODO: wait a short while before deleting?
}
- delete m_vgproc;
- m_vgproc = 0;
+ delete vgproc;
+ vgproc = 0;
}
- if (m_vgreader) {
- delete m_vgreader;
- m_vgreader = 0;
+ if (vgreader) {
+ delete vgreader;
+ vgreader = 0;
}
- /* m_logpoller deleted by it's parent: 'this' */
+ // logpoller deleted by it's parent: 'this'
- /* unsaved log... delete our temp file */
- if (!m_fileSaved && !m_saveFname.isEmpty())
- QDir().remove( m_saveFname );
-#endif
+ // unsaved log... delete our temp file
+ if (!fileSaved && !saveFname.isEmpty())
+ QDir().remove( saveFname );
}
@@ -267,16 +270,16 @@
toolView = new MemcheckView( parent );
#if 0
- /* signals view --> tool */
- connect( m_view, SIGNAL(saveLogFile()),
+ // signals tool_view --> tool_obj
+ connect( toolView, SIGNAL(saveLogFile()),
this, SLOT(fileSaveDialog()) );
- /* signals tool --> view */
+ // signals tool_obj --> tool_view
connect( this, SIGNAL(running(bool)),
- m_view, SLOT(setState(bool)) );
+ toolView, SLOT(setState(bool)) );
+#endif
+ setProcessId( TOOL::PROC_NONE );
- setRunState( VkRunState::STOPPED );
-#endif
return toolView;
}
@@ -284,8 +287,7 @@
/* outputs a message to the status bar. */
void Memcheck::statusMsg( QString hdr, QString msg )
{
-//TODO
-// emit message( hdr + ": " + msg );
+ emit message( hdr + ": " + msg );
}
@@ -299,7 +301,7 @@
/* if current process is not yet finished, ask user if they really
want to close */
if ( isRunning() ) {
- int ok = vkQuery( view(), "Process Running", "&Abort;&Cancel",
+ int ok = vkQuery( getToolView(), "Process Running", "&Abort;&Cancel",
"<p>The current process is not yet finished.</p>"
"<p>Do you want to abort it ?</p>" );
/* Note: process may have finished while waiting for user */
@@ -328,8 +330,8 @@
/* currently loaded / parsed stuff is saved to tmp file - ask user
if they want to save it to a 'real' file */
- if ( !m_fileSaved ) {
- int ok = vkQuery( view(), "Unsaved File",
+ if ( !fileSaved ) {
+ int ok = vkQuery( getToolView(), "Unsaved File",
"&Save;&Discard;&Cancel",
"<p>The current output is not saved, "
" and will be deleted.<br/>"
@@ -345,8 +347,8 @@
} else if ( ok == MsgBox::vkCancel ) { /* procrastinate */
return false;
} else { /* discard */
- QFile::remove( m_saveFname );
- m_fileSaved = true;
+ QFile::remove( saveFname );
+ fileSaved = true;
}
}
#endif
@@ -359,20 +361,18 @@
cerr << "Memcheck::start(): " << procId << endl;
vk_assert( procId > MEMCHECK_VIEW::PROC_NOPROC );
-
-//TODO
-// vk_assert( rs != VkRunState::STOPPED );
-// vk_assert( !isRunning() );
+ vk_assert( procId > TOOL::PROC_NONE );
+ vk_assert( !isRunning() );
bool ok = false;
switch ( procId ) {
- case MEMCHECK_VIEW::PROC_RUN_VALGRIND:
+ case TOOL::PROC_VALGRIND:
ok = runValgrind( vgflags );
break;
- case MEMCHECK_VIEW::PROC_PARSE_LOGFILE:
+ case MEMCHECK::PROC_PARSE_LOG:
ok = parseLogFile();
break;
-//TODO: maybe.
+//TODO: maybe someday.
// case merge: ok = mergeLogFiles(); break;
default:
vk_assert_never_reached();
@@ -382,47 +382,70 @@
}
-/* stop a process
- - doesn't exit until process stopped.
- - may take some time for process to respond: too much time and it
- just gets terminated. */
+/*!
+ Stop a process.
+ Try to be nice, but in case doesn't work, setup timer to guarantee it dies.
+//TODO: Perhaps the view want's to hang around and wait until process is dead. but that's up to the view.
+*/
void Memcheck::stop()
{
-#if 0
if ( !isRunning() )
return;
- switch ( runState() ) {
- case VkRunState::VALGRIND: {
- if (m_vgproc && m_vgproc->isRunning() )
- m_vgproc->stop(); /* signal -> processDone() */
+ // whatever else we do, stop trying to read from the log.
+ if ( logpoller )
+ logpoller->stop();
+
+ switch ( getProcessId() ) {
+ case TOOL::PROC_VALGRIND: {
+ if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) {
+ vkPrint("Memcheck::stop(): process starting/running: terminate.");
+
+ vgproc->terminate(); // if & when succeeds: signal -> processDone()
+
+ // in case doesn't want to stop, start timer to really kill it off.
+ QTimer::singleShot( TIMEOUT_KILLPROC, this, SLOT( killProc() ) );
+ }
+ else {
+ vkPrint("Memcheck::stop(): process was already stopped.");
+ }
} break;
- case VkRunState::TOOL1: { /* parse log */
- /* TODO: make log parsing a VkProcess. This will allow
- - valkyrie to stay responsive
- - the ability to interrupt the process if taking too long */
+ case MEMCHECK::PROC_PARSE_LOG: { // parse log
+ // TODO
VK_DEBUG("TODO: Memcheck::stop(parse log)" );
} break;
- case VkRunState::TOOL2: { /* merge logs */
- if (m_vgproc && m_vgproc->isRunning() )
- m_vgproc->stop(); /* signal -> processDone() */
+#if 0
+ case TODO: { // merge logs
+ if (vgproc && vgproc->isRunning() )
+ vgproc->stop(); // signal -> processDone()
} break;
-
+#endif
default:
vk_assert_never_reached();
}
- /* spin until done */
- while ( isRunning() )
- qApp->processEvents();
-#endif
-
return;
}
+/*!
+ Kills a process immediately
+ - only called as a result of kill timer timeout
+*/
+void Memcheck::killProcess()
+{
+ if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) {
+vkPrint("Memcheck::killProcess(): kill the process");
+ vgproc->kill(); // process will die, then signal -> processDone()
+ }
+ else {
+vkPrint("Memcheck::killProcess(): process already stopped.");
+ }
+}
+
+
/* If --vg-opt=<arg> was specified on the cmd-line, called by
valkyrie->runTool(); if set via the run-button in the gui,
then MainWindow::run() calls valkyrie->runTool().
@@ -431,41 +454,42 @@
*/
bool Memcheck::runValgrind( QStringList vgflags )
{
-#if 0
- m_saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() )
- + "mc_log", "xml" );
- vk_assert( !m_saveFname.isEmpty() );
+//TODO: saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) + "mc_log", "xml" );
+ saveFname = "./mc_log.xml";
+ vk_assert( !saveFname.isEmpty() );
- vgflags.insert( ++(vgflags.begin()), ("--log-file=" + m_saveFname) );
+ vgflags.insert( ++(vgflags.begin()), ("--log-file=" + saveFname) );
+ vgflags.insert( ++(vgflags.begin()), "--xml=yes" );
- setRunState( VkRunState::VALGRIND );
- m_fileSaved = false;
+ setProcessId( TOOL::PROC_VALGRIND );
+ fileSaved = false;
statusMsg( "Memcheck", "Running ... " );
bool ok = startProcess( vgflags );
if (!ok) {
statusMsg( "Memcheck", "Failed" );
- m_fileSaved = true;
- setRunState( VkRunState::STOPPED );
+ fileSaved = true;
+ setProcessId( TOOL::PROC_NONE );
}
+
return ok;
-#endif
- return true;
}
-/* Parse log file given by [valkyrie::view-log] entry.
- Called by valkyrie->runTool() if cmdline --view-log=<file> specified.
- MemcheckView::openLogFile() if gui parse-log selected.
- If 'checked' == true, file perms/format has already been checked */
+/*!
+ Parse log file given by [valkyrie::view-log] entry.
+ Called by valkyrie->runTool() if cmdline --view-log=<file> specified.
+ MemcheckView::openLogFile() if gui parse-log selected.
+ If 'checked' == true, file perms/format has already been checked
+*/
bool Memcheck::parseLogFile()
{
vk_assert( getToolView() != 0 );
//TODO: pass this via flags from the toolview, or something.
QString log_file = vkConfig->value( "valkyrie/view-log" ).toString();
-// statusMsg( "Parsing", log_file );
+ statusMsg( "Parsing", log_file );
//TODO: file checks
#if 0
@@ -473,7 +497,7 @@
int errval = PARSED_OK;
QString ret_file = fileCheck( &errval, log_file, true, false );
if ( errval != PARSED_OK ) {
- vkError( view(), "File Error", "%s: \n\"%s\"",
+ vkError( getToolView(), "File Error", "%s: \n\"%s\"",
parseErrString(errval),
escapeEntities(log_file).latin1() );
return false;
@@ -482,8 +506,8 @@
#endif
// fileSaved true, 'cos we're just parsing an existing file
-// m_fileSaved = true;
-// setRunState( VkRunState::TOOL1 );
+ fileSaved = true;
+ setProcessId( MEMCHECK::PROC_PARSE_LOG );
// Could be a very large file, so at least get ui up-to-date now
qApp->processEvents( QEventLoop::AllEvents, 1000/*max msecs*/ );
@@ -498,15 +522,14 @@
"<p>%s</p>", qPrintable( escapeEntities(hnd->fatalMsg()) ) );
}
-#if 0
if (success) {
- m_saveFname = log_file;
+ saveFname = log_file;
statusMsg( "Loaded", log_file );
} else {
statusMsg( "Parse failed", log_file );
}
- setRunState( VkRunState::STOPPED );
-#endif
+ setProcessId( TOOL::PROC_NONE );
+
return success;
}
@@ -520,31 +543,32 @@
*/
bool Memcheck::mergeLogFiles()
{
+//TODO. maybe.
#if 0
QString fname_logList = vkConfig->rdEntry( "merge", "valkyrie" );
statusMsg( "Merging logs in file-list", fname_logList );
- m_saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() )
- + "mc_merged", "xml" );
- vk_assert( !m_saveFname.isEmpty() );
+ saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() )
+ + "mc_merged", "xml" );
+ vk_assert( !saveFname.isEmpty() );
QStringList flags;
flags << vkConfig->rdEntry( "merge-exec","valkyrie");
flags << "-f";
flags << fname_logList;
flags << "-o";
- flags << m_saveFname;
+ flags << saveFname;
- setRunState( VkRunState::TOOL2 );
- m_fileSaved = false;
+ setProcessId( VkRunState::TOOL2 );
+ fileSaved = false;
statusMsg( "Merge Logs", "Running ... " );
bool ok = startProcess( flags );
if (!ok) {
statusMsg( "Merge Logs", "Failed" );
- m_fileSaved = true;
- setRunState( VkRunState::STOPPED );
+ fileSaved = true;
+ setProcessId( VkRunState::STOPPED );
}
return ok;
#endif
@@ -557,208 +581,225 @@
*/
bool Memcheck::startProcess( QStringList flags )
{
+ QString program = flags.at( 0 );
+ QStringList args = flags.mid(1);
+
// vkPrint("Memcheck::startProcess()");
- // for ( unsigned int i=0; i<flags.count(); i++ )
- // vkPrint("flag[%d] --> %s", i, flags[i].latin1() );
+ for ( int i=0; i<flags.count(); i++ )
+ vkPrint("flag[%d] --> %s", i, qPrintable( flags[i] ) );
vk_assert( getToolView() != 0 );
-#if 0
- /* new m_vgreader - view() may be recreated, so need up-to-date ptr */
- vk_assert( m_vgreader == 0 );
- m_vgreader = new VgLogReader( view()->vgLogPtr() );
+ // new vgreader - view may have been recreated, so need up-to-date ptr
+ vk_assert( vgreader == 0 );
+ vgreader = new VgLogReader( getToolView()->vgLogPtr() );
- /* start the log parse - nothing written yet tho */
- if (!m_vgreader->parse( m_saveFname, true )) {
- QString errMsg = m_vgreader->handler()->fatalMsg();
- VK_DEBUG("m_vgreader failed to start parsing empty log\n");
- vkError( view(), "Process Startup Error",
+ // start the log parse - nothing written yet tho.
+ if (!vgreader->parse( saveFname, true )) {
+ QString errMsg = vgreader->handler()->fatalMsg();
+ VK_DEBUG("vgreader failed to start parsing empty log\n");
+ vkError( getToolView(), "Process Startup Error",
"<p>Failed to start XML parser:<br>%s</p>",
- errMsg.ascii() );
+ qPrintable( errMsg ) );
goto failed_startup;
}
- /* start a new process, listening on exit signal */
- vk_assert( m_vgproc == 0 );
- m_vgproc = new VKProcess( flags, this );
- connect( m_vgproc, SIGNAL(processExited()),
- this, SLOT(processDone()) );
+ // start a new process, listening on exit signal
+ vk_assert( vgproc == 0 );
+ vgproc = new QProcess( this->toolView );
+ connect( vgproc, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(processDone(int, QProcess::ExitStatus)) );
- /* don't need to talk/listen to forked process,
- so don't let it hijack stdin/out/err for socket fd's */
- m_vgproc->setCommunication( 0 );
+ // forward vg process stdout/err to our stdout/err respectively
+ vgproc->setProcessChannelMode( QProcess::ForwardedChannels );
- /* set working directory */
- m_vgproc->setWorkingDirectory(
- QDir( vkConfig->rdEntry( "working-dir", "valkyrie" ) ) );
+ // set working directory
+ vgproc->setWorkingDirectory( vkConfig->value( "valkyrie/working-dir" ).toString() );
- if ( !m_vgproc->start() ) {
+ // start running process
+ vgproc->start( program, args );
+
+//TODO: call vgproc->waitForStarted(), or sthgn with a timeout, and then error to user...
+#if 0
VK_DEBUG("process failed to start");
- QString path_errmsg = (runState() == VkRunState::VALGRIND)
- ? "Please verify the path to Valgrind in Options::Valkyrie."
- : ""; /* TODO: same for vk_logmerge... and provide option widgets to update path... */
- vkError( view(), "Process Startup Error",
- "<p>Failed to start process:<br>%s<br><br>%s</p>",
- flags.join(" ").latin1(),
- path_errmsg.latin1() );
+ vkError( getToolView(), "Process Startup Error",
+ "<p>Failed to start process:<br>%s<br><br>"
+ "Please verify the path to Valgrind in Options::Valkyrie.</p>",
+ qPrintable( flags.join(" ") ) );
goto failed_startup;
}
+#endif
- /* poll log for latest data */
- if (!m_logpoller->start()) {
- QString errMsg = m_vgreader->handler()->fatalMsg();
- VK_DEBUG("m_logpoller failed to start\n");
- vkError( view(), "Process Startup Error",
- "<p>Failed to start log poller.</p>" );
- goto failed_startup;
- }
+ // poll log for latest data
+ logpoller->start();
- // vkPrint(" - END MC::startProcess()" );
+vkPrint(" - END MC::startProcess()" );
return true;
failed_startup:
- VK_DEBUG("failed_startup: '%s'", flags.join(" ").latin1());
- if (m_logpoller != 0) {
- m_logpoller->stop();
+ VK_DEBUG("failed_startup: '%s'", qPrintable( flags.join(" ") ));
+ if (logpoller != 0) {
+ logpoller->stop();
}
- if (m_vgreader != 0) {
- delete m_vgreader;
- m_vgreader = 0;
+ if (vgreader != 0) {
+ delete vgreader;
+ vgreader = 0;
}
- if (m_vgproc != 0) {
- delete m_vgproc;
- m_vgproc = 0;
+ if (vgproc != 0) {
+ delete vgproc;
+ vgproc = 0;
}
return false;
-#endif
- return true;
}
-/* Process exited:
- - self / external signal / user via 'stop()' /
- - terminated from readVgLog because of an xml parse error
- Stops logfile polling, checks xml parsing for errors,
- checks exitstatus, cleans up.
+/*!
+ Process exited:
+ - self / external signal / user via 'stop()' /
+ - terminated from readVgLog because of an xml parse error
+ Stops logfile polling, checks xml parsing for errors,
+ checks exitstatus, cleans up.
*/
-void Memcheck::processDone()
+void Memcheck::processDone( int exitCode, QProcess::ExitStatus exitStatus )
{
-#if 0
+ cerr << "Memcheck::processDone( " << exitCode << ", " << exitStatus << " )" << endl;
+
// vkPrint("Memcheck::processDone()");
- vk_assert( m_vgproc != 0 );
- vk_assert( m_vgreader != 0 );
- vk_assert( m_logpoller != 0 );
+ vk_assert( vgproc != 0 );
+ vk_assert( vgreader != 0 );
+ vk_assert( logpoller != 0 );
bool runError = false;
- /* stop polling logfile ------------------------------------------ */
- m_logpoller->stop();
+ // stop polling logfile ------------------------------------------
+ logpoller->stop();
- /* deal with log reader ------------------------------------------ */
- /* if not finished && no error, try reading log data one last time */
- if (!m_vgreader->handler()->finished() &&
- m_vgreader->handler()->fatalMsg().isEmpty())
+ // deal with log reader ------------------------------------------
+ // if not finished && no error, try reading log data one last time
+ if (!vgreader->handler()->finished() &&
+ vgreader->handler()->fatalMsg().isEmpty())
readVgLog();
- /* did log parsing go ok? */
- QString fatalMsg = m_vgreader->handler()->fatalMsg();
+ // did log parsing go ok?
+ QString fatalMsg = vgreader->handler()->fatalMsg();
if ( !fatalMsg.isEmpty() ) {
- /* fatal log error... */
+ // fatal log error...
runError = true;
// vkPrint(" - Memcheck::processDone(): fatal error");
- if (runState() == VkRunState::VALGRIND) {
+ if (getProcessId() == TOOL::PROC_VALGRIND) {
statusMsg( "Memcheck", "Error parsing output log" );
- vkError( view(), "XML Parse Error",
+ vkError( getToolView(), "XML Parse Error",
"<p>Error parsing Valgrind XML output:<br>%s</p>",
- str2html( fatalMsg ).latin1() );
+ qPrintable( str2html( fatalMsg ) ) );
} else {
+ vk_assert_never_reached();
+//TODO. maybe
+#if 0
statusMsg( "Merge Logs", "Error parsing output log" );
- vkError( view(), "Parse Error",
+ vkError( getToolView(), "Parse Error",
"<p>Error parsing output log</p>" );
+#endif
}
- } else if ( !m_vgreader->handler()->finished() ) {
+ } else if ( !vgreader->handler()->finished() ) {
/* no fatal error, but STILL not reached end of log, either:
- valgrind xml output not completed properly
- merge failed */
runError = true;
// vkPrint(" - Memcheck::processDone(): parsing STILL not finished");
-
- if (runState() == VkRunState::VALGRIND) {
+
+ if (getProcessId() == TOOL::PROC_VALGRIND) {
statusMsg( "Memcheck", "Error - incomplete output log" );
- vkError( view(), "XML Parse Error",
+ vkError( getToolView(), "XML Parse Error",
"<p>Valgrind XML output is incomplete</p>" );
} else {
+ vk_assert_never_reached();
+//TODO. maybe.
+#if 0
statusMsg( "Merge Logs", "Error - incomplete output log" );
- vkError( view(), "Parse Error",
+ vkError( getToolView(), "Parse Error",
"<p>Failed to parse merge result</p>" );
+#endif
}
-
}
- /* check process exit status
- - valgrind might have bombed ---------------------------------- */
- bool exitStatus = m_vgproc->exitStatus();
- if (exitStatus != 0) {
+
+ // check process exit status - valgrind might have bombed
+ if ( exitStatus == QProcess::NormalExit && exitCode == 0 ) {
+ // vkPrint(" - Memcheck::processDone(): process exited ok");
+ } else {
// vkPrint(" - Memcheck::processDone(): process failed (%d)", exitStatus);
- if (runState() == VkRunState::VALGRIND) {
- vkError( view(), "Run Error",
- "<p>Process exited with return value %d.<br> \
+ if (getProcessId() == TOOL::PROC_VALGRIND) {
+ vkError( getToolView(), "Run Error",
+ "<p>Process %s, with return value %d.<br> \
This is likely to simply be the client program \
return value. If, however, you suspect Valgrind \
itself may have crashed, please click 'OK', then \
- 'Save Log' and examine for details.</p>", exitStatus);
+ 'Save Log' and examine for details.</p>",
+ (exitStatus == QProcess::NormalExit) ? "exited normally" : "crashed",
+ exitCode );
} else {
- vkError( view(), "Parse Error",
+ vk_assert_never_reached();
+//TODO: maybe.
+#if 0
+ vkError( getToolView(), "Parse Error",
"<p>Merge process exited with return value %d.<br> \
Please check the terminal for error messages.</p>",
exitStatus);
+#endif
}
- } else {
- // vkPrint(" - Memcheck::processDone(): process exited ok");
}
- /* cleanup ------------------------------------------------------- */
- delete m_vgreader;
- m_vgreader = 0;
- delete m_vgproc;
- m_vgproc = 0;
+ // cleanup -------------------------------------------------------
+ delete vgreader;
+ vgreader = 0;
+ delete vgproc;
+ vgproc = 0;
- /* we're done. --------------------------------------------------- */
- if (!runError) { /* (else we've already set an status error message) */
- if (runState() == VkRunState::VALGRIND)
+ // we're done. ---------------------------------------------------
+ if (!runError) { // (else we've already set an status error message)
+ if (getProcessId() == TOOL::PROC_VALGRIND) {
statusMsg( "Memcheck", "Finished" );
- else
- statusMsg( "Merge Logs", "Finished" );
+ } else {
+ vk_assert_never_reached();
+//TODO: maybe
+// statusMsg( "Merge Logs", "Finished" );
+ }
}
- setRunState( VkRunState::STOPPED );
+// setProcessId( TOOL::PROC_NONE );
// vkPrint("Memcheck::processDone(): DONE.\n");
-#endif
}
/* Read memcheck / logmerge xml output
Called by
- - m_logpoller signals
+ - logpoller signals
- processDone() if one last data read needed.
*/
void Memcheck::readVgLog()
{
-#if 0
- // vkPrint("Memcheck::readVgLog()");
- vk_assert( view() != 0 );
- vk_assert( m_vgreader != 0 );
- vk_assert( m_vgproc != 0 );
+vkPrint("Memcheck::readVgLog()");
+ vk_assert( getToolView() != 0 );
+ vk_assert( vgreader != 0 );
+ vk_assert( vgproc != 0 );
qApp->processEvents();
- /* Try reading some more data */
- if ( m_vgreader && !m_vgreader->parseContinue()) {
- /* Parsing failed: stop m_vgproc, if running */
- if ( m_vgproc && m_vgproc->isRunning())
- m_vgproc->stop(); /* signal -> processDone() */
+ // starting or dead -> get out of here.
+ if ( vgproc->state() != QProcess::Running )
+ return;
+
+ // Try reading some more data. By failure, stop process.
+ if ( vgreader && !vgreader->parseContinue()) {
+vkPrint("Memcheck::readVgLog(): Parsing Failed. Stopping process after timeout");
+
+ // stop trying to read from the log.
+ logpoller->stop();
+
+//TODO: necessary?
+ // give process a little time to finishe before we stop it.
+ QTimer::singleShot( TIMEOUT_STOPPROC, this, SLOT( stop() ) );
}
-#endif
}
@@ -783,7 +824,7 @@
if ( fname.isEmpty() ) {
/* Start save-dialog in User-configured default log dir*/
QString start_path = vkConfig->rdEntry( "default-logdir", "valkyrie" );
- fname = dlg.getSaveFileName( start_path, flt, view(), "fsdlg", cptn );
+ fname = dlg.getSaveFileName( start_path, flt, getToolView(), "fsdlg", cptn );
if ( fname.isEmpty() )
return false;
}
@@ -791,7 +832,7 @@
/* try to save file until succeed, or user Cancels */
while ( !saveParsedOutput( fname ) ) {
QString start_path = QFileInfo( fname ).dirPath();
- fname = dlg.getSaveFileName( start_path, flt, view(), "fsdlg", cptn );
+ fname = dlg.getSaveFileName( start_path, flt, getToolView(), "fsdlg", cptn );
if ( fname.isEmpty() ) /* Cancelled */
return false;
}
@@ -800,13 +841,13 @@
}
/* Save to file
- - we already have everything in m_saveFname logfile, so just copy that
+ - we already have everything in saveFname logfile, so just copy that
*/
bool Memcheck::saveParsedOutput( QString& fname )
{
#if 0
//vkPrint("saveParsedOutput(%s)", fname.latin1() );
- vk_assert( view() != 0 );
+ vk_assert( getToolView() != 0 );
vk_assert( !fname.isEmpty() );
/* make sure path is absolute */
@@ -814,7 +855,7 @@
/* if this filename already exists, check if we should over-write it */
if ( QFile::exists( fname ) ) {
- int ok = vkQuery( view(), 2, "Overwrite File",
+ int ok = vkQuery( getToolView(), 2, "Overwrite File",
"<p>Over-write existing file '%s' ?</p>",
fname.latin1() );
if ( ok == MsgBox::vkNo ) {
@@ -825,38 +866,38 @@
/* save log (=copy/rename) */
bool ok;
- if (!m_fileSaved) {
- /* first save after a run, so just rename m_saveFname => fname */
+ if (!fileSaved) {
+ /* first save after a run, so just rename saveFname => fname */
if (0) vkPrint("renaming: '%s' -> '%s'",
- m_saveFname.latin1(), fname.latin1() );
- if (m_saveFname != fname) {
- ok = FileCopy( m_saveFname, fname );
+ saveFname.latin1(), fname.latin1() );
+ if (saveFname != fname) {
+ ok = FileCopy( saveFname, fname );
if (ok)
- ok = QDir().remove( m_saveFname );
+ ok = QDir().remove( saveFname );
} else {
ok = true; // no need to do anything
}
// OLD:
- //ok = QDir().rename( m_saveFname, fname );
+ //ok = QDir().rename( saveFname, fname );
// but we can't just rename, because that fails when the src
// and dst files are in different partitions. The longwinded
// but more reliable solution is to copy and then delete the
// original.
} else {
- /* we've saved once already: must now copy m_saveFname => fname */
+ /* we've saved once already: must now copy saveFname => fname */
if (0) vkPrint("copying: '%s' -> '%s'",
- m_saveFname.latin1(), fname.latin1() );
- ok = FileCopy( m_saveFname, fname );
+ saveFname.latin1(), fname.latin1() );
+ ok = FileCopy( saveFname, fname );
}
if (ok) {
- m_saveFname = fname;
- m_fileSaved = true;
- statusMsg( "Saved", m_saveFname );
+ saveFname = fname;
+ fileSaved = true;
+ statusMsg( "Saved", saveFname );
} else {
/* nogo: return and try again */
- vkInfo( view(), "Save Failed",
+ vkInfo( getToolView(), "Save Failed",
"<p>Failed to save file to '%s'", fname.latin1() );
- statusMsg( "Failed Save", m_saveFname );
+ statusMsg( "Failed Save", saveFname );
}
return ok;
#endif
Modified: branches/valkyrie_qt4port/objects/memcheck_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/memcheck_object.h 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/objects/memcheck_object.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -21,19 +21,17 @@
#ifndef __MEMCHECK_OBJECT_H
#define __MEMCHECK_OBJECT_H
-
#include "objects/tool_object.h"
-#include "toolview/memcheckview.h"
#include "options/memcheck_options_page.h"
+#include "toolview/memcheckview.h"
+#include "utils/vglogreader.h"
+#include "utils/vk_logpoller.h"
-//#include "vk_logpoller.h"
-//#include "vglogreader.h"
-//#include "vk_process.h"
+#include <QProcess>
+#include <QStringList>
-//TODO
-
// ============================================================
namespace MEMCHECK {
@@ -59,10 +57,9 @@
Tools can run different processes
*/
enum mcProcessId {
- PROC_NOPROC = -1,
- PROC_RUN_VALGRIND,
- PROC_PARSE_LOGFILE,
- NUM_PROCS
+ PROC_PARSE_LOG = TOOL::PROC_TOOL_NONE+1,
+ // Any other process id's go here.
+ PROC_MAX = TOOL::PROC_MAX
};
}
@@ -85,7 +82,6 @@
bool queryDone();
bool start( int procId, QStringList vgflags );
- void stop();
unsigned int maxOptId() { return MEMCHECK::NUM_OPTS; }
@@ -100,6 +96,7 @@
public slots:
bool fileSaveDialog( QString fname=QString() );
+ void stop();
private:
// overriding to avoid casting everywhere
@@ -115,16 +112,15 @@
bool startProcess( QStringList flags );
private slots:
- void processDone();
+ void processDone( int exitCode, QProcess::ExitStatus exitStatus );
void readVgLog();
+ void killProcess();
private:
-/*
- QString m_saveFname;
- VgLogReader* m_vgreader;
- VKProcess* m_vgproc;
- VkLogPoller* m_logpoller;
-*/
+ QString saveFname;
+ VgLogReader* vgreader;
+ QProcess* vgproc;
+ VkLogPoller* logpoller;
};
Modified: branches/valkyrie_qt4port/objects/tool_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/tool_object.cpp 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/objects/tool_object.cpp 2010-01-27 22:54:53 UTC (rev 472)
@@ -37,7 +37,7 @@
*/
ToolObject::ToolObject( const QString& objectName, VGTOOL::ToolID id )
: VkObject( objectName ),
- toolView(0), fileSaved(true), runState(VkRunState::STOPPED), toolId(id)
+ toolView(0), fileSaved(true), processId(TOOL::PROC_NONE), toolId(id)
{
}
@@ -45,20 +45,41 @@
ToolObject::~ToolObject()
{}
-#if 0
bool ToolObject::isRunning()
{
- return (m_runState != VkRunState::STOPPED);
+ return (processId > TOOL::PROC_NONE);
}
-void ToolObject::setRunState( VkRunState::State rs )
+
+/*!
+ Set the process id.
+ Emits signal for subsequent state: 'running(true|false)'
+*/
+void ToolObject::setProcessId( int procId )
{
- m_runState = rs;
+ vk_assert( procId >= TOOL::PROC_NONE );
+ vk_assert( procId != TOOL::PROC_TOOL_NONE );
+ vk_assert( procId < TOOL::PROC_MAX);
+
+ processId = procId;
emit running( isRunning() );
}
+/*!
+ get the currently-running process id
+*/
+int ToolObject::getProcessId()
+{
+ vk_assert( processId >= TOOL::PROC_NONE );
+ vk_assert( processId != TOOL::PROC_TOOL_NONE );
+ vk_assert( processId < TOOL::PROC_MAX );
+ return processId;
+}
+
+
+#if 0
void ToolObject::deleteView()
{
emit message( "" ); /* clear the status bar */
Modified: branches/valkyrie_qt4port/objects/tool_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/tool_object.h 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/objects/tool_object.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -34,13 +34,15 @@
#include <QList>
-/* Own namespace for ease of use */
-namespace VkRunState {
- /* STOPPED: no process running
- * VALGRIND: running valgrind
- * TOOL*: running a tool-defined process
- */
- enum State { STOPPED=-1, VALGRIND=0, TOOL1, TOOL2, TOOL3 };
+namespace TOOL {
+ // Tools may extend this enum with their own process id's.
+ enum toolProcessId {
+ PROC_NONE=-1, // no process running
+ PROC_VALGRIND=0, // run valgrind for given tool
+ PROC_TOOL_NONE=1, // tool defined proc id's start here + 1
+ // tool defined processes may take up this block
+ PROC_MAX=4 // reasonable number of processes per tool
+ };
}
@@ -76,27 +78,26 @@
// stop a process: doesn't exit until success
virtual void stop() = 0;
-/*
bool isRunning();
+/*
virtual OptionsPage* createOptionsPage( OptionsWindow* parent ) = 0;
// returns a list of non-default flags to pass to valgrind
virtual QStringList modifiedVgFlags();
+*/
signals:
void running( bool );
void message( QString );
- void fatal();
+//TODO: needed?
+// void fatal();
protected:
- // set runstate and emit signal running(bool)
- void setRunState( VkRunState::State );
- // get runstate
- VkRunState::State runState() { return runState; }
+ void setProcessId( int procId );
+ int getProcessId();
virtual bool runValgrind( QStringList vgflags ) = 0;
-*/
public:
VGTOOL::ToolID getToolId() { return toolId; }
@@ -106,8 +107,8 @@
bool fileSaved;
private:
- // Keep track of current running state
- VkRunState::State runState;
+ // tools need to add own processId's: classic enum extend problem :-(
+ int processId;
VGTOOL::ToolID toolId; // which tool are we.
};
Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-27 22:54:53 UTC (rev 472)
@@ -19,6 +19,7 @@
****************************************************************************/
#include "help/help_urls.h"
+#include "objects/tool_object.h"
#include "objects/valkyrie_object.h"
#include "options/valkyrie_options_page.h" // createVkOptionsPage()
#include "utils/vk_config.h"
@@ -614,7 +615,7 @@
/*!
- Run the tool with given runState
+ Run the tool with given process id.
*/
bool Valkyrie::runTool( VGTOOL::ToolID tId, int procId )
{
@@ -624,9 +625,36 @@
ToolObject* activeTool = valgrind()->getToolObj( tId );
vk_assert( activeTool != 0 );
- return activeTool->start( procId, QStringList() );
-//TODO
-// return activeTool->start( procId, m_flags );
+ return activeTool->start( procId, vg_flags );
}
+/*!
+ Update flags for current tool
+ Called by MainWindow::updateVgFlags()
+ - which is triggered by optionsWin::flagsChanged signal
+*/
+void Valkyrie::updateVgFlags( VGTOOL::ToolID tId )
+{
+cerr << "Valkyrie::updateVgFlags( " << tId << ")" << endl;
+
+ vk_assert( tId != VGTOOL::ID_NULL );
+ ToolObject* tool = valgrind()->getToolObj( tId );
+ vk_assert( tool != 0 );
+
+ QString vg_exec = vkConfig->value( "valkyrie/vg-exec" ).toString();
+ if (vg_exec.isEmpty())
+ vg_exec = "valgrind"; // hope it's in $PATH
+
+ // modifiedVgFlags() functions return non-default flags
+ vg_flags.clear();
+ vg_flags << vg_exec; // path/to/valgrind
+ vg_flags << "--tool=" + tool->objectName(); // tool
+
+//TODO:
+ vg_flags << "ls";
+// vg_flags += valgrind()->modifiedVgFlags( tool ); // valgrind opts
+// vg_flags += tool->modifiedVgFlags(); // tool opts
+// vg_flags += this->modifiedVgFlags(); // valkyrie opts
+}
+
Modified: branches/valkyrie_qt4port/objects/valkyrie_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -69,6 +69,8 @@
#if 0 // TODO
bool queryToolDone( int tId );
#endif
+ void updateVgFlags( VGTOOL::ToolID tId );
+
unsigned int maxOptId() { return VALKYRIE::NUM_OPTS; }
int checkOptArg( QString optGrp, int optid, QString& argval );
@@ -97,6 +99,7 @@
private:
Valgrind* m_valgrind;
+ QStringList vg_flags;
};
Modified: branches/valkyrie_qt4port/toolview/vglogview.cpp
===================================================================
--- branches/valkyrie_qt4port/toolview/vglogview.cpp 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/toolview/vglogview.cpp 2010-01-27 22:54:53 UTC (rev 472)
@@ -21,7 +21,6 @@
#include "toolview/vglogview.h"
#include "utils/vk_utils.h"
#include "utils/vk_config.h"
-//#include "vglogview_icons.h"
#include <QFileInfo>
#include <QStringList>
@@ -829,8 +828,8 @@
/*!
VgLogView: inherits VgLog
*/
-VgLogView::VgLogView( QTreeWidget* lv )
- : lview(lv), lastChild( 0 )
+VgLogView::VgLogView( QTreeWidget* v )
+ : view(v), lastChild( 0 )
{ }
VgLogView::~VgLogView()
@@ -857,7 +856,7 @@
if (state == VgStatus::RUNNING) {
VgElement exe =
args().getFirstElem( "argv" ).getFirstElem( "exe" );
- topStatus = new TopStatusItem( lview, status, exe, protocol().text() );
+ topStatus = new TopStatusItem( view, status, exe, protocol().text() );
topStatus->setOpen( true );
lastChild = new InfoItem( topStatus, docroot() );
lastChild = new PreambleItem( topStatus, lastChild, preamble() );
Modified: branches/valkyrie_qt4port/toolview/vglogview.h
===================================================================
--- branches/valkyrie_qt4port/toolview/vglogview.h 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/toolview/vglogview.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -221,7 +221,7 @@
class VgLogView : public VgLog
{
public:
- VgLogView( QTreeWidget* lv );
+ VgLogView( QTreeWidget* );
~VgLogView();
bool appendNode( QDomNode node );
@@ -230,7 +230,7 @@
void updateErrorItems( VgErrCounts ec );
private:
- QTreeWidget* lview; // we don't own this: don't delete it
+ QTreeWidget* view; // we don't own this: don't delete it
VgOutputItem* lastChild;
TopStatusItem* topStatus;
};
Copied: branches/valkyrie_qt4port/utils/vk_logpoller.cpp (from rev 471, trunk/valkyrie/tool_utils/vk_logpoller.cpp)
===================================================================
--- branches/valkyrie_qt4port/utils/vk_logpoller.cpp (rev 0)
+++ branches/valkyrie_qt4port/utils/vk_logpoller.cpp 2010-01-27 22:54:53 UTC (rev 472)
@@ -0,0 +1,59 @@
+/****************************************************************************
+** VkLogPoller implementation
+** - polls a log for updates
+** --------------------------------------------------------------------------
+**
+** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved.
+** <in...@op...>
+**
+** This file is part of Valkyrie, a front-end for Valgrind.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file COPYING included in the packaging of
+** this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "utils/vk_logpoller.h"
+
+
+VkLogPoller::VkLogPoller ( QObject* parent, const char* name )
+ : QObject( parent )
+{
+ this->setObjectName( name );
+
+ timer = new QTimer( this );
+
+ connect( timer, SIGNAL(timeout()),
+ this, SIGNAL(logUpdated()) );
+}
+
+
+VkLogPoller::~VkLogPoller()
+{
+ // timer deleted by it's parent: this
+}
+
+
+void VkLogPoller::start( int interval )
+{
+ timer->start( interval );
+}
+
+
+void VkLogPoller::stop()
+{
+ if (timer->isActive())
+ timer->stop();
+}
+
+
+bool VkLogPoller::isActive()
+{
+ return timer->isActive();
+}
+
Copied: branches/valkyrie_qt4port/utils/vk_logpoller.h (from rev 471, trunk/valkyrie/tool_utils/vk_logpoller.h)
===================================================================
--- branches/valkyrie_qt4port/utils/vk_logpoller.h (rev 0)
+++ branches/valkyrie_qt4port/utils/vk_logpoller.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -0,0 +1,58 @@
+/****************************************************************************
+** VkLogPoller definition
+** - polls a log for updates
+** --------------------------------------------------------------------------
+**
+** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved.
+** <in...@op...>
+**
+** This file is part of Valkyrie, a front-end for Valgrind.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file COPYING included in the packaging of
+** this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef VK_LOGPOLLER_H
+#define VK_LOGPOLLER_H
+
+#include <QObject>
+#include <QTimer>
+
+
+/*!
+ NOTE:
+ Future intention is to have another thread running select on the
+ given file, so triggering signal when the file is updated.
+ Or something...
+*/
+
+// ============================================================
+/*!
+ class VkLogPoller
+*/
+class VkLogPoller : public QObject
+{
+ Q_OBJECT
+public:
+ VkLogPoller( QObject * parent, const char * name );
+ ~VkLogPoller();
+
+ void start( int interval=100 );
+ void stop();
+ bool isActive();
+ int interval();
+
+signals:
+ void logUpdated();
+
+private:
+ QTimer* timer;
+};
+
+#endif // VK_LOGPOLLER_H
Modified: branches/valkyrie_qt4port/utils/vk_utils.h
===================================================================
--- branches/valkyrie_qt4port/utils/vk_utils.h 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/utils/vk_utils.h 2010-01-27 22:54:53 UTC (rev 472)
@@ -73,11 +73,10 @@
#if DEBUG_ON
/* print debugging msg with file+line info to stderr ------------------- */
-# define VK_DEBUG(msg, args...) { \
- vkPrintErr("DEBUG: %s#%d:%s:", \
- __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \
- vkPrintErr(msg, ## args ); \
- vkPrintErr(" "); \
+# define VK_DEBUG(msg, args...) { \
+ vkPrintErr("DEBUG: %s#%d:%s:", __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \
+ vkPrintErr(msg, ## args ); \
+ vkPrintErr(" "); \
}
#else
# define VK_DEBUG(msg, args...) /*NOTHING*/
Modified: branches/valkyrie_qt4port/valkyrie.pro
===================================================================
--- branches/valkyrie_qt4port/valkyrie.pro 2010-01-24 18:57:15 UTC (rev 471)
+++ branches/valkyrie_qt4port/valkyrie.pro 2010-01-27 22:54:53 UTC (rev 472)
@@ -37,6 +37,7 @@
utils/vglog.cpp \
utils/vglogreader.cpp \
utils/vk_config.cpp \
+ utils/vk_logpoller.cpp \
utils/vk_messages.cpp \
utils/vk_utils.cpp
HEADERS += mainwindow.h \
@@ -72,6 +73,7 @@
utils/vglog.h \
utils/vglogreader.h \
utils/vk_config.h \
+ utils/vk_logpoller.h \
utils/vk_messages.h \
utils/vk_utils.h
RESOURCES += icons.qrc
|