Logo Search packages:      
Sourcecode: qgit version File versions


      Description: Support for recursive C++ exception handling
                  compatible with Qt qApp->processEvents()

                  See exception_manager.txt for details.

      Author: Marco Costalba (C) 2005-2006

      Copyright: See COPYING file that comes with this distribution

#include "exceptionmanager.h"

ExceptionManager::ExceptionManager() {

      excpId = regionId = currentRegionId = 1;
      descriptions.append("we start from 1");

void ExceptionManager::init(int* excp, const QString& desc) {

      *excp = excpId++;

const QString ExceptionManager::desc(int excpId) {

      return descriptions[excpId];

bool ExceptionManager::isMatch(int value, int excp, const QString& context) {

      bool match = (value == excp);
      if (match) {
            QString info("Catched exception \'" + descriptions[excp] +
                         "\' while in " + context);
      return match;

void ExceptionManager::add(int excpId) {
// add a new exception in currentThrowableSet

      // are prepended so to use a for loop starting
      // from begin to find the latest. Exceptions are
      // always added/removed from both totalThrowableSet
      // and regionThrowableSet

void ExceptionManager::remove(int excpId) {
// removes ONE exception in totalThrowableSet and ONE in regionThrowableSet.
// if add and remove calls are correctly nested the removed
// excp should be the first in both throwable sets

      if (totalThrowableSet.isEmpty() || regionThrowableSet.isEmpty()) {
            qDebug("ASSERT in remove: removing %i from an empty set", excpId);
      // remove from region.
      SetIt itReg(regionThrowableSet.begin());
      if ((*itReg).excpId != excpId) {
            qDebug("ASSERT in remove: %i is not the first in list", excpId);

      // remove from total.
      SetIt itTot(totalThrowableSet.begin());
      if ((*itTot).excpId != excpId) {
            qDebug("ASSERT in remove: %i is not the first in list", excpId);

ExceptionManager::SetIt ExceptionManager::findExcp(ThrowableSet& ts,
            const SetIt& startIt, int excpId) {

      SetIt it(startIt);
      for ( ; it != ts.end(); ++it)
            if ((*it).excpId == excpId)
      return it;

void ExceptionManager::setRaisedFlag(ThrowableSet& ts, int excpId) {

      SetIt it(findExcp(ts, ts.begin(), excpId));
      while (it != ts.end()) {
            (*it).isRaised = true;
            it = findExcp(ts, ++it, excpId);

void ExceptionManager::raise(int excpId) {

      if (totalThrowableSet.isEmpty())

      // check totalThrowableSet to find if excpId is throwable
      SetIt it = findExcp(totalThrowableSet, totalThrowableSet.begin(), excpId);
      if (it == totalThrowableSet.end())

      // we have found an exception. Set raised flag in regionThrowableSet
      setRaisedFlag(regionThrowableSet, excpId);

      // then set the flag in all regions throwableSetList
      QMap<int, ThrowableSet>::iterator itList(throwableSetMap.begin());
      while (itList != throwableSetMap.end()) {
            setRaisedFlag(*itList, excpId);

int ExceptionManager::saveThrowableSet() {
// here we save regionThrowableSet _and_ update the region.
// regionThrowableSet is saved with the current region index.
// then current region is changed to a new and never used index

      int oldCurrentRegionId = currentRegionId;
      throwableSetMap.insert(currentRegionId, regionThrowableSet);
      currentRegionId = ++regionId;

      // we use this call to trigger a region bounduary crossing
      // so we have to clear the new region throwables. We still
      // have totalThrowableSet to catch any request.

      return oldCurrentRegionId;

void ExceptionManager::restoreThrowableSet(int regionId) {

      if (!throwableSetMap.contains(regionId)) {
            qDebug("ASSERT in restoreThrowableSet: region %i not found", regionId);
      regionThrowableSet = throwableSetMap[regionId];

bool ExceptionManager::isPending(int excpId) {

      // check in ALL regions if an exception request is pending
      QMap<int, ThrowableSet>::const_iterator itList(throwableSetMap.constBegin());
      while (itList != throwableSetMap.constEnd()) {

            ThrowableSet::const_iterator it((*itList).constBegin());
            for ( ; it != (*itList).constEnd(); ++it)
                  if ((*it).isRaised && (*it).excpId == excpId)
                        return true;
      return false;

void ExceptionManager::throwPending() {

      if (regionThrowableSet.isEmpty())

      ThrowableSet::const_iterator it(regionThrowableSet.constBegin());
      for ( ; it != regionThrowableSet.constEnd(); ++it)
            if ((*it).isRaised)

      if (it == regionThrowableSet.constEnd())

      int excpToThrow = (*it).excpId;
      qDebug("Thrown exception \'%s\'", desc(excpToThrow).latin1());

      throw excpToThrow;

Generated by  Doxygen 1.6.0   Back to index