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] |