|
From: <sv...@va...> - 2010-01-23 15:25:20
|
Author: cerion
Date: 2010-01-23 15:25:06 +0000 (Sat, 23 Jan 2010)
New Revision: 470
Log:
added basic tool-object framework
added bare memcheck framework incl. options (for vg3.4 still)
added bare helgrind framework (just to have a second tool for testing framework)
refactored code somewhat to remove general knowledge of tool details.
Added:
branches/valkyrie_qt4port/objects/helgrind_object.cpp
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/options/helgrind_options_page.cpp
branches/valkyrie_qt4port/options/helgrind_options_page.h
branches/valkyrie_qt4port/options/memcheck_options_page.cpp
branches/valkyrie_qt4port/options/memcheck_options_page.h
Modified:
branches/valkyrie_qt4port/main.cpp
branches/valkyrie_qt4port/mainwindow.cpp
branches/valkyrie_qt4port/mainwindow.h
branches/valkyrie_qt4port/objects/valgrind_object.cpp
branches/valkyrie_qt4port/objects/valgrind_object.h
branches/valkyrie_qt4port/objects/valkyrie_object.cpp
branches/valkyrie_qt4port/options/vk_options_dialog.cpp
branches/valkyrie_qt4port/toolview/helgrindview.cpp
branches/valkyrie_qt4port/toolview/memcheckview.cpp
branches/valkyrie_qt4port/toolview/toolview.cpp
branches/valkyrie_qt4port/toolview/toolview.h
branches/valkyrie_qt4port/valkyrie.pro
Modified: branches/valkyrie_qt4port/main.cpp
===================================================================
--- branches/valkyrie_qt4port/main.cpp 2010-01-23 09:40:36 UTC (rev 469)
+++ branches/valkyrie_qt4port/main.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -95,7 +95,7 @@
// Start up the gui
vkWin = new MainWindow( &valkyrie );
vkWin->show();
- vkWin->showToolView( vk::ID_MEMCHECK );
+ vkWin->showToolView( VGTOOL::ID_MEMCHECK );
qApp->processEvents();
Modified: branches/valkyrie_qt4port/mainwindow.cpp
===================================================================
--- branches/valkyrie_qt4port/mainwindow.cpp 2010-01-23 09:40:36 UTC (rev 469)
+++ branches/valkyrie_qt4port/mainwindow.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -35,6 +35,7 @@
#include "options/vk_option.h"
#include "utils/vk_config.h"
#include "utils/vk_messages.h"
+#include "utils/vk_utils.h"
/***************************************************************************/
@@ -230,34 +231,32 @@
// ------------------------------------------------------------
- // Tool actions
+ // Tool actions - exclusive selection group
+ toolActionGroup = new QActionGroup( this );
+//TODO: if we make it exclusive, then we can't close all toolviews and have none selected... can we?
+//toolActionGroup->setExclusive( true );
+ connect( toolActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( toolGroupTriggered( QAction* ) ) );
+
QIcon icon_bullet;
icon_bullet.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_mainwin_blackbullet.xpm") ), QIcon::Normal, QIcon::Off );
- actTool_Memcheck = new QAction( this );
- actTool_Memcheck->setObjectName( QString::fromUtf8("actTool_Memcheck") );
- actTool_Memcheck->setText( QApplication::translate("MainWindowClass", "Memcheck", 0, QApplication::UnicodeUTF8) );
- actTool_Memcheck->setCheckable( true );
- actTool_Memcheck->setIcon( icon_bullet );
- actTool_Memcheck->setIconVisibleInMenu( true );
- actTool_Memcheck->setProperty( "toolview_id", vk::ID_MEMCHECK );
+ ToolObjList tools = valkyrie->valgrind()->getToolObjList();
+ vk_assert( tools.size() > 0 );
+ foreach( ToolObject* tool, tools ) {
+ QString toolname = tool->objectName();
+ toolname[0] = toolname[0].toUpper();
- actTool_Helgrind = new QAction( this );
- actTool_Helgrind->setObjectName( QString::fromUtf8("actTool_Helgrind") );
- actTool_Helgrind->setText( QApplication::translate("MainWindowClass", "Helgrind", 0, QApplication::UnicodeUTF8) );
- actTool_Helgrind->setCheckable( true );
- actTool_Helgrind->setIcon( icon_bullet );
- actTool_Helgrind->setIconVisibleInMenu( true );
- actTool_Helgrind->setProperty( "toolview_id", vk::ID_HELGRIND );
+ QAction* actTool = new QAction( this );
+ actTool->setObjectName( "actTool_" + toolname );
+ actTool->setCheckable( true );
+ actTool->setIcon( icon_bullet );
+ actTool->setIconVisibleInMenu( true );
+ actTool->setText( toolname );
+ actTool->setProperty( "toolId", tool->getToolId() );
- // Tool Group: exclusive selection
- toolActionGroup = new QActionGroup( this );
- toolActionGroup->addAction( actTool_Memcheck );
- toolActionGroup->addAction( actTool_Helgrind );
- actTool_Memcheck->setChecked( true );
- connect( toolActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( toolGroupTriggered( QAction* ) ) );
+ toolActionGroup->addAction( actTool );
+ }
-
// ------------------------------------------------------------
// initial enables/disables
actEdit_Options->setEnabled( true );
@@ -319,10 +318,10 @@
menuProcess->addAction( actProcess_Run );
menuProcess->addAction( actProcess_Stop );
+
+ foreach ( QAction* actTool, toolActionGroup->actions() )
+ menuTools->addAction( actTool );
- menuTools->addAction( actTool_Memcheck );
- menuTools->addAction( actTool_Helgrind );
-
menuHelp->addAction( actHelp_Handbook );
menuHelp->addSeparator();
menuHelp->addAction( actHelp_About_Valkyrie );
@@ -377,33 +376,43 @@
/*!
- Show a requested ToolView, from the given \a toolview_id.
+ Show a requested ToolView, from the given \a toolId.
The ToolViews are created and shown on demand.
*/
-void MainWindow::showToolView( vk::ToolViewID toolview_id )
+void MainWindow::showToolView( VGTOOL::ToolID toolId )
{
- if ( toolViewStack->currentViewId() == toolview_id ) {
+ if ( toolViewStack->currentToolId() == toolId ) {
// already loaded and visible => do nothing
return;
}
// toolview maybe loaded, but isn't visible...
- ToolView* nextView = toolViewStack->findView( toolview_id );
+ ToolView* nextView = toolViewStack->findView( toolId );
if ( nextView == 0) {
// toolview not loaded => load it.
- switch ( toolview_id ) {
- case vk::ID_MEMCHECK:
- nextView = new MemcheckView( this );
- break;
- case vk::ID_HELGRIND:
- nextView = new HelgrindView( this );
- break;
- default:
- break;
- }
+ // set up next view
+ ToolObject* nextTool = valkyrie->valgrind()->getToolObj( toolId );
+ vk_assert( nextTool != 0 );
+
+ 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( this, SIGNAL(toolbarLabelsToggled(bool)),
+ nextView, SLOT(toggleToolbarLabels(bool)) );
+
+ // view starts tool processes via this signal
+ connect( nextView, SIGNAL(run(VkRunState::State)),
+ this, SLOT(run(VkRunState::State)) );
+*/
+
// add view to the stack
toolViewStack->addView( nextView );
}
@@ -411,10 +420,11 @@
// make sure the toolview is made visible:
toolViewStack->raiseView( nextView );
- setToggles( toolview_id );
+ setToggles( toolId );
}
+
/*!
Toggles the various actions depending on the current toolview and internal state.
@@ -422,17 +432,15 @@
is brought forward, the various actions must be updated to correspond
with the state of the new ToolView.
*/
-void MainWindow::setToggles( vk::ToolViewID toolview_id )
+void MainWindow::setToggles( VGTOOL::ToolID toolId )
{
- if ( toolview_id == vk::ID_NULL ) {
+ if ( toolId == VGTOOL::ID_NULL ) {
// no more tool views
// disable all actions in the tool actiongroup
// TODO: nicer way to do this? - maybe connect sig/slot toolview to action?
- QList<QAction*> toolActions = toolActionGroup->actions();
- for (int i = 0; i < toolActions.size(); ++i) {
- toolActions.at(i)->setChecked( false );
- }
+ foreach ( QAction* actTool, toolActionGroup->actions() )
+ actTool->setChecked( false );
actFile_Close->setEnabled( false );
actProcess_Run->setEnabled( false );
@@ -443,14 +451,14 @@
// enable the relevant action in the tool actiongroup
// TODO: nicer way to do this? - maybe connect sig/slot toolview to action?
- QList<QAction*> toolActions = toolActionGroup->actions();
- for (int i = 0; i < toolActions.size(); ++i) {
- QAction* act = toolActions.at(i);
- vk::ToolViewID tvid_action = (vk::ToolViewID)act->property( "toolview_id" ).toInt();
- if ( tvid_action == toolview_id ) {
- act->setChecked( true );
- break;
- }
+ foreach ( QAction* actTool, toolActionGroup->actions() ) {
+ VGTOOL::ToolID toolId_action =
+ (VGTOOL::ToolID)actTool->property( "toolId" ).toInt();
+ if ( toolId_action == toolId )
+ actTool->setChecked( true );
+ else
+ actTool->setChecked( false );
+//TODO: review toggle functionality.
}
actFile_Close->setEnabled( true );
@@ -545,7 +553,7 @@
toolViewStack->removeView( tv );
// current toolview will now have changed (maybe to NULL)
- setToggles( toolViewStack->currentViewId() );
+ setToggles( toolViewStack->currentToolId() );
}
@@ -563,17 +571,17 @@
This slot is called by a trigger of the tool actionGroup, which is
setup for the "Tools" menu.
- We make use of the QAction::property to store the toolview_id,
+ We make use of the QAction::property to store the toolId,
and when one of the tools is selected, this id is used to call up
the corresponding ToolView on the ToolViewStack.
*/
void MainWindow::toolGroupTriggered( QAction* action )
{
- vk::ToolViewID tvid = (vk::ToolViewID)action->property( "toolview_id" ).toInt();
+ VGTOOL::ToolID toolId = (VGTOOL::ToolID)action->property( "toolId" ).toInt();
- cerr << "MainWindow::toolGroupTriggered() for toolview " << tvid << endl;
+ cerr << "MainWindow::toolGroupTriggered() for toolview " << toolId << endl;
- showToolView( tvid );
+ showToolView( toolId );
}
Modified: branches/valkyrie_qt4port/mainwindow.h
===================================================================
--- branches/valkyrie_qt4port/mainwindow.h 2010-01-23 09:40:36 UTC (rev 469)
+++ branches/valkyrie_qt4port/mainwindow.h 2010-01-23 15:25:06 UTC (rev 470)
@@ -50,7 +50,7 @@
public slots:
void setStatus( QString msg );
- void showToolView( vk::ToolViewID tvid );
+ void showToolView( VGTOOL::ToolID toolId );
private:
void setupLayout();
@@ -58,7 +58,7 @@
void setupMenus();
void setupToolBars();
void setupStatusBar();
- void setToggles( vk::ToolViewID tvid );
+ void setToggles( VGTOOL::ToolID toolId );
private slots:
void toolGroupTriggered( QAction* );
@@ -88,8 +88,6 @@
QAction* actEdit_Search;
QAction* actProcess_Run;
QAction* actProcess_Stop;
- QAction* actTool_Memcheck;
- QAction* actTool_Helgrind;
QAction* actHelp_Handbook;
QAction* actHelp_About_Valkyrie;
QAction* actHelp_About_Qt;
Added: branches/valkyrie_qt4port/objects/helgrind_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/helgrind_object.cpp (rev 0)
+++ branches/valkyrie_qt4port/objects/helgrind_object.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -0,0 +1,83 @@
+/****************************************************************************
+** Helgrind implementation
+** - Helgrind-specific options / flags / fns
+** --------------------------------------------------------------------------
+**
+** 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 "objects/helgrind_object.h"
+//#include "utils/vk_config.h"
+#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc.
+
+
+/*!
+ class Helgrind
+*/
+Helgrind::Helgrind()
+ : ToolObject( "helgrind", VGTOOL::ID_HELGRIND )
+{
+ setupOptions();
+}
+
+
+Helgrind::~Helgrind()
+{
+}
+
+
+/*!
+ Setup the options for this object.
+
+ Note: These opts should be kept in exactly the same order as valgrind
+ outputs them, as it makes keeping up-to-date a lot easier.
+*/
+void Helgrind::setupOptions()
+{
+ // ------------------------------------------------------------
+ // foobar
+ options.addOpt(
+ HELGRIND::FOO, this->objectName(), "foo-bar",
+ '\0',
+ "<foo|bar>", "foo|bar", "foo",
+ "Fubar",
+ "fubar?",
+ "", VkOPT::ARG_STRING, VkOPT::WDG_COMBO
+ );
+}
+
+
+
+/* check argval for this option, updating if necessary.
+ called by parseCmdArgs() and gui option pages -------------------- */
+int Helgrind::checkOptArg( int optid, QString& argval )
+{
+ return PARSED_OK;
+}
+
+
+/* Creates this tool's ToolView window,
+ and sets up and connections between them */
+ToolView* Helgrind::createView( QWidget* parent )
+{
+ toolView = new HelgrindView( parent );
+ return toolView;
+}
+
+
+VkOptionsPage* Helgrind::createVkOptionsPage()
+{
+ return (VkOptionsPage*)new HelgrindOptionsPage( this );
+}
Added: branches/valkyrie_qt4port/objects/helgrind_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/helgrind_object.h (rev 0)
+++ branches/valkyrie_qt4port/objects/helgrind_object.h 2010-01-23 15:25:06 UTC (rev 470)
@@ -0,0 +1,60 @@
+/****************************************************************************
+** Helgrind definition
+** - Helgrind-specific options / flags / fns
+** --------------------------------------------------------------------------
+**
+** 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 __HELGRIND_OBJECT_H
+#define __HELGRIND_OBJECT_H
+
+
+#include "objects/tool_object.h"
+#include "toolview/helgrindview.h"
+#include "options/helgrind_options_page.h"
+
+
+// ============================================================
+namespace HELGRIND {
+/*!
+ enum identification of all options for this object
+*/
+ enum mcOptId {
+ FOO,
+ NUM_OPTS
+ };
+}
+
+
+// ============================================================
+// class Helgrind
+class Helgrind : public ToolObject
+{
+ Q_OBJECT
+public:
+ Helgrind();
+ ~Helgrind();
+
+ void setupOptions();
+
+ ToolView* createView( QWidget* parent );
+ unsigned int maxOptId() { return HELGRIND::NUM_OPTS; }
+ int checkOptArg( int optid, QString& argval );
+ VkOptionsPage* createVkOptionsPage();
+};
+
+
+#endif // __HELGRIND_OBJECT_H
Added: branches/valkyrie_qt4port/objects/memcheck_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/memcheck_object.cpp (rev 0)
+++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -0,0 +1,856 @@
+/****************************************************************************
+** Memcheck implementation
+** - Memcheck-specific options / flags / fns
+** --------------------------------------------------------------------------
+**
+** 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 "config.h"
+#include "objects/memcheck_object.h"
+#include "objects/valkyrie_object.h"
+#include "utils/vk_config.h"
+#include "help/help_urls.h"
+#include "utils/vk_messages.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.
+
+
+
+/*!
+ 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()),
+ this, SLOT(readVgLog()) );
+#endif
+
+ setupOptions();
+}
+
+
+Memcheck::~Memcheck()
+{
+#if 0
+ if (m_vgproc) {
+ m_vgproc->disconnect(); /* so no signal calling processDone() */
+ if (m_vgproc->isRunning()) {
+ m_vgproc->stop();
+ }
+ delete m_vgproc;
+ m_vgproc = 0;
+ }
+ if (m_vgreader) {
+ delete m_vgreader;
+ m_vgreader = 0;
+ }
+
+ /* m_logpoller deleted by it's parent: 'this' */
+
+ /* unsaved log... delete our temp file */
+ if (!m_fileSaved && !m_saveFname.isEmpty())
+ QDir().remove( m_saveFname );
+#endif
+}
+
+
+/*!
+ Setup the options for this object.
+
+ Note: These opts should be kept in exactly the same order as valgrind
+ outputs them, as it makes keeping up-to-date a lot easier.
+*/
+void Memcheck::setupOptions()
+{
+ // ------------------------------------------------------------
+ // leak-check
+ options.addOpt(
+ MEMCHECK::LEAK_CHECK, this->objectName(), "leak-check",
+ '\0',
+ "<no|summary|full>", "no|summary|full", "full",
+ "Search for memory leaks at exit:",
+ "search for memory leaks at exit?",
+ urlMemcheck::Leakcheck, VkOPT::ARG_STRING, VkOPT::WDG_COMBO
+ );
+
+ // ------------------------------------------------------------
+ // leak-resolution
+ options.addOpt(
+ MEMCHECK::LEAK_RES, this->objectName(), "leak-resolution",
+ '\0',
+ "<low|med|high>", "low|med|high", "low",
+ "Degree of backtrace merging:",
+ "how much backtrace merging in leak check",
+ urlMemcheck::Leakres, VkOPT::ARG_STRING, VkOPT::WDG_COMBO
+ );
+
+ // ------------------------------------------------------------
+ // leak-resolution
+ options.addOpt(
+ MEMCHECK::SHOW_REACH, this->objectName(), "show-reachable",
+ '\0',
+ "<yes|no>", "yes|no", "no",
+ "Show reachable blocks in leak check",
+ "show reachable blocks in leak check?",
+ urlMemcheck::Showreach, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK
+ );
+
+ // ------------------------------------------------------------
+ // undef-value-errors
+ //options.addOpt(
+ // MEMCHECK::UNDEF_VAL, this->objectName(), "undef-value-errors",
+ // '\0',
+ // "<yes|no>", "yes|no", "yes",
+ // "Check for undefined value errors",
+ // "check for undefined value errors?",
+ // urlMemcheck::UndefVal, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK
+ // );
+
+ // ------------------------------------------------------------
+ // track-origins
+ options.addOpt(
+ MEMCHECK::TRACK_ORI, this->objectName(), "track-origins",
+ '\0',
+ "<yes|no>", "yes|no", "no",
+ "Show the origins of uninitialised values",
+ "show the origins of uninitialised values?",
+ urlMemcheck::TrackOri, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK
+ );
+
+ // ------------------------------------------------------------
+ // partial-loads-ok
+ options.addOpt(
+ MEMCHECK::PARTIAL, this->objectName(), "partial-loads-ok",
+ '\0',
+ "<yes|no>", "yes|no", "no",
+ "Ignore errors on partially invalid addresses",
+ "too hard to explain here; see manual",
+ urlMemcheck::Partial, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK
+ );
+
+ // ------------------------------------------------------------
+ // freelist-vol
+ options.addOpt(
+ MEMCHECK::FREELIST, this->objectName(), "freelist-vol",
+ '\0',
+ "<number>", "0|1000000000", "10000000",
+ "Volume of freed blocks queue:",
+ "volume of freed blocks queue",
+ urlMemcheck::Freelist, VkOPT::ARG_UINT, VkOPT::WDG_LEDIT
+ );
+
+ // ------------------------------------------------------------
+ // workaround-gcc296-bugs
+ options.addOpt(
+ MEMCHECK::GCC_296, this->objectName(), "workaround-gcc296-bugs",
+ '\0',
+ "<yes|no>", "yes|no", "no",
+ "Work around gcc-296 bugs",
+ "self explanatory",
+ urlMemcheck::gcc296, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK
+ );
+
+ // ------------------------------------------------------------
+ // alignment
+ options.addOpt(
+ MEMCHECK::ALIGNMENT, this->objectName(), "alignment",
+ '\0',
+ "<number>", "8|1048576", "8",
+ "Minimum alignment of allocations",
+ "set minimum alignment of allocations",
+ urlVgCore::Alignment, VkOPT::ARG_PWR2, VkOPT::WDG_SPINBOX
+ );
+}
+
+
+
+/* check argval for this option, updating if necessary.
+ called by parseCmdArgs() and gui option pages -------------------- */
+int Memcheck::checkOptArg( int optid, QString& argval )
+{
+ vk_assert( optid >= 0 && optid < MEMCHECK::NUM_OPTS );
+
+ int errval = PARSED_OK;
+#if 0
+ Option* opt = findOption( optid );
+
+ switch ( (Memcheck::mcOpts)optid ) {
+ case PARTIAL:
+ case FREELIST:
+ case LEAK_RES:
+ case SHOW_REACH:
+ //case UNDEF_VAL:
+ case TRACK_ORI:
+ case GCC_296:
+ case ALIGNMENT:
+ opt->isValidArg( &errval, argval );
+ break;
+
+ /* when using xml output from valgrind, this option is preset to
+ 'full' by valgrind, so this option should not be used. */
+ case LEAK_CHECK:
+ /* Note: gui options disabled, so only reaches here from cmdline */
+ errval = PERROR_BADOPT;
+ vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1());
+ vkPrintErr(" - Memcheck presets this option to 'full' when generating the required xml output.");
+ vkPrintErr(" - See valgrind/docs/internals/xml_output.txt.");
+ break;
+
+ default:
+ vk_assert_never_reached();
+ }
+#endif
+
+ return errval;
+}
+
+
+/* called from Valkyrie::updateVgFlags() whenever flags have been changed */
+QStringList Memcheck::modifiedVgFlags()
+{
+ QStringList modFlags;
+#if 0
+ QString defVal, cfgVal, flag;
+
+ Option* opt;
+ for ( opt = m_optList.first(); opt; opt = m_optList.next() ) {
+ flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag
+ : opt->m_longFlag;
+ defVal = opt->m_defaultValue; /* opt holds the default */
+ cfgVal = vkConfig->rdEntry( opt->m_longFlag, name() );
+
+ switch ( (Memcheck::mcOpts)opt->m_key ) {
+
+ /* when using xml output from valgrind, this option is preset to
+ 'full' by valgrind, so this option should not be used. */
+ case LEAK_CHECK:
+ /* ignore this opt */
+ break;
+
+ default:
+ if ( defVal != cfgVal )
+ modFlags << "--" + opt->m_longFlag + "=" + cfgVal;
+ }
+ }
+#endif
+ return modFlags;
+}
+
+
+/* Creates this tool's ToolView window,
+ and sets up and connections between them */
+ToolView* Memcheck::createView( QWidget* parent )
+{
+ toolView = new MemcheckView( parent );
+
+#if 0
+ /* signals view --> tool */
+ connect( m_view, SIGNAL(saveLogFile()),
+ this, SLOT(fileSaveDialog()) );
+
+ /* signals tool --> view */
+ connect( this, SIGNAL(running(bool)),
+ m_view, SLOT(setState(bool)) );
+
+ setRunState( VkRunState::STOPPED );
+#endif
+ return toolView;
+}
+
+
+/* outputs a message to the status bar. */
+void Memcheck::statusMsg( QString hdr, QString msg )
+{
+//TODO
+// emit message( hdr + ": " + msg );
+}
+
+
+/* are we done and dusted?
+ anything we need to check/do before being deleted/closed?
+*/
+bool Memcheck::queryDone()
+{
+ vk_assert( getToolView() != 0 );
+#if 0
+ /* 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",
+ "<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 */
+ if ( ok == MsgBox::vkYes ) {
+ stop(); /* abort */
+ vk_assert( !isRunning() );
+ } else if ( ok == MsgBox::vkNo ) {
+ return false; /* continue */
+ }
+ }
+
+ if (!queryFileSave())
+ return false; // not saved: procrastinate.
+#endif
+ return true;
+}
+
+/* if current output not saved, ask user if want to save
+ returns false if not saved, but user wants to procrastinate.
+*/
+bool Memcheck::queryFileSave()
+{
+ vk_assert( getToolView() != 0 );
+#if 0
+ vk_assert( !isRunning() );
+
+ /* 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",
+ "&Save;&Discard;&Cancel",
+ "<p>The current output is not saved, "
+ " and will be deleted.<br/>"
+ "Do you want to save it ?</p>" );
+ if ( ok == MsgBox::vkYes ) { /* save */
+
+ if ( !fileSaveDialog() ) {
+ /* user clicked Cancel, but we already have the
+ auto-fname saved anyway, so get outta here. */
+ return false;
+ }
+
+ } else if ( ok == MsgBox::vkCancel ) { /* procrastinate */
+ return false;
+ } else { /* discard */
+ QFile::remove( m_saveFname );
+ m_fileSaved = true;
+ }
+ }
+#endif
+ return true;
+}
+
+
+bool Memcheck::start( VkRunState::State rs, QStringList vgflags )
+{
+ bool ok = false;
+#if 0
+ vk_assert( rs != VkRunState::STOPPED );
+ vk_assert( !isRunning() );
+
+ switch ( rs ) {
+ case VkRunState::VALGRIND: { ok = runValgrind( vgflags ); break; }
+ case VkRunState::TOOL1: { ok = parseLogFile(); break; }
+ case VkRunState::TOOL2: { ok = mergeLogFiles(); break; }
+ default:
+ vk_assert_never_reached();
+ }
+#endif
+ return ok;
+}
+
+
+/* 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. */
+void Memcheck::stop()
+{
+#if 0
+ if ( !isRunning() )
+ return;
+
+ switch ( runState() ) {
+ case VkRunState::VALGRIND: {
+ if (m_vgproc && m_vgproc->isRunning() )
+ m_vgproc->stop(); /* signal -> processDone() */
+ } 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 */
+ VK_DEBUG("TODO: Memcheck::stop(parse log)" );
+ } break;
+
+ case VkRunState::TOOL2: { /* merge logs */
+ if (m_vgproc && m_vgproc->isRunning() )
+ m_vgproc->stop(); /* signal -> processDone() */
+ } break;
+
+ default:
+ vk_assert_never_reached();
+ }
+
+ /* spin until done */
+ while ( isRunning() )
+ qApp->processEvents();
+#endif
+
+ return;
+}
+
+
+/* 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().
+
+ Auto-generated logs always saved in hard-coded (configured) log dir
+*/
+bool Memcheck::runValgrind( QStringList vgflags )
+{
+#if 0
+ m_saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() )
+ + "mc_log", "xml" );
+ vk_assert( !m_saveFname.isEmpty() );
+
+ vgflags.insert( ++(vgflags.begin()), ("--log-file=" + m_saveFname) );
+
+ setRunState( VkRunState::VALGRIND );
+ m_fileSaved = false;
+ statusMsg( "Memcheck", "Running ... " );
+
+ bool ok = startProcess( vgflags );
+
+ if (!ok) {
+ statusMsg( "Memcheck", "Failed" );
+ m_fileSaved = true;
+ setRunState( VkRunState::STOPPED );
+ }
+ 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 */
+bool Memcheck::parseLogFile()
+{
+ vk_assert( getToolView() != 0 );
+#if 0
+ QString log_file = vkConfig->rdEntry( "view-log", "valkyrie" );
+ statusMsg( "Parsing", log_file );
+
+ /* check this is a valid file, and has the right perms */
+ int errval = PARSED_OK;
+ QString ret_file = fileCheck( &errval, log_file, true, false );
+ if ( errval != PARSED_OK ) {
+ vkError( view(), "File Error", "%s: \n\"%s\"",
+ parseErrString(errval),
+ escapeEntities(log_file).latin1() );
+ return false;
+ }
+ log_file = ret_file;
+
+ /* fileSaved is always true here 'cos we are just parsing a file
+ which already exists on disk */
+ m_fileSaved = true;
+ setRunState( VkRunState::TOOL1 );
+
+ /* Could be a very large file, so at least get ui up-to-date now */
+ qApp->processEvents( 1000/*max msecs*/ );
+
+ /* Parse the log */
+ VgLogReader vgLogFileReader( view()->vgLogPtr() );
+ bool success = vgLogFileReader.parse( log_file );
+ if (!success) {
+ VgLogHandler* hnd = vgLogFileReader.handler();
+ statusMsg( "Parsing", "Error" );
+ vkError( view(), "XML Parse Error",
+ "<p>%s</p>", escapeEntities(hnd->fatalMsg()).latin1() );
+ }
+
+ if (success) {
+ m_saveFname = log_file;
+ statusMsg( "Loaded", log_file );
+ } else {
+ statusMsg( "Parse failed", log_file );
+ }
+ setRunState( VkRunState::STOPPED );
+ return success;
+#endif
+ return true;
+}
+
+
+/* if --merge=<file_list> was specified on the cmd-line, called by
+ valkyrie->runTool(); if set via the open-file-dialog in the gui,
+ called by MemcheckView::openMergeFile(). either way, the value in
+ [valkyrie:merge] is what we need to know
+
+ Auto-generated logs always saved in hard-coded (configured) log dir
+*/
+bool Memcheck::mergeLogFiles()
+{
+#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() );
+
+ QStringList flags;
+ flags << vkConfig->rdEntry( "merge-exec","valkyrie");
+ flags << "-f";
+ flags << fname_logList;
+ flags << "-o";
+ flags << m_saveFname;
+
+ setRunState( VkRunState::TOOL2 );
+ m_fileSaved = false;
+ statusMsg( "Merge Logs", "Running ... " );
+
+ bool ok = startProcess( flags );
+
+ if (!ok) {
+ statusMsg( "Merge Logs", "Failed" );
+ m_fileSaved = true;
+ setRunState( VkRunState::STOPPED );
+ }
+ return ok;
+#endif
+ return true;
+}
+
+
+/* Run a VKProcess, as given by 'flags'.
+ Reads ouput from file, loading this to the listview.
+*/
+bool Memcheck::startProcess( QStringList flags )
+{
+ // vkPrint("Memcheck::startProcess()");
+ // for ( unsigned int i=0; i<flags.count(); i++ )
+ // vkPrint("flag[%d] --> %s", i, flags[i].latin1() );
+ 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() );
+
+ /* 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",
+ "<p>Failed to start XML parser:<br>%s</p>",
+ errMsg.ascii() );
+ 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()) );
+
+ /* 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 );
+
+ /* set working directory */
+ m_vgproc->setWorkingDirectory(
+ QDir( vkConfig->rdEntry( "working-dir", "valkyrie" ) ) );
+
+ if ( !m_vgproc->start() ) {
+ 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() );
+ goto failed_startup;
+ }
+
+ /* 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;
+ }
+
+ // vkPrint(" - END MC::startProcess()" );
+ return true;
+
+ failed_startup:
+ VK_DEBUG("failed_startup: '%s'", flags.join(" ").latin1());
+ if (m_logpoller != 0) {
+ m_logpoller->stop();
+ }
+ if (m_vgreader != 0) {
+ delete m_vgreader;
+ m_vgreader = 0;
+ }
+ if (m_vgproc != 0) {
+ delete m_vgproc;
+ m_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.
+*/
+void Memcheck::processDone()
+{
+#if 0
+ // vkPrint("Memcheck::processDone()");
+ vk_assert( m_vgproc != 0 );
+ vk_assert( m_vgreader != 0 );
+ vk_assert( m_logpoller != 0 );
+ bool runError = false;
+
+ /* stop polling logfile ------------------------------------------ */
+ m_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())
+ readVgLog();
+
+ /* did log parsing go ok? */
+ QString fatalMsg = m_vgreader->handler()->fatalMsg();
+ if ( !fatalMsg.isEmpty() ) {
+ /* fatal log error... */
+ runError = true;
+ // vkPrint(" - Memcheck::processDone(): fatal error");
+
+ if (runState() == VkRunState::VALGRIND) {
+ statusMsg( "Memcheck", "Error parsing output log" );
+ vkError( view(), "XML Parse Error",
+ "<p>Error parsing Valgrind XML output:<br>%s</p>",
+ str2html( fatalMsg ).latin1() );
+ } else {
+ statusMsg( "Merge Logs", "Error parsing output log" );
+ vkError( view(), "Parse Error",
+ "<p>Error parsing output log</p>" );
+ }
+ } else if ( !m_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) {
+ statusMsg( "Memcheck", "Error - incomplete output log" );
+ vkError( view(), "XML Parse Error",
+ "<p>Valgrind XML output is incomplete</p>" );
+ } else {
+ statusMsg( "Merge Logs", "Error - incomplete output log" );
+ vkError( view(), "Parse Error",
+ "<p>Failed to parse merge result</p>" );
+ }
+
+ }
+
+ /* check process exit status
+ - valgrind might have bombed ---------------------------------- */
+ bool exitStatus = m_vgproc->exitStatus();
+ if (exitStatus != 0) {
+ // vkPrint(" - Memcheck::processDone(): process failed (%d)", exitStatus);
+ if (runState() == VkRunState::VALGRIND) {
+ vkError( view(), "Run Error",
+ "<p>Process exited 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);
+ } else {
+ vkError( view(), "Parse Error",
+ "<p>Merge process exited with return value %d.<br> \
+ Please check the terminal for error messages.</p>",
+ exitStatus);
+ }
+ } else {
+ // vkPrint(" - Memcheck::processDone(): process exited ok");
+ }
+
+ /* cleanup ------------------------------------------------------- */
+ delete m_vgreader;
+ m_vgreader = 0;
+ delete m_vgproc;
+ m_vgproc = 0;
+
+
+ /* we're done. --------------------------------------------------- */
+ if (!runError) { /* (else we've already set an status error message) */
+ if (runState() == VkRunState::VALGRIND)
+ statusMsg( "Memcheck", "Finished" );
+ else
+ statusMsg( "Merge Logs", "Finished" );
+ }
+
+ setRunState( VkRunState::STOPPED );
+ // vkPrint("Memcheck::processDone(): DONE.\n");
+#endif
+}
+
+
+/* Read memcheck / logmerge xml output
+ Called by
+ - m_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 );
+
+ 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() */
+ }
+#endif
+}
+
+
+/* Brings up a fileSaveDialog until successfully saved,
+ or user pressed Cancel.
+ If fname.isEmpty, ask user for a name first.
+ returns false on user pressing Cancel, else true.
+
+ Save-dialog started in user-configured default log dir
+*/
+bool Memcheck::fileSaveDialog( QString fname/*=QString()*/ )
+{
+ vk_assert( getToolView() != 0 );
+#if 0
+
+ QFileDialog dlg;
+ dlg.setShowHiddenFiles( true );
+ QString flt = "XML Files (*.xml);;Log Files (*.log.*);;All Files (*)";
+ QString cptn = "Save Log File As";
+
+ /* Ask fname if don't have one already */
+ 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 );
+ if ( fname.isEmpty() )
+ return false;
+ }
+
+ /* 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 );
+ if ( fname.isEmpty() ) /* Cancelled */
+ return false;
+ }
+#endif
+ return true;
+}
+
+/* Save to file
+ - we already have everything in m_saveFname logfile, so just copy that
+*/
+bool Memcheck::saveParsedOutput( QString& fname )
+{
+#if 0
+ //vkPrint("saveParsedOutput(%s)", fname.latin1() );
+ vk_assert( view() != 0 );
+ vk_assert( !fname.isEmpty() );
+
+ /* make sure path is absolute */
+ fname = QFileInfo( fname ).absFilePath();
+
+ /* if this filename already exists, check if we should over-write it */
+ if ( QFile::exists( fname ) ) {
+ int ok = vkQuery( view(), 2, "Overwrite File",
+ "<p>Over-write existing file '%s' ?</p>",
+ fname.latin1() );
+ if ( ok == MsgBox::vkNo ) {
+ /* nogo: return and try again */
+ return false;
+ }
+ }
+
+ /* save log (=copy/rename) */
+ bool ok;
+ if (!m_fileSaved) {
+ /* first save after a run, so just rename m_saveFname => fname */
+ if (0) vkPrint("renaming: '%s' -> '%s'",
+ m_saveFname.latin1(), fname.latin1() );
+ if (m_saveFname != fname) {
+ ok = FileCopy( m_saveFname, fname );
+ if (ok)
+ ok = QDir().remove( m_saveFname );
+ } else {
+ ok = true; // no need to do anything
+ }
+ // OLD:
+ //ok = QDir().rename( m_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 */
+ if (0) vkPrint("copying: '%s' -> '%s'",
+ m_saveFname.latin1(), fname.latin1() );
+ ok = FileCopy( m_saveFname, fname );
+ }
+ if (ok) {
+ m_saveFname = fname;
+ m_fileSaved = true;
+ statusMsg( "Saved", m_saveFname );
+ } else {
+ /* nogo: return and try again */
+ vkInfo( view(), "Save Failed",
+ "<p>Failed to save file to '%s'", fname.latin1() );
+ statusMsg( "Failed Save", m_saveFname );
+ }
+ return ok;
+#endif
+ return true;
+}
+
+
+VkOptionsPage* Memcheck::createVkOptionsPage()
+{
+ return (VkOptionsPage*)new MemcheckOptionsPage( this );
+}
Added: branches/valkyrie_qt4port/objects/memcheck_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/memcheck_object.h (rev 0)
+++ branches/valkyrie_qt4port/objects/memcheck_object.h 2010-01-23 15:25:06 UTC (rev 470)
@@ -0,0 +1,119 @@
+/****************************************************************************
+** Memcheck definition
+** - Memcheck-specific options / flags / fns
+** --------------------------------------------------------------------------
+**
+** 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 __MEMCHECK_OBJECT_H
+#define __MEMCHECK_OBJECT_H
+
+
+#include "objects/tool_object.h"
+#include "toolview/memcheckview.h"
+#include "options/memcheck_options_page.h"
+
+//#include "vk_logpoller.h"
+//#include "vglogreader.h"
+//#include "vk_process.h"
+
+
+//TODO
+
+
+// ============================================================
+namespace MEMCHECK {
+/*!
+ enum identification of all options for this object
+*/
+ enum mcOptId {
+ TOOL, // --tool
+ LEAK_CHECK,
+ LEAK_RES,
+ SHOW_REACH,
+ //UNDEF_VAL,
+ TRACK_ORI,
+ PARTIAL,
+ FREELIST,
+ GCC_296,
+ ALIGNMENT,
+ NUM_OPTS
+ };
+}
+
+
+// ============================================================
+// class Memcheck
+class Memcheck : public ToolObject
+{
+ Q_OBJECT
+public:
+ Memcheck();
+ ~Memcheck();
+
+ void setupOptions();
+
+
+ // returns the ToolView window (memcheckView) for this tool
+ ToolView* createView( QWidget* parent );
+ // called by MainWin::closeToolView()
+ bool queryDone();
+
+ bool start( VkRunState::State rm, QStringList vgflags );
+ void stop();
+
+ unsigned int maxOptId() { return MEMCHECK::NUM_OPTS; }
+
+ // check argval for this option, updating if necessary.
+ // - called by parseCmdArgs() and gui option pages
+ int checkOptArg( int optid, QString& argval );
+
+ VkOptionsPage* createVkOptionsPage();
+
+ // returns a list of non-default flags to pass to valgrind
+ QStringList modifiedVgFlags();
+
+public slots:
+ bool fileSaveDialog( QString fname=QString() );
+
+private:
+ // overriding to avoid casting everywhere
+ MemcheckView* getToolView() { return (MemcheckView*)toolView; }
+
+ void statusMsg( QString hdr, QString msg );
+ bool queryFileSave();
+ bool saveParsedOutput( QString& fname );
+
+ bool runValgrind( QStringList vgflags ); // RM_Valgrind
+ bool parseLogFile(); // RM_Tool0
+ bool mergeLogFiles(); // RM_Tool1
+ bool startProcess( QStringList flags );
+
+private slots:
+ void processDone();
+ void readVgLog();
+
+private:
+/*
+ QString m_saveFname;
+ VgLogReader* m_vgreader;
+ VKProcess* m_vgproc;
+ VkLogPoller* m_logpoller;
+*/
+};
+
+
+#endif
Added: branches/valkyrie_qt4port/objects/tool_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/tool_object.cpp (rev 0)
+++ branches/valkyrie_qt4port/objects/tool_object.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -0,0 +1,92 @@
+/****************************************************************************
+** ToolObject class implementation
+**
+** Essential functionality is contained within a ToolObject.
+** Each ToolObject has an associated ToolView for displaying output.
+** --------------------------------------------------------------------------
+**
+** 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 "objects/tool_object.h"
+#include "toolview/toolview.h"
+#include "utils/vk_config.h"
+#include "utils/vk_utils.h"
+
+#include <QKeySequence>
+#include <QString>
+#include <QStringList>
+
+
+
+/*!
+ class ToolObject
+*/
+ToolObject::ToolObject( const QString& objectName, VGTOOL::ToolID id )
+ : VkObject( objectName ),
+ toolView(0), fileSaved(true), runState(VkRunState::STOPPED), toolId(id)
+{
+
+}
+
+ToolObject::~ToolObject()
+{}
+
+#if 0
+bool ToolObject::isRunning()
+{
+ return (m_runState != VkRunState::STOPPED);
+}
+
+
+void ToolObject::setRunState( VkRunState::State rs )
+{
+ m_runState = rs;
+ emit running( isRunning() );
+}
+
+
+void ToolObject::deleteView()
+{
+ emit message( "" ); /* clear the status bar */
+ vk_assert( m_view != 0 );
+
+ m_view->close( true/*alsoDelete*/ );
+ m_view = 0;
+}
+
+ToolView* ToolObject::view()
+{
+ return m_view;
+}
+
+
+/* called from Valkyrie::updateVgFlags() whenever flags have been changed */
+QStringList ToolObject::modifiedVgFlags()
+{
+ QStringList modFlags;
+
+ for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) {
+
+ QString defVal = opt->m_defaultValue; /* opt holds the default */
+ QString cfgVal = vkConfig->rdEntry( opt->m_longFlag, name() );
+
+ if ( defVal != cfgVal )
+ modFlags << "--" + opt->m_longFlag + "=" + cfgVal;
+ }
+ return modFlags;
+}
+#endif
Added: branches/valkyrie_qt4port/objects/tool_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/tool_object.h (rev 0)
+++ branches/valkyrie_qt4port/objects/tool_object.h 2010-01-23 15:25:06 UTC (rev 470)
@@ -0,0 +1,115 @@
+/****************************************************************************
+** ToolObject class definition
+**
+** Essential functionality is contained within a ToolObject.
+** Each ToolObject has an associated ToolView for displaying output.
+** --------------------------------------------------------------------------
+**
+** 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.
+**
+****************************************************************************/
+
+
+/* TODO: don't have enum values for the objOpts; instead, init an int
+ array in the constructor. This means will have to implement addOpt
+ somewhat differently, as won't have enums available */
+
+#ifndef __TOOL_OBJECT_H
+#define __TOOL_OBJECT_H
+
+#include "objects/vk_objects.h"
+#include "toolview/toolview.h"
+
+#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 };
+}
+
+
+
+// ============================================================
+// forward decls
+class ToolView;
+class ToolObject;
+
+typedef QList<ToolObject*> ToolObjList;
+
+
+// ============================================================
+// class ToolObject
+class ToolObject : public VkObject
+{
+ Q_OBJECT
+
+public:
+ ToolObject( const QString& objectName, VGTOOL::ToolID toolId );
+ ~ToolObject();
+
+ // creates and init's this tool's ToolView window
+ virtual ToolView* createView( QWidget* parent ) = 0;
+/*
+ // called by MainWin::closeToolView()
+ virtual bool queryDone() = 0;
+ virtual void deleteView();
+ ToolView* view();
+
+ // start a process: may fail
+ virtual bool start( VkRunState::State rs, QStringList vgflags ) = 0;
+ // 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();
+
+protected:
+ // set runstate and emit signal running(bool)
+ void setRunState( VkRunState::State );
+ // get runstate
+ VkRunState::State runState() { return runState; }
+
+ virtual bool runValgrind( QStringList vgflags ) = 0;
+*/
+
+public:
+ VGTOOL::ToolID getToolId() { return toolId; }
+
+protected:
+ ToolView* toolView; // the toolview window
+ bool fileSaved;
+
+private:
+ // Keep track of current running state
+ VkRunState::State runState;
+
+ VGTOOL::ToolID toolId; // which tool are we.
+};
+
+
+#endif // #ifndef __TOOL_OBJECT_H
Modified: branches/valkyrie_qt4port/objects/valgrind_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-23 09:40:36 UTC (rev 469)
+++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -27,11 +27,12 @@
#include "utils/vk_config.h"
//#include "config.h"
-//#include "memcheck_object.h"
+#include "objects/helgrind_object.h"
+#include "objects/memcheck_object.h"
//#include "cachegrind_object.h"
//#include "massif_object.h"
//#include "vk_option.h" // PERROR* and friends
-//#include "vk_utils.h" // vk_assert, VK_DEBUG, etc.
+#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc.
//#include <ctype.h>
@@ -46,10 +47,8 @@
*/
Valgrind::Valgrind()
: VkObject( "valgrind" )
- // : VkObject( "Valgrind", "Valgrind", Qt::Key_unknown, VkObject::ID_VALGRIND )
{
- // /* init tools */
- // initToolObjects();``
+ initToolObjects();
setupOptions();
}
@@ -799,59 +798,76 @@
return modFlags;
}
+#endif
-
-/* Register tools */
+/*!
+ Register tools
+*/
void Valgrind::initToolObjects()
{
- int objId = VkObject::ID_TOOL0;
- m_toolObjList.append( new Memcheck ( objId++ ) );
+ toolObjList.append( new Memcheck() );
+ toolObjList.append( new Helgrind() );
// TODO: I need another lifetime!
- // m_toolObjList.append( new Cachegrind( objId++ ) );
- // m_toolObjList.append( new Massif ( objId++ ) );
+ // toolObjList.append( new Cachegrind() );
+ // toolObjList.append( new Massif () );
}
-/* ToolObject access -------------------------------------------=---- */
-/* Returns a list of all ptrs to ToolObjects */
-ToolObjList Valgrind::toolObjList()
+
+/*!
+ ToolObject access
+ - Returns a list of all ptrs to ToolObjects
+*/
+ToolObjList Valgrind::getToolObjList()
{
- return m_toolObjList;
+ return toolObjList;
}
+#if 0
/* Returns a ToolObject's objectId based on its name */
-int Valgrind::toolObjId( const QString& name )
+int Valgrind::getToolObjId( const QString& name )
{
- return toolObj(name)->objId();
+ return toolObj( name )->objId();
}
+#endif
/* Returns a ToolObject based on its objectId */
-ToolObject* Valgrind::toolObj( int tid )
+ToolObject* Valgrind::getToolObj( VGTOOL::ToolID tid )
{
// vkPrint("Valgrind::toolObj( int tid=%d )", tid);
- vk_assert( tid >= ID_TOOL0 );
- ToolObject* tool = m_toolObjList.at( tid - ID_TOOL0 );
- vk_assert( tool != 0 );
- vk_assert( tool->objId() == tid );
+ vk_assert( tid > VGTOOL::ID_NULL );
+
+ ToolObject* tool = NULL;
+ for ( int i=0; i< toolObjList.size(); i++ ) {
+ tool = toolObjList.at( i );
+ if ( tool->getToolId() == tid )
+ break;
+ }
+ vk_assert( tool != NULL );
+ vk_assert( tool->getToolId() == tid );
return tool;
}
+#if 0
/* Returns a ToolObject based on its name */
-ToolObject* Valgrind::toolObj( const QString& name ) {
- ToolObject* tool;
- for ( tool = m_toolObjList.first(); tool; tool = m_toolObjList.next() ) {
+ToolObject* Valgrind::getToolObj( const QString& name )
+{
+ ToolObject* tool = NULL;
+ for ( tool = toolObjList.first(); tool; tool = toolObjList.next() ) {
if ( tool->name() == name )
- return tool;
+ break;
}
- vk_assert_never_reached();
- return NULL;
-}
+ vk_assert( tool != NULL );
+ vk_assert( tool->name() == name );
+ return tool;
+}getToolId
#endif
-VkOptionsPage* Valgrind::createVkOptionsPage() {
+VkOptionsPage* Valgrind::createVkOptionsPage()
+{
return (VkOptionsPage*)new ValgrindOptionsPage( this );
}
Modified: branches/valkyrie_qt4port/objects/valgrind_object.h
===================================================================
--- branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-23 09:40:36 UTC (rev 469)
+++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-23 15:25:06 UTC (rev 470)
@@ -22,7 +22,7 @@
#define __VALGRIND_OBJECT_H
#include "objects/vk_objects.h"
-//#include "tool_object.h"
+#include "objects/tool_object.h"
// ============================================================
@@ -92,24 +92,18 @@
VkOptionsPage* createVkOptionsPage();
-#if 0
public:
- /* ToolObject access */
- ToolObjList toolObjList();
- int toolObjId( const QString& name );
- ToolObject* toolObj( int tid );
- ToolObject* toolObj( const QString& name );
-#endif
+ // ToolObject access
+ ToolObjList getToolObjList();
+// int getToolObjId( const QString& name );
+ ToolObject* getToolObj( VGTOOL::ToolID tid );
+// ToolObject* getToolObj( const QString& name );
private:
-#if 0
- /* creates the various VkObjects and initialises their options,
- ready for cmd-line parsing (if any). */
+ // create & init vg tools, ready for cmdline parsing
void initToolObjects();
+ ToolObjList toolObjList; // Valgrind Tools
- ToolObjList m_toolObjList; /* Tools */
-#endif
-
private:
void setupOptions();
};
Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp
===================================================================
--- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-23 09:40:36 UTC (rev 469)
+++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -585,12 +585,8 @@
vkObjList.append( this );
vkObjList.append( valgrind() );
-
-#if 0 // TODO
- ToolObjList tools = valgrind()->toolObjList();
- for ( ToolObject* tool = tools.first(); tool; tool = tools.next() )
+ foreach( ToolObject* tool, valgrind()->getToolObjList() )
vkObjList.append( tool );
-#endif
return vkObjList;
}
Added: branches/valkyrie_qt4port/options/helgrind_options_page.cpp
===================================================================
--- branches/valkyrie_qt4port/options/helgrind_options_page.cpp (rev 0)
+++ branches/valkyrie_qt4port/options/helgrind_options_page.cpp 2010-01-23 15:25:06 UTC (rev 470)
@@ -0,0 +1,84 @@
+/****************************************************************************
+** HelgrindOptionsPage implementation
+** - subclass of VkOptionsPage to hold helgrind-specific options
+** --------------------------------------------------------------------------
+**
+** 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 "helgrind_options_page.h"
+
+#include "objects/helgrind_object.h"
+
+#include "help/help_context.h"
+#include "help/help_urls.h"
+#include "utils/vk_utils.h"
+
+#include "o...
[truncated message content] |