From: <sv...@va...> - 2009-12-19 23:12:54
|
Author: cerion Date: 2009-12-19 23:12:34 +0000 (Sat, 19 Dec 2009) New Revision: 461 Log: Lots more Options stuff ported. Not (at all) well tested, but it builds. Added: branches/valkyrie_qt4port/core/valgrind_object.cpp branches/valkyrie_qt4port/core/valgrind_object.h branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valgrind_options_page.h branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_lb_widget.h branches/valkyrie_qt4port/utils/vk_utils.cpp branches/valkyrie_qt4port/utils/vk_utils.h Modified: branches/valkyrie_qt4port/core/valkyrie_object.cpp branches/valkyrie_qt4port/core/valkyrie_object.h branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.h branches/valkyrie_qt4port/options/vk_option.h branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/vk_options_page.h branches/valkyrie_qt4port/options/widgets/opt_cb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_cb_widget.h branches/valkyrie_qt4port/options/widgets/opt_ck_widget.h branches/valkyrie_qt4port/options/widgets/opt_le_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_le_widget.h branches/valkyrie_qt4port/options/widgets/opt_sp_widget.cpp branches/valkyrie_qt4port/valkyrie.pro Added: branches/valkyrie_qt4port/core/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.cpp (rev 0) +++ branches/valkyrie_qt4port/core/valgrind_object.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,838 @@ +/**************************************************************************** +** Valgrind implementation +** - Valgrind-specific: options / flags / functionality +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 <QDir> + +#include "core/valgrind_object.h" +#include "options/valgrind_options_page.h" // createVkOptionsPage() + +//#include "config.h" // VK_CFG_DIR, VK_SUPPS_DIR +//#include "vk_config.h" +//#include "html_urls.h" +//#include "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. + + +//TODO: from config.h +#define VK_CFG_DIR ".valkyrie" +#define VK_SUPPS_DIR "suppressions/" + +//#include <ctype.h> +//#include <stdlib.h> +//#include <string.h> +//#include <stdio.h> + + +/***************************************************************************/ +/*! + Constructs a Valkyrie object +*/ +Valgrind::Valgrind() + : VkObject( "valgrind" ) + // : VkObject( "Valgrind", "Valgrind", Qt::Key_unknown, VkObject::ID_VALGRIND ) +{ + // /* init tools */ + // initToolObjects();`` + + setupOptions(); +} + + +Valgrind::~Valgrind() +{ + // m_toolObjList.setAutoDelete( true ); + // m_toolObjList.clear(); +} + + + +/*! + 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 Valgrind::setupOptions() +{ + + // ------------------------------------------------------------ + // tool + options.addOpt( + VALGRIND::TOOL, + this->objectName(), + "tool", + '\0', + "<name>", + "memcheck|cachegrind|massif", + "memcheck", + "Main tool:", + "use the Valgrind tool named <name>. Available tools are: memcheck, cachegrind, massif", + "",// TODO: urlVgCore::mainTool + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + + // ------------------------------------------------------------ + // common options relevant to all tools + options.addOpt( + VALGRIND::VERBOSITY, + this->objectName(), + "verbosity", + '\0', + "<0..4>", + "0|4", + "1", + "Verbosity level:", + "Be more verbose, include counts of errors", + "",// TODO: urlVgCore::verbosity + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::TRACE_CH, + this->objectName(), + "trace-children", + '\0', + "<yes|no>", + "yes|no", + "no", + "Trace child processes: ", + "Valgrind-ise child processes (follow execve)?", + "",// TODO: urlVgCore::traceChild + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SILENT_CH, + this->objectName(), + "child-silent-after-fork", + '\0', + "<yes|no>", + "yes|no", + "yes", /* currently necessary for clean XML output */ + "Omit child output between fork and exec: ", + "omit child output between fork & exec?", + "",// TODO: urlVgCore::silentChild + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::TRACK_FDS, + this->objectName(), + "track-fds", + '\0', + "<yes|no>", + "yes|no", + "no", + "Track open file descriptors:", + "track open file descriptors?", + "",// TODO: urlVgCore::trackFds + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::TIME_STAMP, + this->objectName(), + "time-stamp", + '\0', + "<yes|no>", + "yes|no", + "no", + "Add timestamps to log messages:", + "add timestamps to log messages?", + "",// TODO: urlVgCore::timeStamp + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::LOG_FD, + this->objectName(), + "log-fd", + '\0', + "<1..1024>", + "1|1023", + "2", + "Log to file descriptor:", + "log messages to file descriptor (1=stdout, 2=stderr)", + "",// TODO: urlVgCore::logToFd + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::LOG_FILE, + this->objectName(), + "log-file", + '\0', + "<file>", + "", + "", + "Log to file:", + "log messages to <file>", + "",// TODO: urlVgCore::logToFile + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + options.addOpt( + VALGRIND::LOG_SOCKET, + this->objectName(), + "log-socket", + '\0', + "<ipaddr:port>", + "", + "", + "Log to socket:", + "log messages to socket ipaddr:port", + "",// TODO: urlVgCore::logToSocket + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + + // ------------------------------------------------------------ + // uncommon options relevant to all tools + options.addOpt( + VALGRIND::RUN_LIBC, + this->objectName(), + "run-libc-freeres", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Free glibc memory at exit:", + "Free up glibc memory at exit?", + "",// TODO: urlVgCore::freeGlibc + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SIM_HINTS, + this->objectName(), + "sim-hints", + '\0', + "<hint1,hint2,...>", + "none|lax-ioctls|enable-outer", + "none", + "Simulation Hints:", + "Slightly modify the simulated behaviour. Recognised hints are: lax-ioctls, enable-outer. Use with caution!", + "",// TODO: urlVgCore::simHints + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::KERN_VAR, + this->objectName(), + "kernel-variant", + '\0', + "<variant1,...>", + "none|bproc", + "none", + "Kernel Variants:", + "Handle non-standard kernel variants. Recognised variants are: bproc. Use with caution!", + "",// TODO: urlVgCore::kernelVariant + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::EM_WARNS, + this->objectName(), + "show-emwarns", + '\0', + "<yes|no>", + "yes|no", + "no", + "Show warnings about emulation limits:", + "show warnings about emulation limits?", + "",// TODO: urlVgCore::showEmWarns + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SMC_CHECK, + this->objectName(), + "smc-check", + '\0', + "<none|stack|all>", + "none|stack|all", + "stack", + "Where to check for self-modifying code", + "checks for self-modifying code: none, only for code on the stack, or all", + "",// TODO: urlVgCore::smcSupport + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + + // ------------------------------------------------------------ + // options relevant to error-reporting tools + options.addOpt( + VALGRIND::XML_OUTPUT, + this->objectName(), + "xml", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Output in xml format:", + "all output is in XML", + "",// TODO: urlVgCore::xmlOutput + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::XML_COMMENT, + this->objectName(), + "xml-user-comment", + '\0', + "<str>", + "", + "", + "Insert verbatim in xml output", + "copy <str> verbatim to XML output", + "",// TODO: urlVgCore::xmlComment + VkOPT::ARG_STRING, + VkOPT::WDG_NONE + ); + + options.addOpt( + VALGRIND::DEMANGLE, + this->objectName(), + "demangle", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Automatically demangle C++ names", + "automatically demangle C++ names?", + "",// TODO: urlVgCore::autoDemangle + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::NUM_CALLERS, + this->objectName(), + "num-callers", + '\0', + "<1..50>", + "1|50", + "12", + "Number of stack trace callers:", + "show <num> callers in stack traces", + "",// TODO: urlVgCore::numCallers + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::ERROR_LIMIT, + this->objectName(), + "error-limit", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Limit the number of errors shown", + "Stop showing new errors if too many?", + "",// TODO: urlVgCore::errorLimit + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SHOW_BELOW, + this->objectName(), + "show-below-main", + '\0', + "<yes|no>", + "yes|no", + "no", + "Continue stack traces below main()", + "continue stack traces below main()", + "",// TODO: urlVgCore::stackTraces + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + + // ------------------------------------------------------------ + // Can't access vkConfig->suppDir(): config created after us! + QString defSuppDir = QDir::homePath() + "/" + VK_CFG_DIR + VK_SUPPS_DIR; + /* list of dirs holding suppression files */ + options.addOpt( + VALGRIND::SUPPS_DIRS, + this->objectName(), + "supps-dirs", + '\0', + "", + "", + defSuppDir, + "Suppression Dirs:", + "", + "",// TODO: urlValkyrie::suppsTab + VkOPT::NOT_POPT, + VkOPT::WDG_LISTBOX + ); + + /* list of all suppression files found in option SUPP_DIRS */ + options.addOpt( + VALGRIND::SUPPS_AVAIL, + this->objectName(), + "supps-avail", + '\0', + "", + "", + "", + "Available error-suppression file(s):", + "", + "",// TODO: urlValkyrie::suppsTab + VkOPT::NOT_POPT, + VkOPT::WDG_LISTBOX + ); + + /* list of selected suppression files */ + options.addOpt( + VALGRIND::SUPPS_SEL, + this->objectName(), + "suppressions", + '\0', + "<file1,...>", + "", + "", + "Selected error-suppression file(s):", + "suppress errors described in suppressions file(s)", + "",// TODO: urlValkyrie::suppsTab + VkOPT::ARG_STRING, + VkOPT::WDG_LISTBOX + ); + + + // ------------------------------------------------------------ + // ... + options.addOpt( + VALGRIND::GEN_SUPP, + this->objectName(), + "gen-suppressions", + '\0', + "<yes|no|all>", + "yes|no|all", + "no", + "Print suppressions for errors", + "print suppressions for errors?", + "",// TODO: urlVgCore::genSuppressions + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::DB_ATTACH, + this->objectName(), + "db-attach", + '\0', + "<yes|no>", + "yes|no", + "no", + "Start debugger on error detection", + "start debugger when errors detected?", + "",// TODO: urlVgCore::startDebugger + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::DB_COMMAND, + this->objectName(), + "db-command", + '\0', + "<command>", + "", + "/usr/bin/gdb -nw %f %p", + "Debugger:", + "command to start debugger", + "",// TODO: urlVgCore::whichDebugger + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + options.addOpt( + VALGRIND::INPUT_FD, + this->objectName(), + "input-fd", + '\0', + "<0..1024>", + "0|1023", + "0", + "Input file descriptor:", + + "File descriptor for (db) input (0=stdin, 1=stdout, 2=stderr)", + "",// TODO: urlVgCore::inputFd + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::MAX_SFRAME, + this->objectName(), + "max-stackframe", + '\0', + "<number>", + "0|2000000", + "2000000", + "Stack switch on SP changes at:", + "assume stack switch for stack pointer changes larger than <number> bytes", + "",// TODO: urlVgCore::maxSFrames + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); +} + + +/* check argval for this option, updating if necessary. + called by parseCmdArgs() and gui option pages -------------------- */ +int Valgrind::checkOptArg( int optid, QString& argval ) +{ +optid = optid; argval = argval; +// vk_assert( optid >= 0 && optid < NUM_OPTS ); + + int errval = PARSED_OK; + +#if 0 + Option* opt = findOption( optid ); + QString sep = vkConfig->sepChar(); + + switch ( (Valgrind::vgOpts)optid ) { + + case VALGRIND::TOOL: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valkyrie currently only supports Memcheck."); + break; + + case VALGRIND::SIM_HINTS: + case VALGRIND::RUN_LIBC: + case VALGRIND::NUM_CALLERS: + case VALGRIND::DEMANGLE: + // case VALGRIND::INPUT_FD: // TODO + case VALGRIND::SHOW_BELOW: + case VALGRIND::MAX_SFRAME: + case VALGRIND::SMC_CHECK: + opt->isValidArg( &errval, argval ); + break; + + case VALGRIND::VERBOSITY: + case VALGRIND::TRACK_FDS: + case VALGRIND::TIME_STAMP: + case VALGRIND::EM_WARNS: + case VALGRIND::GEN_SUPP: + case VALGRIND::ERROR_LIMIT: + case VALGRIND::DB_COMMAND: + case VALGRIND::DB_ATTACH: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valgrind presets these options for XML output."); + vkPrintErr(" - See valgrind/docs/internals/xml_output.txt."); + break; + + case VALGRIND::XML_COMMENT: + /* don't wan't xml in comment: escape '<','&',etc */ + argval = escapeEntities( argval ); + break; + + case VALGRIND::SUPPS_DIRS: { /* not popt: only reaches here from gui */ + /* check all entries are valid dirs */ + QStringList dirs = QStringList::split(sep, argval); + QStringList::iterator it = dirs.begin(); + for (; it != dirs.end(); ++it) { + /* check dirs ok */ + *it = dirCheck( &errval, *it, true, false ); + if ( errval != PARSED_OK ) + break; + } + argval = dirs.join(sep); + } break; + + case VALGRIND::SUPPS_AVAIL: /* not popt: only reaches here from gui */ + case VALGRIND::SUPPS_SEL: { /* is popt: --suppressions */ + QStringList files = QStringList::split(sep, argval); + QStringList::iterator it = files.begin(); + for (; it != files.end(); ++it) { + /* check files ok & readable */ + *it = fileCheck( &errval, *it, true, false ); + if ( errval != PARSED_OK ) + break; + /* TODO: do we care if it doesn't end in .supp? + - breaks the suppression widgets a little, as only lists those ending in .supp ... */ + + /* TODO: ? check valid suppression files */ + } + argval = files.join(sep); + } break; + + case VALGRIND::TRACE_CH: { +#if 0 + if ( opt->isValidArg( &errval, argval ) ) { + if ( argval == "yes" ) { + if ( vkConfig->rdBool( "db-attach", "valgrind" ) ) + errval = PERROR_DB_CONFLICT; + } + } +#else + /* Disabled for now - can't deal with the multiple xml files this generates */ + /* Note: Also disabled in ValgrindOptionsPage() */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Valkyrie can't yet handle the multiple xml files this generates."); +#endif + } break; + + case VALGRIND::SILENT_CH: { + /* Disabled for now - output between fork and exec is confusing for the XML output */ + /* Note: Also disabled in ValgrindOptionsPage() */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Necessary, to get clean XML output from Valgrind."); + } break; + + case VALGRIND::XML_OUTPUT: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Valkyrie always requires xml output from Valgrind."); + break; + + +#if 0 // TODO: Fix Valgrind to allow gdb attaching with XML output + case VALGRIND::DB_COMMAND: { /* gdb -nw %f %p */ + int pos = argval.find( ' ' ); + QString tmp = argval.left( pos ); + argval = binaryCheck( &errval, tmp ); + argval += tmp.right( tmp.length() - pos+1 ); + // vkPrint("db_command: %s", argval.latin1() ); + } break; + + /* check for conflict with --trace-children */ + case VALGRIND::DB_ATTACH: + if ( opt->isValidArg( &errval, argval ) ) { + if ( argval == "yes" ) { + if ( vkConfig->rdBool( "trace-children","valgrind" ) ) + errval = PERROR_DB_CONFLICT; + } + } break; +#endif + + case VALGRIND::KERN_VAR: + break; + + /* logging options */ + /* all tools use an internal logging option, + all logging options are therefore ignored */ + case VALGRIND::LOG_FILE: + case VALGRIND::LOG_FD: + case VALGRIND::LOG_SOCKET: + /* Note: gui options disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valkyrie sets its own logging options to gather data from Valgrind."); + break; + + + /* Not yet implemented */ + case VALGRIND::INPUT_FD: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Not yet implemented."); + break; + + default: + assert( true ); +// vk_assert_never_reached(); + } +#endif + + return errval; +} + + +#if 0 +/* valkyrie hijacks any log-to-file flags; these are not passed to + valgrind, but are used after parsing has finished to save to. */ +QStringList Valgrind::modifiedVgFlags( const ToolObject* tool_obj ) +{ + QStringList modFlags; + QString defVal, cfgVal, flag; + + for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) { + flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag + : opt->m_longFlag; + defVal = opt->m_defaultValue; + cfgVal = vkConfig->rdEntry( opt->cfgKey(), name() ); + + switch ( (Valgrind::vgOpts)opt->m_key ) { + + /* we never want these included */ + case VALGRIND::TOOL: /* tool set by valkyrie */ + case VALGRIND::SUPPS_DIRS: /* false option */ + case VALGRIND::SUPPS_AVAIL: /* false option */ + break; + + /* only error-reporting tools have suppressions */ + case VALGRIND::SUPPS_SEL: { + if ( tool_obj->name() == "memcheck" ) { + /* we need '--suppressions=' before each and every filename */ + QString optEntry = vkConfig->rdEntry( opt->cfgKey(), name() ); + QStringList files = QStringList::split( ",", optEntry ); + for ( unsigned int i=0; i<files.count(); i++ ) { + modFlags << "--" + opt->cfgKey() + "=" + files[i]; + } + } + } break; + + + /* for memcheck we always need xml=yes */ + case VALGRIND::XML_OUTPUT: + if ( tool_obj->name() == "memcheck") + modFlags << "--" + opt->cfgKey() + "=yes"; + else + if ( defVal != cfgVal ) + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + break; + + /* for memcheck we needs this enabled to keep the xml clean */ + case VALGRIND::SILENT_CH: + if ( tool_obj->name() == "memcheck") + modFlags << "--" + opt->cfgKey() + "=yes"; + else + if ( defVal != cfgVal ) + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + break; + + case VALGRIND::VERBOSITY: + case VALGRIND::TRACK_FDS: + case VALGRIND::TIME_STAMP: + case VALGRIND::EM_WARNS: + case VALGRIND::GEN_SUPP: + case VALGRIND::ERROR_LIMIT: + case VALGRIND::DB_ATTACH: + case VALGRIND::DB_COMMAND: + if ( defVal != cfgVal ) { + // disabled for now: /* gui options not disabled: other tools use these options */ + if ( tool_obj->name() == "memcheck") { + /* memcheck presets/ignores these options for xml output + - ignore these opts + - see valgrind/docs/internals/xml_output.txt */ + } else { + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + } + } + break; + + /* all tools use an internal logging option, + all logging options should therefore not be used */ + case VALGRIND::LOG_FILE: + case VALGRIND::LOG_FD: + case VALGRIND::LOG_SOCKET: + /* ignore these opts */ + break; + + default: + if ( defVal != cfgVal ) { + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + } + break; + } + } + + return modFlags; +} + + + +/* Register tools */ +void Valgrind::initToolObjects() +{ + int objId = VkObject::ID_TOOL0; + m_toolObjList.append( new Memcheck ( objId++ ) ); + + // TODO: I need another lifetime! + // m_toolObjList.append( new Cachegrind( objId++ ) ); + // m_toolObjList.append( new Massif ( objId++ ) ); +} + + +/* ToolObject access -------------------------------------------=---- */ + +/* Returns a list of all ptrs to ToolObjects */ +ToolObjList Valgrind::toolObjList() +{ + return m_toolObjList; +} + +/* Returns a ToolObject's objectId based on its name */ +int Valgrind::toolObjId( const QString& name ) +{ + return toolObj(name)->objId(); +} + +/* Returns a ToolObject based on its objectId */ +ToolObject* Valgrind::toolObj( int 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 ); + return tool; +} + +/* 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() ) { + if ( tool->name() == name ) + return tool; + } + vk_assert_never_reached(); + return NULL; +} +#endif + + + +VkOptionsPage* Valgrind::createVkOptionsPage() { + return (VkOptionsPage*)new ValgrindOptionsPage( this ); +} Added: branches/valkyrie_qt4port/core/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.h (rev 0) +++ branches/valkyrie_qt4port/core/valgrind_object.h 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,115 @@ +/**************************************************************************** +** Valgrind object class definition +** - Valgrind-specific: options / flags / functionality +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 __VALGRIND_OBJECT_H +#define __VALGRIND_OBJECT_H + +#include "core/vk_objects.h" +//#include "tool_object.h" + + +// ============================================================ +namespace VALGRIND { +/*! + enum identification of all options for this object +*/ + enum vgOptId { + TOOL, // --tool + /* common options relevant to all tools */ + VERBOSITY, // --verbosity + TRACE_CH, // --trace-children + SILENT_CH, // --child-silent-after-fork + TRACK_FDS, // --track-fds + TIME_STAMP, // --time-stamp + LOG_FD, // --log-fd + LOG_FILE, // --log-file + LOG_SOCKET, // --log-socket + + /* uncommon options relevant to all tools */ + RUN_LIBC, // --run-libc-freeres + SIM_HINTS, // --sim-hints + KERN_VAR, // --kernel-variant + EM_WARNS, // --show-emwarns + SMC_CHECK, // --smc-check + + /* options relevant to error-reporting tools */ + XML_OUTPUT, // --xml + XML_COMMENT, // -- xml-user-comment + DEMANGLE, // --demangle + NUM_CALLERS, // --num-callers + ERROR_LIMIT, // --error-limit + SHOW_BELOW, // --show-below-main + + /* suppressions hackery */ + SUPPS_DIRS, /* list of suppfile dirs - feeds SUPPS_AVAIL list */ + SUPPS_AVAIL, /* fake opt: dyname list of available supp files */ + SUPPS_SEL, /* the currently selected suppression(s) */ + + /* misc */ + GEN_SUPP, // --gen-suppressions + DB_ATTACH, // --db-attach + DB_COMMAND, // --db-command + INPUT_FD, // --input-fd + MAX_SFRAME, // --max-stackframe + NUM_OPTS + }; +} + + +// ============================================================ +class Valgrind : public VkObject +{ +public: + Valgrind(); + ~Valgrind(); + +#if 0 + /* returns a list of non-default flags to pass to valgrind */ + QStringList modifiedVgFlags( const ToolObject* tool_obj ); + unsigned int maxOptId() { return NUM_OPTS; } +#endif + + int checkOptArg( int optid, QString& argval ); + + VkOptionsPage* createVkOptionsPage(); + +#if 0 +public: + /* ToolObject access */ + ToolObjList toolObjList(); + int toolObjId( const QString& name ); + ToolObject* toolObj( int tid ); + ToolObject* toolObj( const QString& name ); +#endif + +private: +#if 0 + /* creates the various VkObjects and initialises their options, + ready for cmd-line parsing (if any). */ + void initToolObjects(); + + ToolObjList m_toolObjList; /* Tools */ +#endif + +private: + void setupOptions(); +}; + +#endif Modified: branches/valkyrie_qt4port/core/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/core/valkyrie_object.cpp 2009-11-01 20:23:02 UTC (rev 460) +++ branches/valkyrie_qt4port/core/valkyrie_object.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -36,6 +36,9 @@ : VkObject( "valkyrie" ) { setupOptions(); + + /* init valgrind */ + m_valgrind = new Valgrind(); } @@ -44,6 +47,11 @@ */ Valkyrie:: ~Valkyrie() { + if ( m_valgrind != 0 ) { + delete m_valgrind; + m_valgrind = 0; + } + } @@ -322,7 +330,7 @@ //int Valkyrie::checkOptArg( int optid, QString& argval ) int Valkyrie::checkOptArg( int, QString& ) { -// VkOption* opt = this->options.getOption( optid ); + // VkOption* opt = this->options.getOption( optid ); #if 0 // TODO vk_assert( optid >= 0 && optid < NUM_OPTS ); @@ -432,16 +440,19 @@ -/* Return list of all VkObjects */ +/*! + Return list of all VkObjects + + TODO: const. +*/ VkObjectList Valkyrie::vkObjList() { - VkObjectList vkObjList; // don't delete contents! + VkObjectList vkObjList; vkObjList.append( this ); + vkObjList.append( this->valgrind() ); #if 0 // TODO - vkObjList.append(m_valgrind); - ToolObjList tools = valgrind()->toolObjList(); for ( ToolObject* tool = tools.first(); tool; tool = tools.next() ) vkObjList.append( tool ); Modified: branches/valkyrie_qt4port/core/valkyrie_object.h =================================================================== --- branches/valkyrie_qt4port/core/valkyrie_object.h 2009-11-01 20:23:02 UTC (rev 460) +++ branches/valkyrie_qt4port/core/valkyrie_object.h 2009-12-19 23:12:34 UTC (rev 461) @@ -21,6 +21,7 @@ #ifndef __VALKYRIE_OBJECT_H #define __VALKYRIE_OBJECT_H +#include "core/valgrind_object.h" #include "core/vk_objects.h" // ============================================================ @@ -73,14 +74,17 @@ // Generate own options page VkOptionsPage* createVkOptionsPage(); -// TODO -// Valgrind* valgrind() { return m_valgrind; } -// /* for simplicity */ + Valgrind* valgrind() { return m_valgrind; } + + /* for simplicity */ VkObjectList vkObjList(); // VkObject* vkObject( int objId ); private: void setupOptions(); + +private: + Valgrind* m_valgrind; }; Added: branches/valkyrie_qt4port/options/valgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.cpp (rev 0) +++ branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,416 @@ +/**************************************************************************** +** ValgrindOptionsPage implementation +** - subclass of VkOptionsPage to hold valgrind-specific options +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 <QDir> +#include <QListWidget> +#include <QTabWidget> + +//#include "vk_config.h" +//#include "vk_messages.h" +#include "utils/vk_utils.h" +//#include "context_help.h" +//#include "html_urls.h" + +#include "core/valgrind_object.h" +#include "options/widgets/opt_base_widget.h" +#include "options/widgets/opt_le_widget.h" +#include "options/widgets/opt_lb_widget.h" +#include "options/valgrind_options_page.h" + + + +/* from valgrind/coregrind/pub_core_options.h + = maximum number of suppression files */ +#define VG_CLO_MAX_SFILES 10 + + +/***************************************************************************/ +/*! + Valgrind Options Page + This page is different from the others in that it uses three tabs + because there are just too many options to put on one page. + (a) general core options, + (b) error-reporting options, and + (c) suppression-related options +*/ +ValgrindOptionsPage::ValgrindOptionsPage( VkObject* obj ) + : VkOptionsPage( obj ) +{ + this->setObjectName(QString::fromUtf8("valgrind_options_page")); + + // setup the widgets & layout + setupOptions(); + + // setup edit signals/slots + It_OptWidgHash it = m_itemList.begin(); + while ( it != m_itemList.constEnd() ) { + OptionWidget* widg = it.value(); + connect( widg, SIGNAL(valueChanged( bool, OptionWidget* )), + this, SLOT(updateEditList( bool, OptionWidget* )) ); + ++it; + } +} + + +void ValgrindOptionsPage::setupOptions() +{ + group1 = new QGroupBox( " Valgrind Options ", this ); + group1->setObjectName(QString::fromUtf8("ValgrindOptionsPage_group1")); + pageTopVLayout->addWidget( group1 ); + + QTabWidget* tabWidget = new QTabWidget( this ); + tabWidget->setObjectName(QString::fromUtf8("ValgrindOptionsPage_tabWidget")); + pageTopVLayout->addWidget( tabWidget ); + + // ============================================================ + // tabCore - tab 1: core options + QWidget* tabCore = new QWidget( tabWidget ); + tabCore->setObjectName(QString::fromUtf8("tab_core")); + tabWidget->addTab( tabCore, " Core " ); +// ContextHelp::add( tabCore, urlValkyrie::coreTab ); + + // tabCore - vbox + QVBoxLayout* core_vbox = new QVBoxLayout( tabCore ); + core_vbox->setObjectName(QString::fromUtf8("core_vbox")); + + // ------------------------------------------------------------ + // tabCore - group box 1 + QGroupBox* cgroup1 = new QGroupBox(" Common Options ", tabCore ); + cgroup1->setObjectName(QString::fromUtf8("cgroup1")); + core_vbox->addWidget( cgroup1 ); // , m_space + + // tabCore - group box 1 - options + insertOptionWidget( VALGRIND::TOOL, cgroup1, true ); // combobox + insertOptionWidget( VALGRIND::VERBOSITY, cgroup1, true ); // spinbox + insertOptionWidget( VALGRIND::XML_OUTPUT, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::TRACE_CH, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::SILENT_CH, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::TRACK_FDS, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::TIME_STAMP, cgroup1, false ); // checkbox + + // tabCore - group box 1 - layout + int i=0; + QGridLayout* cgrid1 = new QGridLayout( cgroup1 ); + cgrid1->setRowMinimumHeight( i++, lineHeight/2 ); // blank top row + cgrid1->addLayout( m_itemList[VALGRIND::TOOL ]->hlayout(), i++, 0 ); + cgrid1->addLayout( m_itemList[VALGRIND::VERBOSITY ]->hlayout(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::XML_OUTPUT]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::TRACE_CH ]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::SILENT_CH ]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::TRACK_FDS ]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::TIME_STAMP]->widget(), i++, 0 ); + + + // ------------------------------------------------------------ + // tabCore - group box 2 + QGroupBox* cgroup2 = new QGroupBox(" Less Common Options ", tabCore ); + cgroup2->setObjectName(QString::fromUtf8("cgroup2")); + core_vbox->addWidget( cgroup2 ); // , m_space + + // tabCore - group box 2 - options + insertOptionWidget( VALGRIND::RUN_LIBC, cgroup2, false ); // checkbox + insertOptionWidget( VALGRIND::EM_WARNS, cgroup2, false ); // checkbox + insertOptionWidget( VALGRIND::SMC_CHECK, cgroup2, true ); // combobox + insertOptionWidget( VALGRIND::SIM_HINTS, cgroup2, true ); // combobox + insertOptionWidget( VALGRIND::KERN_VAR, cgroup2, true ); // combobox + + // tabCore - group box 2 - layout + i=0; + QGridLayout* cgrid2 = new QGridLayout( cgroup2 ); + cgrid1->setRowMinimumHeight( i++, lineHeight/2 ); // blank top row + cgrid2->addWidget( m_itemList[VALGRIND::RUN_LIBC ]->widget(), i++, 0 ); + cgrid2->addWidget( m_itemList[VALGRIND::EM_WARNS ]->widget(), i++, 0 ); + cgrid2->addLayout( m_itemList[VALGRIND::SMC_CHECK]->hlayout(), i++, 0 ); + cgrid2->addLayout( m_itemList[VALGRIND::SIM_HINTS]->hlayout(), i++, 0 ); + cgrid2->addLayout( m_itemList[VALGRIND::KERN_VAR ]->hlayout(), i++, 0 ); + + // v. stretch at bottom + core_vbox->addStretch( 1 ); + + + // ============================================================ + // tabErep - tab 2: error-reporting + QWidget* tabErep = new QWidget( tabWidget ); + tabErep->setObjectName(QString::fromUtf8("tab_erep")); + tabWidget->addTab( tabErep, " Error Reporting " ); +// ContextHelp::add( tabErep, urlValkyrie::errorTab ); + + // tabErep - vbox + QVBoxLayout* erep_vbox = new QVBoxLayout( tabErep ); + erep_vbox->setObjectName(QString::fromUtf8("erep_vbox")); + + // ------------------------------------------------------------ + // tabErep - group box 1 + QGroupBox* egroup1 = new QGroupBox(" Options ", tabErep ); + egroup1->setObjectName(QString::fromUtf8("egroup1")); + erep_vbox->addWidget( egroup1 ); // , m_space + + // tabErep - group box 1 - options + insertOptionWidget( VALGRIND::GEN_SUPP, egroup1, true ); // combobox + insertOptionWidget( VALGRIND::DEMANGLE, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::ERROR_LIMIT, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::SHOW_BELOW, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::NUM_CALLERS, egroup1, true ); // intspin + insertOptionWidget( VALGRIND::MAX_SFRAME, egroup1, true ); // spinbox + + insertOptionWidget( VALGRIND::DB_ATTACH, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::DB_COMMAND, egroup1, false ); // ledit+button + LeWidget* dbLedit = ((LeWidget*)m_itemList[VALGRIND::DB_COMMAND]); + dbLedit->addButton( egroup1, this, SLOT(getDbBin()) ); + connect(dbLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); + + insertOptionWidget( VALGRIND::INPUT_FD, egroup1, true ); // spinbox + insertOptionWidget( VALGRIND::LOG_FD, egroup1, true ); // spinbox + insertOptionWidget( VALGRIND::LOG_FILE, egroup1, true ); // ledit + insertOptionWidget( VALGRIND::LOG_SOCKET, egroup1, true ); // ledit + + // tabErep - group box 1 - layout + i=0; + QGridLayout* egrid1 = new QGridLayout( egroup1 ); + egrid1->setRowMinimumHeight( i++, lineHeight/2 ); // blank top row + egrid1->addLayout( m_itemList[VALGRIND::GEN_SUPP ]->hlayout(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::DEMANGLE ]->widget(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::ERROR_LIMIT]->widget(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::SHOW_BELOW ]->widget(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::NUM_CALLERS]->hlayout(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::MAX_SFRAME ]->hlayout(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::DB_ATTACH ]->widget(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::DB_COMMAND ]->hlayout(), i++, 0 ); + + egrid1->addWidget( sep(egroup1), i++,0, 1,2 ); + + QHBoxLayout* hBox = new QHBoxLayout(); + hBox->addLayout( m_itemList[VALGRIND::INPUT_FD]->hlayout() ); + hBox->addLayout( m_itemList[VALGRIND::LOG_FD]->hlayout() ); + egrid1->addLayout( hBox, i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::LOG_FILE ]->hlayout(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::LOG_SOCKET ]->hlayout(), i++, 0 ); + + // v. stretch at bottom + erep_vbox->addStretch( 1 ); + + + + // ============================================================ + // tabSupps - tab 3: suppressions + QWidget* tabSupps = new QWidget( tabWidget ); + tabSupps->setObjectName(QString::fromUtf8("tab_supps")); + tabWidget->addTab( tabSupps, " Suppressions " ); +// ContextHelp::add( tabSupps, urlValkyrie::suppsTab ); + + // tabErep - vbox + QVBoxLayout* supp_vbox = new QVBoxLayout( tabSupps ); + supp_vbox->setObjectName(QString::fromUtf8("supp_vbox")); + + // tabErep - options + insertOptionWidget( VALGRIND::SUPPS_DIRS, tabSupps, true ); // listbox + insertOptionWidget( VALGRIND::SUPPS_AVAIL, tabSupps, true ); // listbox + insertOptionWidget( VALGRIND::SUPPS_SEL, tabSupps, true ); // listbox + + /* FIXME: suppression listbox widgets have far too much knowledge + about what they're used for. */ + LbWidget* lbDirs = (LbWidget*)m_itemList[VALGRIND::SUPPS_DIRS]; + LbWidget* lbAvail = (LbWidget*)m_itemList[VALGRIND::SUPPS_AVAIL]; + LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL]; + + // lbDirs updates lbAvail + connect( lbDirs, SIGNAL(listChanged()), + this, SLOT(suppDirsChanged()) ); + + // lbSel and lbAvail update each other + connect( lbAvail, SIGNAL(itemSelected(const QString&)), + this, SLOT(updateSuppsSel(const QString&)) ); + connect( lbSel, SIGNAL(listChanged()), + this, SLOT(updateSuppsAvail()) ); + + supp_vbox->addLayout( m_itemList[VALGRIND::SUPPS_DIRS ]->vlayout(), 1 ); + supp_vbox->addLayout( m_itemList[VALGRIND::SUPPS_AVAIL]->vlayout(), 2 ); + supp_vbox->addLayout( m_itemList[VALGRIND::SUPPS_SEL ]->vlayout(), 1 ); + + + + // ============================================================ + // Disabled Widgets + /* These widgets are disabled because Valkyrie uses + --log-file-exactly internally: logging options would interfere + with this. */ + // error reporting tab + m_itemList[VALGRIND::LOG_FD ]->setEnabled( false ); + m_itemList[VALGRIND::LOG_FILE ]->setEnabled( false ); + m_itemList[VALGRIND::LOG_SOCKET ]->setEnabled( false ); + + /* Disabled because Valkyrie always requires xml output from Valgrind */ + m_itemList[VALGRIND::XML_OUTPUT ]->setEnabled( false ); + + /* Disabled for now: Only supporting memcheck so far. */ + m_itemList[VALGRIND::TOOL ]->setEnabled( false ); + + /* Disabled for now - can't deal with the multiple xml files this generates */ + /* Note: Also disabled in Valgrind::checkOptArg() */ + m_itemList[VALGRIND::TRACE_CH ]->setEnabled( false ); + + /* Disabled - must be left on to generate clean XML */ + /* Note: Also disabled in Valgrind::checkOptArg() */ + m_itemList[VALGRIND::SILENT_CH ]->setEnabled( false ); + + /* Disabled for now - not yet implemented */ + m_itemList[VALGRIND::INPUT_FD ]->setEnabled( false ); + + /* Disabled for now - Valgrind presets these options for XML output + - See valgrind/docs/internals/xml_output.txt */ + m_itemList[VALGRIND::VERBOSITY ]->setEnabled( false ); + m_itemList[VALGRIND::TRACK_FDS ]->setEnabled( false ); + m_itemList[VALGRIND::EM_WARNS ]->setEnabled( false ); + m_itemList[VALGRIND::GEN_SUPP ]->setEnabled( false ); + m_itemList[VALGRIND::ERROR_LIMIT]->setEnabled( false ); + m_itemList[VALGRIND::DB_ATTACH ]->setEnabled( false ); + m_itemList[VALGRIND::DB_COMMAND ]->setEnabled( false ); + dbLedit->button()->setEnabled( false ); + + vk_assert( m_itemList.count() <= VALGRIND::NUM_OPTS ); +} + + + + +#if 0 +/* Called from OptionsWindow::categoryClicked() */ +void ValgrindOptionsPage::init() +{ + /* if usr gave suppfile on cmdline (updating lbSel) + - update suppDirs, suppsAvail from each path in lbSel */ + QChar sep = vkConfig->sepChar(); + LbWidget* lbSel = (LbWidget*)m_itemList[Valgrind::SUPPS_SEL ]; + QStringList currSupps = QStringList::split( sep, lbSel->currValue() ); + LbWidget* lbDirs = (LbWidget*)m_itemList[Valgrind::SUPPS_DIRS]; + QStringList suppDirs = QStringList::split( sep, lbDirs->currValue() ); + + for ( unsigned int i=0; i<currSupps.count(); i++ ) { + QFileInfo fi( currSupps[i] ); + QString path = fi.dirPath(); + if ( suppDirs.find( path ) == suppDirs.end() ) + suppDirs << path; + } + lbDirs->setCurrValue( suppDirs.join( sep ) ); + + /* apply changes to lbDirs */ + applyEdits(); + + /* init suppsAvail */ + suppDirsChanged(); +} + + +/* called when user clicks "Apply" / "Ok" / "Reset" buttons. */ +void ValgrindOptionsPage::applyOption( int optId ) +{ + vk_assert( optId >= 0 && optId < Valgrind::NUM_OPTS ); + +// QString argval = m_itemList[optId]->currValue(); + + /* apply option */ + switch ( optId ) { + default: + break; + } +} +#endif + + +void ValgrindOptionsPage::getDbBin() +{ + vkPrintErr("TODO: ValgrindOptionsPage::getDbBin()\n"); +} + + +/* Scan dirs set in option "valgrind::supps-dirs" for available + suppression files. + Update other widgets with result. +*/ +void ValgrindOptionsPage::suppDirsChanged() +{ + m_allAvailSuppFiles = QStringList(); + LbWidget* lbDirs = (LbWidget*)m_itemList[VALGRIND::SUPPS_DIRS]; +//TODO +// QChar m_sep = vkConfig->sepChar(); + QChar m_sep = ':'; + + /* Get list of dirs from "valgrind::supps-dirs" */ + QStringList suppDirs = lbDirs->currValue().split( m_sep ); + for ( int i=0; i<suppDirs.count(); i++ ) { + + /* for each suppDir, find all supp files */ + QDir suppDir( suppDirs[i] ); + QString path = suppDir.absolutePath() + '/'; + QStringList entries = suppDir.entryList( QStringList( "*.supp" ), QDir::Files ); + for ( int i=0; i<entries.count(); i++) { + m_allAvailSuppFiles += (path + entries[i]); + } + } + + updateSuppsAvail(); +} + + +/* Given available suppfiles from dirscan, + remove those already selected in option "valgrind::supps-sel" + Set suppsAvail list with result. +*/ +void ValgrindOptionsPage::updateSuppsAvail() +{ +//TODO +// QChar m_sep = vkConfig->sepChar(); +QChar m_sep = ':'; + LbWidget* lbAvail = (LbWidget*)m_itemList[VALGRIND::SUPPS_AVAIL]; + LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL ]; + QStringList suppsAvail = m_allAvailSuppFiles; + QStringList currSupps = lbSel->currValue().split( m_sep ); + + for ( int i=0; i<currSupps.count(); i++ ) { + int idx = suppsAvail.indexOf( currSupps[i] ); + if ( idx != -1 ) { + suppsAvail.removeAt( idx ); + } + } + + lbAvail->setCurrValue( suppsAvail.join( m_sep ) ); +} + + +/* Called by selecting an item in suppsAvail listbox. + Adds item to selected supps listbox (up to limit) +*/ +void ValgrindOptionsPage::updateSuppsSel(const QString& suppr) +{ + LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL]; + + if (((QListWidget*)lbSel->widget())->count() < VG_CLO_MAX_SFILES) { + lbSel->insertItem(suppr); + } else { +//TODO + cerr << "FIXME: Valgrind won't accept more than %d suppression files" << endl; +#if 0 + /* valgrind doesn't accept any more suppression files */ + vkError( this, "Error", + "Valgrind won't accept more than %d suppression files", + VG_CLO_MAX_SFILES ); +#endif + } +} Added: branches/valkyrie_qt4port/options/valgrind_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.h (rev 0) +++ branches/valkyrie_qt4port/options/valgrind_options_page.h 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,62 @@ +/**************************************************************************** +** ValgrindOptionsPage definition +** - subclass of VkOptionsPage to hold valgrind-specific options +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 __VALGRIND_OPTIONS_PAGE_H +#define __VALGRIND_OPTIONS_PAGE_H + +#include <QGroupBox> +#include <QStringList> + +#include "options/vk_options_page.h" + + +// ============================================================ +class ValgrindOptionsPage : public VkOptionsPage +{ + Q_OBJECT +public: + ValgrindOptionsPage( VkObject* obj ); + +#if 0 + void applyOption( int optId ); + + void init(); +#endif + +private slots: + void getDbBin(); + void suppDirsChanged(); + void updateSuppsAvail(); + void updateSuppsSel(const QString&); + +private: + // hold on to these, so don't have to rescan dirs all the time + QStringList m_allAvailSuppFiles; + +private: + void setupOptions(); + +private: + QGroupBox* group1; + +}; + + +#endif Modified: branches/valkyrie_qt4port/options/valkyrie_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2009-11-01 20:23:02 UTC (rev 460) +++ branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -22,28 +22,34 @@ //QGroupBox #include <QLabel> +#include "utils/vk_utils.h" + #if 0 #include "vk_objects.h" #include "vk_config.h" -#include "vk_utils.h" #include "main_window.h" #include "vk_messages.h" #include "context_help.h" #include "html_urls.h" #endif -#include "core/valkyrie_object.h" // access to valkyrie object +#include "core/valkyrie_object.h" // access to valkyrie object #include "options/widgets/opt_base_widget.h" #include "options/widgets/opt_le_widget.h" #include "options/valkyrie_options_page.h" +/***************************************************************************/ +/*! + Valkyrie Options Page +*/ ValkyrieOptionsPage::ValkyrieOptionsPage( VkObject* obj ) : VkOptionsPage( obj ) { + this->setObjectName(QString::fromUtf8("valkyrie_options_page")); + // setup the widgets & layout setupOptions(); - setupLayout(); // setup edit signals/slots It_OptWidgHash it = m_itemList.begin(); @@ -66,9 +72,15 @@ //TODO //ContextHelp::add( group1, urlVALKYRIE::optsPage ); + // Note: not using opt_widget->hlayout()'s as button width won't match qlabel width. + QGridLayout* grid = new QGridLayout( group1 ); + grid->setColumnStretch(0, 0); + grid->setColumnStretch(1, 1); + grid->setColumnStretch(2, 1); + grid->setColumnStretch(3, 1); // ------------------------------------------------------------ - // general prefs + // general prefs - options insertOptionWidget( VALKYRIE::TOOLTIP, group1, false ); // checkbox insertOptionWidget( VALKYRIE::ICONTXT, group1, false ); // checkbox insertOptionWidget( VALKYRIE::PALETTE, group1, false ); // checkbox @@ -88,10 +100,26 @@ dirWorking->addButton( group1, this, SLOT(getWorkingDir()) ); connect(dirWorking, SIGNAL(returnPressed()), this, SIGNAL(apply())); + // general prefs - layout + int i=0; + grid->setRowMinimumHeight( i++, lineHeight/2 ); // blank row + grid->addWidget( m_itemList[VALKYRIE::TOOLTIP]->widget(), i++,0, 1,2 ); + grid->addWidget( m_itemList[VALKYRIE::ICONTXT]->widget(), i++,0, 1,2 ); + grid->addWidget( m_itemList[VALKYRIE::PALETTE]->widget(), i++,0, 1,2 ); + grid->addWidget( brwsrLedit->button(), i, 0 ); + grid->addWidget( brwsrLedit->widget(), i++, 1, 1,3 ); + grid->addWidget( dirLogSave->button(), i, 0 ); + grid->addWidget( dirLogSave->widget(), i++,1, 1,3 ); + grid->addWidget( dirWorking->button(), i, 0 ); + grid->addWidget( dirWorking->widget(), i++,1, 1,3 ); + grid->addWidget( sep(group1), i++,0, 1,4 ); + + // ------------------------------------------------------------ - // fonts + // fonts - options insertOptionWidget( VALKYRIE::FNT_GEN_SYS, group1, false ); // checkbox + LeWidget* fontGenSysLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_SYS]); insertOptionWidget( VALKYRIE::FNT_GEN_USR, group1, false ); // line edit LeWidget* fontGenLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_USR]); fontGenLedit->addButton( group1, this, SLOT(chooseGenFont()) ); @@ -102,17 +130,26 @@ // bool use_sys_font = vkConfig->rdBool("font-gen-sys", "valkyrie"); bool use_sys_font = true; fontGenLedit->setDisabled( use_sys_font ); - connect( m_itemList[VALKYRIE::FNT_GEN_SYS], SIGNAL(changed(bool)), - m_itemList[VALKYRIE::FNT_GEN_USR], SLOT(setDisabled(bool)) ); + connect( fontGenSysLedit, SIGNAL(changed(bool)), + fontGenLedit, SLOT(setDisabled(bool)) ); insertOptionWidget( VALKYRIE::FNT_TOOL_USR, group1, false ); // line edit LeWidget* fontToolLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_TOOL_USR]); fontToolLedit->addButton( group1, this, SLOT(chooseToolFont()) ); fontToolLedit->setReadOnly( true ); // don't allow direct editing + // fonts - layout + grid->addWidget( fontGenSysLedit->widget(), i++,0, 1,4 ); + grid->addWidget( fontGenLedit->button(), i, 0 ); + grid->addWidget( fontGenLedit->widget(), i++,1, 1,3 ); + grid->addWidget( fontToolLedit->button(), i, 0 ); + grid->addWidget( fontToolLedit->widget(), i++,1, 1,3 ); + grid->addWidget( sep(group1), i++,0, 1,4 ); + + // ------------------------------------------------------------ - // core + // core - options insertOptionWidget( VALKYRIE::SRC_LINES, group1, true ); // intspin insertOptionWidget( VALKYRIE::SRC_EDITOR, group1, false ); // ledit + button LeWidget* editLedit = ((LeWidget*)m_itemList[VALKYRIE::SRC_EDITOR]); @@ -133,105 +170,29 @@ vgbinLedit->addButton( group1, this, SLOT(getVgExec()) ); connect(vgbinLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); -//TODO -// vk_assert( m_itemList.count() <= VALKYRIE::NUM_OPTS ); -} - - -void ValkyrieOptionsPage::setupLayout() -{ - // Note: not using opt_widget->hlayout()'s as button width won't match qlabel width. - int i=0; - QGridLayout* grid = new QGridLayout( group1 ); - grid->setColumnStretch(0, 0); - grid->setColumnStretch(1, 1); - grid->setColumnStretch(2, 1); - grid->setColumnStretch(3, 1); - - grid->setRowMinimumHeight( i, lineHeight/2 ); // blank row - i++; - - // ------------------------------------------------------------ - // general prefs - grid->addWidget( m_itemList[VALKYRIE::TOOLTIP]->widget(), i,0, 1,2 ); - i++; - grid->addWidget( m_itemList[VALKYRIE::ICONTXT]->widget(), i,0, 1,2 ); - i++; - grid->addWidget( m_itemList[VALKYRIE::PALETTE]->widget(), i,0, 1,2 ); - i++; - - LeWidget* brwsrLedit = ((LeWidget*)m_itemList[VALKYRIE::BROWSER]); - grid->addWidget( brwsrLedit->button(), i, 0 ); - grid->addWidget( brwsrLedit->widget(), i, 1, 1,3 ); - i++; - - LeWidget* dirLogSave = ((LeWidget*)m_itemList[VALKYRIE::DFLT_LOGDIR]); - grid->addWidget( dirLogSave->button(), i, 0 ); - grid->addWidget( dirLogSave->widget(), i,1, 1,3 ); - i++; - - LeWidget* dirWorking = ((LeWidget*)m_itemList[VALKYRIE::WORKING_DIR]); - grid->addWidget( dirWorking->button(), i, 0 ); - grid->addWidget( dirWorking->widget(), i,1, 1,3 ); - i++; - - grid->addWidget( sep(group1), i,0, 1,4 ); - i++; - - - // ------------------------------------------------------------ - // fonts - LeWidget* fontGenSysLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_SYS]); - grid->addWidget( fontGenSysLedit->widget(), i,0, 1,4 ); - i++; - - LeWidget* fontGenLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_USR]); - grid->addWidget( fontGenLedit->button(), i, 0 ); - grid->addWidget( fontGenLedit->widget(), i,1, 1,3 ); - i++; - - LeWidget* fontToolLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_TOOL_USR]); - grid->addWidget( fontToolLedit->button(), i, 0 ); - grid->addWidget( fontToolLedit->widget(), i,1, 1,3 ); - i++; - - grid->addWidget( sep(group1), i,0, 1,4 ); - i++; - - - // ------------------------------------------------------------ - // core - grid->addLayout( m_itemList[VALKYRIE::SRC_LINES]->hlayout(), i,0, 1,4 ); - i++; - LeWidget* editLedit = ((LeWidget*)m_itemList[VALKYRIE::SRC_EDITOR]); + // core - layout + grid->addLayout( m_itemList[VALKYRIE::SRC_LINES]->hlayout(), i++,0, 1,4 ); grid->addWidget( editLedit->button(), i, 0 ); - grid->addWidget( editLedit->widget(), i,1, 1,3 ); - i++; + grid->addWidget( editLedit->widget(), i++,1, 1,3 ); - grid->setRowMinimumHeight( i, lineHeight ); // blank row - i++; + grid->setRowMinimumHeight( i++, lineHeight ); // blank row - LeWidget* binLedit = ((LeWidget*)m_itemList[VALKYRIE::BINARY]); - grid->addWidget( binLedit->button(), i, 0 ); - grid->addWidget( binLedit->widget(), i,1, 1,3 ); - i++; + grid->addWidget( binLedit->button(), i, 0 ); + grid->addWidget( binLedit->widget(), i++,1, 1,3 ); + grid->addWidget( binFlgsLedit->label(), i, 0 ); + grid->addWidget( binFlgsLedit->widget(), i++,1, 1,3 ); - LeWidget* binFlgsLedit = ((LeWidget*)m_itemList[VALKYRIE::BIN_FLAGS]); - grid->addWidget( binFlgsLedit->label(), i, 0 ); - grid->addWidget( binFlgsLedit->widget(), i,1, 1,3 ); - i++; + grid->setRowMinimumHeight( i++, lineHeight ); // blank row - grid->setRowMinimumHeight( i, lineHeight ); // blank row - i++; - - LeWidget* vgbinLedit = ((LeWidget*)m_itemList[VALKYRIE::VG_EXEC]); grid->addWidget( vgbinLedit->button(), i, 0 ); - grid->addWidget( vgbinLedit->widget(), i,1, 1,3 ); - i++; + grid->addWidget( vgbinLedit->widget(), i++,1, 1,3 ... [truncated message content] |