Index: src/plugins/grass/qgsgrassplugin.cpp =================================================================== --- src/plugins/grass/qgsgrassplugin.cpp (revision 11516) +++ src/plugins/grass/qgsgrassplugin.cpp (working copy) @@ -301,14 +301,13 @@ QgsGrass::setLocation( sel->gisdbase, sel->location ); /* Open vector */ - QgsGrass::resetError(); - Vect_set_open_level( 2 ); - struct Map_info map; - int level = Vect_open_old_head( &map, sel->map.toAscii().data(), - sel->mapset.toAscii().data() ); + try + { + Vect_set_open_level( 2 ); + struct Map_info map; + int level = Vect_open_old_head( &map, sel->map.toAscii().data(), + sel->mapset.toAscii().data() ); - if ( QgsGrass::getError() != QgsGrass::FATAL ) - { if ( level >= 2 ) { // Count layers @@ -336,9 +335,9 @@ Vect_close( &map ); } - else + catch ( QgsGrass::Exception &e ) { - QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open GRASS vector:\n %1" ).arg( QgsGrass::getErrorMessage() ) ); + QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open GRASS vector:\n %1" ).arg( e.what() ) ); } qGisInterface->addVectorLayer( uri, name, "grass" ); @@ -486,26 +485,29 @@ QgsGrass::getDefaultLocation(), QgsGrass::getDefaultMapset() ); - QgsGrass::resetError(); - struct Map_info Map; - Vect_open_new( &Map, name.toAscii().data(), 0 ); - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + try { - QMessageBox::warning( 0, tr( "Warning" ), - tr( "Cannot create new vector: %1" ).arg( QgsGrass::getErrorMessage() ) ); - return; - } + struct Map_info Map; + Vect_open_new( &Map, name.toAscii().data(), 0 ); #if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \ ( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6 ) - Vect_build( &Map ); + Vect_build( &Map ); #else - Vect_build( &Map, stderr ); + Vect_build( &Map, stderr ); #endif - Vect_set_release_support( &Map ); - Vect_close( &Map ); + Vect_set_release_support( &Map ); + Vect_close( &Map ); + } + catch ( QgsGrass::Exception &e ) + { + QMessageBox::warning( 0, tr( "Warning" ), + tr( "Cannot create new vector: %1" ).arg( e.what() ) ); + return; + } + + // Open in GRASS vector provider QString uri = QgsGrass::getDefaultGisdbase() + "/" Index: src/plugins/grass/qgsgrassnewmapset.cpp =================================================================== --- src/plugins/grass/qgsgrassnewmapset.cpp (revision 11516) +++ src/plugins/grass/qgsgrassnewmapset.cpp (working copy) @@ -1268,17 +1268,20 @@ int ret = 0; - QgsGrass::resetError(); - if ( setjmp( QgsGrass::fatalErrorEnv() ) == 0 ) + try { ret = G_make_location( location.toAscii().data(), &mCellHead, mProjInfo, mProjUnits, stdout ); } - QgsGrass::clearErrorEnv(); + catch ( QgsGrass::Exception &e ) + { + ret = -1; + Q_UNUSED( e ); + } - if ( QgsGrass::getError() == QgsGrass::FATAL || ret != 0 ) + if ( ret != 0 ) { QMessageBox::warning( this, tr( "Create location" ), - tr( "Cannot create new location: %1" ).arg( QgsGrass::getErrorMessage() ) ); + tr( "Cannot create new location: %1" ).arg( QgsGrass::errorMessage() ) ); return; } Index: src/plugins/grass/qgsgrassmodel.cpp =================================================================== --- src/plugins/grass/qgsgrassmodel.cpp (revision 11516) +++ src/plugins/grass/qgsgrassmodel.cpp (working copy) @@ -36,8 +36,7 @@ class QgsGrassModelItem { public: - QgsGrassModelItem( QgsGrassModelItem *parent, int row, QString name, - QString path, int type ); + QgsGrassModelItem( QgsGrassModelItem *parent, int row, QString name, QString path, int type ); QgsGrassModelItem(); ~QgsGrassModelItem(); @@ -81,7 +80,7 @@ QgsGrassModelItem::~QgsGrassModelItem() { - for ( int i = 0; i < mChildren.size();i++ ) + for ( int i = 0; i < mChildren.size(); i++ ) { delete mChildren[i]; } @@ -606,13 +605,13 @@ // Add new items - for ( int i = 0; i < list.size();i++ ) + for ( int i = 0; i < list.size(); i++ ) { QString name = list.at( i ); // QgsDebugMsg(QString("? add %1").arg(name)); int insertAt = item->mChildren.size(); - for ( int i = 0; i < item->mChildren.size();i++ ) + for ( int i = 0; i < item->mChildren.size(); i++ ) { if ( item->mChildren[i]->name() == name ) { @@ -897,7 +896,6 @@ default: return mIconDirectory; } - return mIconDirectory; } return item->data( role ); } Index: src/plugins/grass/qgsgrassselect.cpp =================================================================== --- src/plugins/grass/qgsgrassselect.cpp (revision 11516) +++ src/plugins/grass/qgsgrassselect.cpp (working copy) @@ -410,15 +410,15 @@ // Call to setjmp() returns 0 first time. In case of fatal error, // our error routine uses longjmp() to come back to this context, // this time setjmp() will return non-zero value and we can continue... - if ( setjmp( QgsGrass::fatalErrorEnv() ) == 0 ) + + try { level = Vect_open_old_head( &map, ( char * ) mapName.toAscii().data(), ( char * ) mapset.toAscii().data() ); } - QgsGrass::clearErrorEnv(); - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + catch ( QgsGrass::Exception &e ) { - QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( QgsGrass::getErrorMessage() ) ); + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) ); return list; } Index: src/core/qgsmessageoutput.cpp =================================================================== --- src/core/qgsmessageoutput.cpp (revision 11516) +++ src/core/qgsmessageoutput.cpp (working copy) @@ -62,7 +62,10 @@ { // show title if provided if ( !mTitle.isNull() ) + { QgsDebugMsg( QString( "%1:" ).arg( mTitle ) ); + } + // show the message QgsDebugMsg( mMessage ); emit destroyed(); Index: src/providers/grass/qgsgrass.h =================================================================== --- src/providers/grass/qgsgrass.h (revision 11516) +++ src/providers/grass/qgsgrass.h (working copy) @@ -23,16 +23,20 @@ #include } +#include #include -#include /*! Methods for C library initialization and error handling. */ class QgsGrass { - public: + struct Exception : public std::runtime_error + { + Exception( const std::string &msg ) : std::runtime_error( msg ) {} + }; + //! Get info about the mode /*! QgsGrass may be running in active or passive mode. * Active mode means that GISRC is set up and GISRC file is available, @@ -64,10 +68,9 @@ */ static GRASS_EXPORT void setMapset( QString gisdbase, QString location, QString mapset ); - //! Error codes returned by GetError() + //! Error codes returned by error() enum GERROR { OK, /*!< OK. No error. */ - WARNING, /*!< Warning, non fatal error. Should be printed by application. */ - FATAL /*!< Fatal error. Function faild. */ + WARNING /*!< Warning, non fatal error. Should be printed by application. */ }; //! Map type @@ -77,10 +80,10 @@ static GRASS_EXPORT void resetError( void ); // reset error status //! Check if any error occured in lately called functions. Returns value from ERROR. - static GRASS_EXPORT int getError( void ); + static GRASS_EXPORT int error( void ); //! Get last error message - static GRASS_EXPORT QString getErrorMessage( void ); + static GRASS_EXPORT QString errorMessage( void ); /** \brief Open existing GRASS mapset * \return NULL string or error message @@ -160,10 +163,6 @@ static GRASS_EXPORT int versionRelease(); static GRASS_EXPORT QString versionString(); - static GRASS_EXPORT jmp_buf& fatalErrorEnv(); - static GRASS_EXPORT void clearErrorEnv(); - - private: static int initialized; // Set to 1 after initialization static bool active; // is active mode @@ -172,7 +171,7 @@ static QString defaultMapset; /* last error in GRASS libraries */ - static GERROR error; // static, because used in constructor + static GERROR lastError; // static, because used in constructor static QString error_message; // G_set_error_routine has two versions of the function's first argument it expects: @@ -188,10 +187,6 @@ static QString mGisrc; // Temporary directory where GISRC and sockets are stored static QString mTmp; - - // Context saved before a call to routine that can produce a fatal error - static jmp_buf mFatalErrorEnv; - static bool mFatalErrorEnvActive; }; #endif // QGSGRASS_H Index: src/providers/grass/qgsgrassprovider.cpp =================================================================== --- src/providers/grass/qgsgrassprovider.cpp (revision 11516) +++ src/providers/grass/qgsgrassprovider.cpp (working copy) @@ -218,7 +218,8 @@ mValid = false; - if ( ! mMaps[mLayers[mLayerId].mapId].valid ) return; + if ( !mMaps[mLayers[mLayerId].mapId].valid ) + return; // Getting the total number of features in the layer // It may happen that the field disappeares from the map (deleted features, new map without that field) @@ -300,7 +301,8 @@ if ( isEdited() || isFrozen() || !mValid ) return false; - if ( mCidxFieldIndex < 0 ) return false; // No features, no features in this layer + if ( mCidxFieldIndex < 0 || mNextCidx >= mCidxFieldNumCats ) + return false; // No features, no features in this layer // Get next line/area id int found = 0; @@ -309,12 +311,17 @@ Vect_cidx_get_cat_by_index( mMap, mCidxFieldIndex, mNextCidx++, &cat, &type, &id ); // Warning: selection array is only of type line/area of current layer -> check type first - if ( !( type & mGrassType ) ) continue; - if ( !mSelection[id] ) continue; + if ( !( type & mGrassType ) ) + continue; + + if ( !mSelection[id] ) + continue; + found = 1; break; } - if ( !found ) return false; // No more features + if ( !found ) + return false; // No more features #if QGISDEBUG > 3 QgsDebugMsg( QString( "cat = %1 type = %2 id = %3" ).arg( cat ).arg( type ).arg( id ) ); #endif @@ -655,16 +662,15 @@ // Open map QgsGrass::init(); - QgsGrass::resetError(); - if ( setjmp( QgsGrass::fatalErrorEnv() ) == 0 ) + + try { layer.mapId = openMap( gisdbase, location, mapset, mapName ); } - QgsGrass::clearErrorEnv(); - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + catch ( QgsGrass::Exception &e ) { - QgsDebugMsg( QString( "Cannot open vector map: %1" ).arg( QgsGrass::getErrorMessage() ) ); + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot open vector map: %1" ).arg( e.what() ) ); return -1; } @@ -1020,53 +1026,56 @@ // Do we have topology and cidx (level2) int level = 2; - QgsGrass::resetError(); - Vect_set_open_level( 2 ); - Vect_open_old_head( map.map, mapName.toAscii().data(), mapset.toAscii().data() ); - if ( QgsGrass::getError() == QgsGrass::FATAL ) + try { - QgsDebugMsg( QString( "Cannot open GRASS vector head on level2: %1" ).arg( QgsGrass::getErrorMessage() ) ); - level = 1; + Vect_set_open_level( 2 ); + Vect_open_old_head( map.map, mapName.toAscii().data(), mapset.toAscii().data() ); + Vect_close( map.map ); } - else + catch ( QgsGrass::Exception &e ) { - Vect_close( map.map ); + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot open GRASS vector head on level2: %1" ).arg( e.what() ) ); + level = 1; } if ( level == 1 ) { QMessageBox::StandardButton ret = QMessageBox::question( 0, "Warning", - "GRASS vector map " + mapName + - + " does not have topology. Build topology?", + tr( "GRASS vector map %1 does not have topology. Build topology?" ).arg( mapName ), QMessageBox::Ok | QMessageBox::Cancel ); if ( ret == QMessageBox::Cancel ) return -1; } // Open vector - QgsGrass::resetError(); // to "catch" error after Vect_open_old() - Vect_set_open_level( level ); - Vect_open_old( map.map, mapName.toAscii().data(), mapset.toAscii().data() ); - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + try { - QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( QgsGrass::getErrorMessage() ) ); + Vect_set_open_level( level ); + Vect_open_old( map.map, mapName.toAscii().data(), mapset.toAscii().data() ); + } + catch ( QgsGrass::Exception &e ) + { + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) ); return -1; } if ( level == 1 ) { - QgsGrass::resetError(); + try + { #if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \ ( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6 ) - Vect_build( map.map ); + Vect_build( map.map ); #else - Vect_build( map.map, stderr ); + Vect_build( map.map, stderr ); #endif - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + } + catch ( QgsGrass::Exception &e ) { - QgsDebugMsg( QString( "Cannot build topology: %1" ).arg( QgsGrass::getErrorMessage() ) ); + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot build topology: %1" ).arg( e.what() ) ); return -1; } } @@ -1098,7 +1107,8 @@ // TODO: Is it necessary for close ? G__setenv(( char * )"MAPSET", map->mapset.toAscii().data() ); - if ( closeMap ) Vect_close( map->map ); + if ( closeMap ) + Vect_close( map->map ); QFileInfo di( map->gisdbase + "/" + map->location + "/" + map->mapset + "/vector/" + map->mapName ); map->lastModified = di.lastModified(); @@ -1107,17 +1117,15 @@ map->lastAttributesModified = di.lastModified(); // Reopen vector - QgsGrass::resetError(); // to "catch" error after Vect_open_old() - Vect_set_open_level( 2 ); - if ( setjmp( QgsGrass::fatalErrorEnv() ) == 0 ) + try { + Vect_set_open_level( 2 ); Vect_open_old( map->map, map->mapName.toAscii().data(), map->mapset.toAscii().data() ); } - QgsGrass::clearErrorEnv(); - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + catch ( QgsGrass::Exception &e ) { - QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( QgsGrass::getErrorMessage() ) ); + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( e.what() ) ); // if reopen fails, mLayers should be also updated for ( unsigned int i = 0; i < mLayers.size(); i++ ) @@ -1168,7 +1176,15 @@ bool mapsetunset = G__getenv( "MAPSET" ) == NULL || *G__getenv( "MAPSET" ) == 0; if ( mapsetunset ) G__setenv(( char * )"MAPSET", mMaps[mapId].mapset.toAscii().data() ); - Vect_close( mMaps[mapId].map ); + try + { + Vect_close( mMaps[mapId].map ); + } + catch ( QgsGrass::Exception &e ) + { + Q_UNUSED( e ); + QgsDebugMsg( QString( "Vect_close failed: %1" ).arg( e.what() ) ); + } if ( mapsetunset ) G__setenv(( char * )"MAPSET", "" ); } @@ -1268,7 +1284,7 @@ GATT *att = ( GATT * ) bsearch( &key, mLayers[layerId].attributes, mLayers[layerId].nAttributes, sizeof( GATT ), cmpAtt ); - for ( QgsAttributeList::const_iterator iter = attlist.begin(); iter != attlist.end();++iter ) + for ( QgsAttributeList::const_iterator iter = attlist.begin(); iter != attlist.end(); ++iter ) { if ( att != NULL ) { @@ -1306,16 +1322,15 @@ const char *oldlocale = setlocale( LC_NUMERIC, NULL ); setlocale( LC_NUMERIC, "C" ); - if ( setjmp( QgsGrass::fatalErrorEnv() ) == 0 ) + try { G_get_default_window( &cellhd ); } - QgsGrass::clearErrorEnv(); - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + catch ( QgsGrass::Exception &e ) { + Q_UNUSED( e ); setlocale( LC_NUMERIC, oldlocale ); - QgsDebugMsg( QString( "Cannot get default window: %1" ).arg( QgsGrass::getErrorMessage() ) ); + QgsDebugMsg( QString( "Cannot get default window: %1" ).arg( e.what() ) ); return QgsCoordinateReferenceSystem(); } @@ -1473,41 +1488,42 @@ Vect_close( map->map ); // TODO: Catch error - - QgsGrass::resetError(); - int level = Vect_open_update( map->map, map->mapName.toAscii().data(), map->mapset.toAscii().data() ); - if ( level < 2 ) + int level = -1; + try { - if ( QgsGrass::getError() == QgsGrass::FATAL ) + level = Vect_open_update( map->map, map->mapName.toAscii().data(), map->mapset.toAscii().data() ); + if ( level < 2 ) { - QgsDebugMsg( QString( "Cannot open GRASS vector for update: %1" ).arg( QgsGrass::getErrorMessage() ) ); - } - else - { QgsDebugMsg( "Cannot open GRASS vector for update on level 2." ); } + } + catch ( QgsGrass::Exception &e ) + { + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot open GRASS vector for update: %1" ).arg( e.what() ) ); + } + if ( level < 2 ) + { // reopen vector for reading - QgsGrass::resetError(); - Vect_set_open_level( 2 ); - level = Vect_open_old( map->map, map->mapName.toAscii().data(), map->mapset.toAscii().data() ); - - if ( level < 2 ) + try { - if ( QgsGrass::getError() == QgsGrass::FATAL ) + Vect_set_open_level( 2 ); + level = Vect_open_old( map->map, map->mapName.toAscii().data(), map->mapset.toAscii().data() ); + if ( level < 2 ) { - QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( QgsGrass::getErrorMessage() ) ); + QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( QgsGrass::errorMessage() ) ); } - else - { - QgsDebugMsg( "Cannot reopen GRASS vector on level 2." ); - } } - else + catch ( QgsGrass::Exception &e ) { - map->valid = true; + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( e.what() ) ); } + if ( level >= 2 ) + map->valid = true; + return false; } Vect_set_category_index_update( map->map ); @@ -1588,14 +1604,15 @@ map->lastAttributesModified = di.lastModified(); // Reopen vector - QgsGrass::resetError(); // to "catch" error after Vect_open_old() - Vect_set_open_level( 2 ); - - Vect_open_old( map->map, map->mapName.toAscii().data(), map->mapset.toAscii().data() ); - - if ( QgsGrass::getError() == QgsGrass::FATAL ) + try { - QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( QgsGrass::getErrorMessage() ) ); + Vect_set_open_level( 2 ); + Vect_open_old( map->map, map->mapName.toAscii().data(), map->mapset.toAscii().data() ); + } + catch ( QgsGrass::Exception &e ) + { + Q_UNUSED( e ); + QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( e.what() ) ); return false; } Index: src/providers/grass/provider.cpp =================================================================== --- src/providers/grass/provider.cpp (revision 11516) +++ src/providers/grass/provider.cpp (working copy) @@ -14,7 +14,6 @@ * * ***************************************************************************/ #include -#include #include #include Index: src/providers/grass/qgsgrass.cpp =================================================================== --- src/providers/grass/qgsgrass.cpp (revision 11516) +++ src/providers/grass/qgsgrass.cpp (working copy) @@ -54,7 +54,8 @@ // Set error function G_set_error_routine( &error_routine ); - if ( initialized ) return; + if ( initialized ) + return; QSettings settings; @@ -355,7 +356,7 @@ bool QgsGrass::active = 0; -QgsGrass::GERROR QgsGrass::error = QgsGrass::OK; +QgsGrass::GERROR QgsGrass::lastError = QgsGrass::OK; QString QgsGrass::error_message; @@ -367,9 +368,6 @@ QString QgsGrass::mGisrc; QString QgsGrass::mTmp; -jmp_buf QgsGrass::mFatalErrorEnv; -bool QgsGrass::mFatalErrorEnvActive = false; - int QgsGrass::error_routine( char *msg, int fatal ) { return error_routine(( const char* ) msg, fatal ); @@ -383,52 +381,30 @@ if ( fatal ) { - error = FATAL; // we have to do a long jump here, otherwise GRASS >= 6.3 will kill our process - if ( mFatalErrorEnvActive ) - longjmp( mFatalErrorEnv, 1 ); - else - { - QMessageBox::warning( 0, QObject::tr( "Uncatched fatal GRASS error" ), msg ); - abort(); - } + throw QgsGrass::Exception( msg ); } else - error = WARNING; + lastError = WARNING; return 1; } void GRASS_EXPORT QgsGrass::resetError( void ) { - error = OK; + lastError = OK; } -int GRASS_EXPORT QgsGrass::getError( void ) +int GRASS_EXPORT QgsGrass::error( void ) { - return error; + return lastError; } -QString GRASS_EXPORT QgsGrass::getErrorMessage( void ) +QString GRASS_EXPORT QgsGrass::errorMessage( void ) { return error_message; } -jmp_buf GRASS_EXPORT &QgsGrass::fatalErrorEnv() -{ - if ( mFatalErrorEnvActive ) - QgsDebugMsg( "fatal error environment already active." ); - mFatalErrorEnvActive = true; - return mFatalErrorEnv; -} - -void GRASS_EXPORT QgsGrass::clearErrorEnv() -{ - if ( !mFatalErrorEnvActive ) - QgsDebugMsg( "fatal error environment already deactive." ); - mFatalErrorEnvActive = false; -} - QString GRASS_EXPORT QgsGrass::openMapset( QString gisdbase, QString location, QString mapset ) { QgsDebugMsg( QString( "gisdbase = %1" ).arg( gisdbase.toLocal8Bit().constData() ) );