libyui
|
00001 /************************************************************************** 00002 Copyright (C) 2000 - 2010 Novell, Inc. 00003 All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License along 00016 with this program; if not, write to the Free Software Foundation, Inc., 00017 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 00019 **************************************************************************/ 00020 00021 00022 /*---------------------------------------------------------------------\ 00023 | | 00024 | __ __ ____ _____ ____ | 00025 | \ \ / /_ _/ ___|_ _|___ \ | 00026 | \ V / _` \___ \ | | __) | | 00027 | | | (_| |___) || | / __/ | 00028 | |_|\__,_|____/ |_| |_____| | 00029 | | 00030 | core system | 00031 | (C) SuSE GmbH | 00032 \----------------------------------------------------------------------/ 00033 00034 File: YUIException.h 00035 00036 Stolen from zypp/libzypp/base/Exception.h 00037 00038 Author: Michael Andres <ma@suse.de> 00039 Maintainer: Stefan Hundhammer <sh@suse.de> 00040 00041 /-*/ 00042 00043 #ifndef YUIException_h 00044 #define YUIException_h 00045 00046 00047 #include <cerrno> 00048 #include <iostream> 00049 #include <stdexcept> 00050 00051 #include "YProperty.h" 00052 00053 using std::string; 00054 using std::ostream; 00055 using std::endl; 00056 00057 class YWidget; 00058 00059 00060 // 00061 // Macros for application use 00062 // 00063 00102 #define YUI_EXCEPTION_CODE_LOCATION YCodeLocation(__FILE__,__FUNCTION__,__LINE__) 00103 00104 00108 #define YUI_THROW( EXCEPTION ) \ 00109 _YUI_THROW( ( EXCEPTION ), YUI_EXCEPTION_CODE_LOCATION ) 00110 00114 #define YUI_CAUGHT( EXCEPTION ) \ 00115 _YUI_CAUGHT( ( EXCEPTION ), YUI_EXCEPTION_CODE_LOCATION ) 00116 00117 00121 #define YUI_RETHROW( EXCEPTION ) \ 00122 _YUI_RETHROW( ( EXCEPTION ), YUI_EXCEPTION_CODE_LOCATION ) 00123 00124 00128 #define YUI_THROW_MSG( EXCEPTION_TYPE, MSG ) \ 00129 YUI_THROW( EXCEPTION_TYPE( MSG ) ) 00130 00131 00135 #define YUI_THROW_ERRNO( EXCEPTION_TYPE ) \ 00136 YUI_THROW( EXCEPTION_TYPE( YUIException::strErrno( errno ) ) ) 00137 00141 #define YUI_THROW_ERRNO1( EXCEPTION_TYPE, ERRNO ) \ 00142 YUI_THROW( EXCEPTION_TYPE( YUIException::strErrno( ERRNO ) ) ) 00143 00147 #define YUI_THROW_ERRNO_MSG( EXCEPTION_TYPE, MSG) \ 00148 YUI_THROW( EXCEPTION_TYPE( YUIException::strErrno( errno, MSG ) ) ) 00149 00153 #define YUI_THROW_ERRNO_MSG1( EXCEPTION_TYPE, ERRNO,MSG ) \ 00154 YUI_THROW( EXCEPTION_TYPE( YUIException::strErrno( ERRNO, MSG ) ) ) 00155 00156 00157 // 00158 // Higher-level (UI specific) exception macros 00159 // 00160 00165 #define YUI_CHECK_NEW( PTR ) \ 00166 do \ 00167 { \ 00168 if ( ! (PTR) ) \ 00169 { \ 00170 YUI_THROW( YUIOutOfMemoryException() ); \ 00171 } \ 00172 } while( 0 ) 00173 00174 00175 00180 #define YUI_CHECK_PTR( PTR ) \ 00181 do \ 00182 { \ 00183 if ( ! (PTR) ) \ 00184 { \ 00185 YUI_THROW( YUINullPointerException() ); \ 00186 } \ 00187 } while( 0 ) 00188 00189 00194 #define YUI_CHECK_WIDGET( WIDGET ) \ 00195 do \ 00196 { \ 00197 if ( ! (WIDGET) || ! (WIDGET)->isValid() ) \ 00198 { \ 00199 YUI_THROW( YUIInvalidWidgetException() ); \ 00200 } \ 00201 } while( 0 ) 00202 00203 00210 #define YUI_CHECK_INDEX_MSG( INDEX, VALID_MIN, VALID_MAX, MSG ) \ 00211 do \ 00212 { \ 00213 if ( (INDEX) < (VALID_MIN) || \ 00214 (INDEX) > (VALID_MAX) ) \ 00215 { \ 00216 YUI_THROW( YUIIndexOutOfRangeException( (INDEX), (VALID_MIN), (VALID_MAX), (MSG) ) ); \ 00217 } \ 00218 } while( 0 ) 00219 00220 00221 #define YUI_CHECK_INDEX( INDEX, VALID_MIN, VALID_MAX ) \ 00222 YUI_CHECK_INDEX_MSG( (INDEX), (VALID_MIN), (VALID_MAX), "") 00223 00224 00225 00226 00231 class YCodeLocation 00232 { 00233 public: 00238 YCodeLocation( const string & file_r, 00239 const string & func_r, 00240 int line_r ) 00241 : _file( file_r ) 00242 , _func( func_r ) 00243 , _line( line_r ) 00244 {} 00245 00249 YCodeLocation() 00250 : _line( 0 ) 00251 {} 00252 00256 string file() const { return _file; } 00257 00261 string func() const { return _func; } 00262 00266 int line() const { return _line; } 00267 00271 string asString() const; 00272 00276 friend ostream & operator<<( ostream & str, const YCodeLocation & obj ); 00277 00278 private: 00279 string _file; 00280 string _func; 00281 int _line; 00282 00283 }; // YCodeLocation 00284 00285 00289 ostream & operator<<( ostream & str, const YCodeLocation & obj ); 00290 00291 00299 class YUIException : public std::exception 00300 { 00301 public: 00306 YUIException(); 00307 00312 YUIException( const string & msg_r ); 00313 00317 virtual ~YUIException() throw(); 00318 00322 const YCodeLocation & where() const 00323 { return _where; } 00324 00328 void relocate( const YCodeLocation & newLocation ) const 00329 { _where = newLocation; } 00330 00336 const string & msg() const 00337 { return _msg; } 00338 00342 void setMsg( const string & msg ) 00343 { _msg = msg; } 00344 00348 string asString() const; 00349 00353 static string strErrno( int errno_r ); 00354 00358 static string strErrno( int errno_r, const string & msg ); 00359 00364 static void log( const YUIException & exception, 00365 const YCodeLocation & location, 00366 const char * const prefix ); 00372 virtual const char * what() const throw() 00373 { return _msg.c_str(); } 00374 00375 protected: 00376 00380 virtual ostream & dumpOn( ostream & str ) const; 00381 00382 00383 private: 00384 friend ostream & operator<<( ostream & str, const YUIException & obj ); 00385 00386 00387 mutable YCodeLocation _where; 00388 string _msg; 00389 00394 ostream & dumpError( ostream & str ) const; 00395 00396 }; // class YUIException 00397 00398 00402 ostream & operator<<( ostream & str, const YUIException & obj ); 00403 00404 00409 class YUINullPointerException: public YUIException 00410 { 00411 public: 00412 YUINullPointerException() 00413 : YUIException( "Null pointer" ) 00414 {} 00415 00416 virtual ~YUINullPointerException() throw() 00417 {} 00418 }; 00419 00420 00425 class YUIOutOfMemoryException: public YUIException 00426 { 00427 public: 00428 YUIOutOfMemoryException() 00429 : YUIException( "Out of memory" ) 00430 {} 00431 00432 virtual ~YUIOutOfMemoryException() throw() 00433 {} 00434 00435 }; 00436 00442 class YUIInvalidWidgetException: public YUIException 00443 { 00444 public: 00445 YUIInvalidWidgetException() 00446 : YUIException( "Invalid widget" ) 00447 {} 00448 00449 virtual ~YUIInvalidWidgetException() throw() 00450 {} 00451 }; 00452 00453 00457 class YUIWidgetNotFoundException: public YUIException 00458 { 00459 public: 00460 YUIWidgetNotFoundException( const string & idString ) 00461 : YUIException( string( "No widget with ID " ) + idString ) 00462 {} 00463 00464 virtual ~YUIWidgetNotFoundException() throw() 00465 {} 00466 }; 00467 00468 00469 class YUINoDialogException: public YUIException 00470 { 00471 public: 00472 YUINoDialogException() 00473 : YUIException( "No dialog existing" ) 00474 {} 00475 00476 virtual ~YUINoDialogException() throw() 00477 {} 00478 }; 00479 00480 00481 class YUIDialogStackingOrderException: public YUIException 00482 { 00483 public: 00484 YUIDialogStackingOrderException() 00485 : YUIException( "Dialog stacking order violated" ) 00486 {} 00487 00488 virtual ~YUIDialogStackingOrderException() throw() 00489 {} 00490 }; 00491 00492 00493 class YUISyntaxErrorException: public YUIException 00494 { 00495 public: 00496 YUISyntaxErrorException( const string & msg ) 00497 : YUIException( msg ) 00498 {} 00499 00500 virtual ~YUISyntaxErrorException() throw() 00501 {} 00502 }; 00503 00504 00508 class YUIPropertyException: public YUIException 00509 { 00510 protected: 00511 YUIPropertyException( const YProperty & prop, 00512 YWidget * widget = 0 ) 00513 : YUIException() 00514 , _property( prop ) 00515 , _widget( widget ) 00516 {} 00517 00518 virtual ~YUIPropertyException() throw() 00519 {} 00520 00521 public: 00525 YProperty property() const { return _property; } 00526 00530 YWidget * widget() const { return _widget; } 00531 00535 void setWidget( YWidget * w ) { _widget = w; } 00536 00537 protected: 00538 00543 virtual ostream & dumpOn( ostream & str ) const = 0; 00544 00545 private: 00546 YProperty _property; 00547 YWidget * _widget; 00548 }; 00549 00550 00555 class YUIUnknownPropertyException: public YUIPropertyException 00556 { 00557 public: 00558 YUIUnknownPropertyException( const string & propertyName, 00559 YWidget * widget = 0 ) 00560 : YUIPropertyException( YProperty( propertyName, YUnknownPropertyType ), widget ) 00561 {} 00562 00563 virtual ~YUIUnknownPropertyException() throw() 00564 {} 00565 00566 protected: 00567 00572 virtual ostream & dumpOn( ostream & str ) const; 00573 }; 00574 00575 00580 class YUIPropertyTypeMismatchException: public YUIPropertyException 00581 { 00582 public: 00583 00584 YUIPropertyTypeMismatchException( const YProperty & property, 00585 YPropertyType type, 00586 YWidget * widget = 0 ) 00587 : YUIPropertyException( property, widget ) 00588 , _type( type ) 00589 {} 00590 00591 virtual ~YUIPropertyTypeMismatchException() throw() 00592 {} 00593 00597 YPropertyType type() const { return _type; } 00598 00599 protected: 00600 00605 virtual ostream & dumpOn( ostream & str ) const; 00606 00607 private: 00608 YPropertyType _type; 00609 }; 00610 00611 00615 class YUISetReadOnlyPropertyException: public YUIPropertyException 00616 { 00617 public: 00618 00619 YUISetReadOnlyPropertyException( const YProperty & property, 00620 YWidget * widget = 0 ) 00621 : YUIPropertyException( property, widget ) 00622 {} 00623 00624 virtual ~YUISetReadOnlyPropertyException() throw() 00625 {} 00626 00627 protected: 00628 00633 virtual ostream & dumpOn( ostream & str ) const; 00634 }; 00635 00636 00637 class YUIBadPropertyArgException: public YUIPropertyException 00638 { 00639 public: 00640 00641 YUIBadPropertyArgException( const YProperty & property, 00642 YWidget * widget, 00643 const string & message = "" ) 00644 : YUIPropertyException( property, widget ) 00645 { setMsg( message ); } 00646 00647 virtual ~YUIBadPropertyArgException() throw() 00648 {} 00649 00650 protected: 00651 00656 virtual ostream & dumpOn( ostream & str ) const; 00657 }; 00658 00659 00665 template<class YWidget> class YUITooManyChildrenException: public YUIException 00666 { 00667 public: 00668 00669 YUITooManyChildrenException( YWidget * container ) 00670 : YUIException( "Too many children" ) 00671 , _container( container ) 00672 {} 00673 00674 virtual ~YUITooManyChildrenException() throw() 00675 {} 00676 00680 YWidget * container() const { return _container; } 00681 00682 protected: 00683 00688 virtual ostream & dumpOn( ostream & str ) const 00689 { 00690 string widgetClass = 00691 container() ? container()->widgetClass() : 00692 "widget"; 00693 00694 return str << "Too many children for " 00695 << widgetClass 00696 << endl; 00697 } 00698 00699 private: 00700 00701 YWidget * _container; 00702 }; 00703 00704 00714 template<class YWidget> class YUIInvalidChildException: public YUIException 00715 { 00716 public: 00717 00718 YUIInvalidChildException( YWidget * container, 00719 YWidget * child = 0 ) 00720 : YUIException( "Invalid child" ) 00721 , _container( container ) 00722 , _child( child ) 00723 {} 00724 00725 virtual ~YUIInvalidChildException() throw() 00726 {} 00727 00731 YWidget * container() const { return _container; } 00732 00736 YWidget * child() const { return _child; } 00737 00738 protected: 00739 00744 virtual ostream & dumpOn( ostream & str ) const 00745 { 00746 string containerWidgetClass = 00747 container() ? container()->widgetClass() : 00748 "widget"; 00749 00750 string childWidgetClass = 00751 child() ? child()->widgetClass() : 00752 "<Null>"; 00753 00754 return str << childWidgetClass 00755 << " is not a child of " 00756 << containerWidgetClass 00757 << endl; 00758 } 00759 00760 private: 00761 00762 YWidget * _container; 00763 YWidget * _child; 00764 }; 00765 00766 00767 00777 class YUIUnsupportedWidgetException: public YUIException 00778 { 00779 public: 00780 00781 YUIUnsupportedWidgetException( const string & widgetType ) 00782 : YUIException( string( "Unsupported optional widget type: " ) + widgetType ) 00783 {} 00784 00785 virtual ~YUIUnsupportedWidgetException() throw() 00786 {} 00787 }; 00788 00789 00794 class YUIInvalidDimensionException: public YUIException 00795 { 00796 public: 00797 YUIInvalidDimensionException() 00798 : YUIException( "Invalid dimension (neither YD_HORIZ nor YD_VERT)" ) 00799 {} 00800 00801 virtual ~YUIInvalidDimensionException() throw() 00802 {} 00803 }; 00804 00805 00809 class YUIIndexOutOfRangeException: public YUIException 00810 { 00811 public: 00820 YUIIndexOutOfRangeException( int invalidIndex, 00821 int validMin, 00822 int validMax, 00823 const string & msg = "" ) 00824 : YUIException( msg ) 00825 , _invalidIndex( invalidIndex ) 00826 , _validMin( validMin ) 00827 , _validMax( validMax ) 00828 {} 00829 00830 virtual ~YUIIndexOutOfRangeException() throw() 00831 {} 00832 00836 int invalidIndex() const { return _invalidIndex; } 00837 00841 int validMin() const { return _validMin; } 00842 00846 int validMax() const { return _validMax; } 00847 00848 protected: 00849 00854 virtual ostream & dumpOn( ostream & str ) const 00855 { 00856 string prefix = msg(); 00857 00858 if ( prefix.empty() ) 00859 prefix = "Index out of range"; 00860 00861 return str << prefix << ": " << _invalidIndex 00862 << " valid: " << _validMin << " .. " << _validMax 00863 << endl; 00864 } 00865 00866 private: 00867 00868 int _invalidIndex; 00869 int _validMin; 00870 int _validMax; 00871 }; 00872 00873 00877 class YUIPluginException: public YUIException 00878 { 00879 public: 00880 YUIPluginException( const string & pluginName ) 00881 : YUIException( string( "Couldn't load plug-in " ) + pluginName ) 00882 {} 00883 00884 virtual ~YUIPluginException() throw() 00885 {} 00886 }; 00887 00888 00892 class YUICantLoadAnyUIException: public YUIException 00893 { 00894 public: 00895 YUICantLoadAnyUIException() 00896 : YUIException( "No $DISPLAY and stdout is not a tty" ) 00897 {} 00898 00899 virtual ~YUICantLoadAnyUIException() throw() 00900 {} 00901 }; 00902 00903 00907 class YUIButtonRoleMismatchException: public YUIException 00908 { 00909 public: 00910 00911 YUIButtonRoleMismatchException( const string & msg ) 00912 : YUIException( msg ) 00913 {} 00914 00915 virtual ~YUIButtonRoleMismatchException() throw() 00916 {} 00917 }; 00918 00919 00920 // 00921 // Helper templates 00922 // 00923 00924 00928 template<class _Exception> 00929 void _YUI_THROW( const _Exception & exception_r, const YCodeLocation & where_r ) 00930 { 00931 exception_r.relocate( where_r ); 00932 YUIException::log( exception_r, where_r, "THROW: " ); 00933 throw( exception_r ); 00934 } 00935 00936 00940 template<class _Exception> 00941 void _YUI_CAUGHT( const _Exception & exception_r, const YCodeLocation & where_r ) 00942 { 00943 YUIException::log( exception_r, where_r, "CAUGHT: " ); 00944 } 00945 00946 00950 template<class _Exception> 00951 void _YUI_RETHROW( const _Exception & exception_r, const YCodeLocation & where_r ) 00952 { 00953 YUIException::log( exception_r, where_r, "RETHROW: " ); 00954 exception_r.relocate( where_r ); 00955 throw; 00956 } 00957 00958 00959 #endif // YUIException_h