#ifndef __ERROR_EXCEPTION_AH__ #define __ERROR_EXCEPTION_AH__ #include #include #include #include #include #include "LinuxError.h" aspect ThrowLinuxErrors { template< class TJP, int N > struct stream_params { static void process( std::ostream& os, TJP* tjp ) { os << *(tjp->template arg< TJP::ARGS - N >()) << ", "; stream_params< TJP, N - 1 >::process( os, tjp ); } }; template struct stream_params< TJP, 1 > { static void process( std::ostream& os, TJP* tjp ) { os << *(tjp->template arg< TJP::ARGS - 1 >()); } }; template struct stream_params< TJP, 0 > { static void process( std::ostream& os, TJP* tjp ) { } }; static void stream_header( std::ostream& os, const char* sig, int code ) { os << "LINUX ERROR " << errno << ": " << GetErrorText( code ) << std::endl; os << "WHILE CALLING: " << sig << std::endl; os << "WITH: "; os << "("; } static void stream_footer_and_throw( std::ostringstream& os, int code ) { os << ")"; throw Exception( os.str(), code ); } advice call( Linux() ) : after() { // Dummy access, to ensure ac++ includes arguments in the TJP structure if (JoinPoint::ARGS>0) { void* p = tjp->arg(0); } if( IsErrorResult(tjp->result()) ) { std::ostringstream os; stream_header( os, tjp->signature(), errno ); stream_params< JoinPoint, JoinPoint::ARGS >::process( os, tjp ); stream_footer_and_throw( os, errno ); } } }; aspect CatchLinuxErrors { advice execution( "% main(...)" ) : around() { try { tjp->proceed(); } catch( Exception& e ) { std::cerr << "An exception occured: " << e.where << " " << std::endl; } } }; #endif // __ERROR_EXCEPTION_AH__