//================================================================================================== // S t a n d a r d Interface // E r r o r // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides facilities to manage errors. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "standard/error.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guStandardError #define guStandardError
// Headers //--------------------------------------------------------------------------------------- #include <stdexcept> /*INCLUDE*/ #include <bpp/standard/environment.hpp> /*INCLUDE*/ #include <bpp/standard/type.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef STANDARD_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area standardError #define private_area standardError_private
namespace public_area { /*NAMESPACE*/ using namespace standardType; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //-------------------------------------------------------------------------------- #define iniStandardError has_initializer;
// Macrocommands //--------------------------------------------------------------------------------- #ifdef EVENT_SPY_MODE /*MACROCOMMAND*/ /* The expression <CODE>prLine</CODE> is integrated into the source code if <CODE>EVENT_SPY_MODE</CODE> is defined. */ #define event_spy_mode(prLine) prLine
/*MACROCOMMAND*/ /* Gives a name to a method or function that can be then traced (do not use it with inline methods and functions). */ #define method_name(prMethodName) \ const standardError_private::clEventSpy _spy_(prMethodName,private_area::goModuleName) \
/*MACROCOMMAND*/ /* Sends an error message from a traceable method or function. */ #define send_error(prError) \ ( (prError).module()=private_area::goModuleName, (prError).method()=_spy_.method(), \ (prError).file()=__FILE__, (prError).line()=__LINE__+1, standardError::throwError(prError) ) \
/*MACROCOMMAND*/ /* Sends an error message from an inline method or function. <CODE>prMethodName</CODE> is the name of the method or function from which the error is sent. */ #define send_inline_error(prError,prMethodName) \ ( (prError).module()=private_area::goModuleName, (prError).method()=prMethodName, \ (prError).file()=__FILE__, (prError).line()=__LINE__+1, standardError::throwError(prError) ) \
#else #define event_spy_mode(prLine)
#define method_name(prMethodName) static const tcString _methodName_ = prMethodName
#define send_error(prError) \ ( (prError).module()=private_area::goModuleName, (prError).method()=_methodName_, \ (prError).file()=__FILE__, (prError).line()=__LINE__+1, standardError::throwError(prError) ) \
#define send_inline_error(prError,prMethodName) \ ( (prError).module()=private_area::goModuleName, (prError).method()=prMethodName, \ (prError).file()=__FILE__, (prError).line()=__LINE__+1, standardError::throwError(prError) ) \
#endif
#ifdef TESTING_MODE /*MACROCOMMAND*/ /* Activated if <CODE>TESTING_MODE</CODE> is defined. Sends an error message if <CODE>prCondition</CODE> is evaluated to <CODE>false</CODE>. */ #define assertion(prCondition,prError) if (not (prCondition)) send_error(prError)
/*MACROCOMMAND*/ /* Activated if <CODE>TESTING_MODE</CODE> is defined. Displays a flag for the debugging. */ #define flag(prFlag) { \ environment::out("Flag ",false,true); environment::out(#prFlag,false); \ environment::out(" [",false); environment::out(__FILE__,false); \ environment::out("][",false); environment::out(tyCardinal(__LINE__+1),false); \ environment::out("]",true); } \
/*MACROCOMMAND*/ /* Activated if <CODE>TESTING_MODE</CODE> is defined. Displays the value of a variable for the debugging. */ #define spy(prVariable) { \ environment::out(#prVariable,false,true); \ environment::out(" = "); \ environment::out(prVariable,true); } \
#else #define assertion(prCondition,prError) #define flag(prFlag) #define spy(prVariable) #endif
/*MACROCOMMAND*/ /* Default error handling for initializers. */ #define initializer_catch \ catch (ctError & agError) { outError(agError); environment::terminate(); } \ catch (tcString agMessage) { outError(agMessage); environment::terminate(); } \ catch (ctException & agException) { outException(agException); environment::terminate(); } \ catch (...) { outUnexpectedError(); environment::terminate(); } \
/*MACROCOMMAND*/ /* Default error handling for programs. */ #define program_catch \ catch (ctError & agError) { \ outError(agError); \ if (environment::informationDisplayed()) environment::nextLine(); \ clearError(); \ return (environment::quit(environment::failure)); \ } \ \ catch (tcString agMessage) { \ outError(agMessage); \ if (environment::informationDisplayed()) environment::nextLine(); \ clearError(); \ return (environment::quit(environment::failure)); \ } \ \ catch (ctException & agException) { \ outException(agException); \ if (environment::informationDisplayed()) environment::nextLine(); \ clearError(); \ return (environment::quit(environment::failure)); \ } \ \ catch (...) { \ outUnexpectedError(); \ if (environment::informationDisplayed()) environment::nextLine(); \ clearError(); \ return (environment::quit(environment::failure)); \ } \ \ if (environment::informationDisplayed()) environment::nextLine(); \ return (environment::quit(environment::success)); \
// Types & Classes //------------------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------------------Classes class clError; //-----------------------------------------------------------------------------------Variable Types /*TYPE*/ /* Exception sent by the STL. */ typedef std_exception clException;
/*TYPE*/ /* List of errors sent by the B++ Library. */ typedef std_vector(const clError *) clErrorS; //-----------------------------------------------------------------------------------Constant Types typedef const clError ctError; typedef const clErrorS ctErrorS; typedef const clException ctException; }
namespace private_area { #ifdef EVENT_SPY_MODE class clEventSpy; typedef std_vector(tcString) clStringS; enumeration { start, end } tyEventKind; typedef std_vector(tyEventKind) clEventKindS; #endif
typedef std::ostream clOutStream; }
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { inline tyBoolean operator == (ctError &,ctError &);
function void outError(ctError &); function void outError(private_area::clOutStream &,ctError &); function void outError(tcString); function void outError(private_area::clOutStream &,tcString); function void outException(ctException &); function void outException(private_area::clOutStream &,ctException &); function void outUnexpectedError(void); function void outUnexpectedError(private_area::clOutStream &);
event_spy_mode ( function void outTrace(private_area::clOutStream &); )
function void throwError(ctError &); function void clearError(void); }
namespace private_area { testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area { /*ERROR*/ extern_error erInvalidErrorNumber; /* Invalid error number. */ /*ERROR*/ extern_error erNone; /* No error. */ /*ERROR*/ extern_error erUnexpected; /* Unexpected error. */
/*ERROR*/ extern_error erDataLocationParameterMissing; /* The <CODE>data_location</CODE> parameter is missing in the initialization file. */
/*ERROR*/ extern_error erTemporaryLocationParameterMissing; /* The <CODE>temporary_location</CODE> parameter is missing in the initialization file. */
testing_mode ( /*ERROR*/ extern_error erTestingLocationParameterMissing; /* The <CODE>testing_location</CODE> parameter is missing in the initialization file. */ )
extern_error erCreateThread; extern_error erMutexNotAvailable; extern_error erMutexUnlocked; }
// Constants & Variables //------------------------------------------------------------------------- /*CONSTANT*/ /* List of the errors declared in the B++ Library. */ extern_dynamic_constant(public,clErrorS,goErrorS,errors);
/*VARIABLE*/ /* Indicates if an error has been thrown. */ extern_static_constant(public,tyBoolean,goErrorThrown,errorThrown);
/*VARIABLE*/ /* Returns the pending error that is currently being thrown. */ extern_dynamic_constant(public,ctError,goCurrentError,currentError);
extern_static_constant(private,clMutex,goErrorMutex,?);
event_spy_mode ( extern_dynamic_constant(private,clEventKindS,goEventKindS,?); extern_dynamic_constant(private,clStringS,goMethodS,?); extern_dynamic_constant(private,clStringS,goModuleS,?); extern_static_constant(private,clMutex,goSpyMutex,?);
extern_static_constant(private,tcString,goEventTraceFileName,?); extern_static_constant(private,tyCardinal,goTraceSize,?); )
// E r r o r Interface //-------------------------------------------------------------------------- namespace public_area { /*CLASS clError */ /* Represents an error sent by the B++ Library. */ class clError { //-----------------------------------------------------------------------------------------Friends friend inline tyBoolean operator == (ctError &,ctError &); //-----------------------------------------------------------------------------------------Private private_property clError & operator = (ctError &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clError */ /* Message of the error. */ read_only_attribute(tcString,atMessage,message);
/*ATTRIBUTE clError */ /* Number of the error. */ read_only_attribute(tyCardinal,atNumber,number);
/*ATTRIBUTE clError */ /* Module where the error occurs. */ read_write_attribute(tcString,atModule,module);
/*ATTRIBUTE clError */ /* Method where the error occurs. */ read_write_attribute(tcString,atMethod,method);
/*ATTRIBUTE clError */ /* File where the error occurs. */ read_write_attribute(tcString,atFile,file);
/*ATTRIBUTE clError */ /* Line where the error occurs. */ read_write_attribute(tyCardinal,atLine,line);
public_property constructor clError(void); public_property constructor clError(ctError &); public_property destructor clError(void) {}
public_property void create(tcString); }; }
// E v e n t S p y Interface //-------------------------------------------------------------------- event_spy_mode ( namespace private_area { class clEventSpy { private_property constructor clEventSpy(const clEventSpy &); private_property clEventSpy & operator = (const clEventSpy &);
read_only_attribute(tcString,atMethod,method); read_only_attribute(tcString,atModule,module);
public_property constructor clEventSpy(tcString,tcString); public_property destructor clEventSpy(void); }; } )
// Functions Inline //------------------------------------------------------------------------------ namespace public_area { //--------------------------------------------------------------------------------------Operator == /*FUNCTION*/ /* Checks if two errors are the same. */ inline tyBoolean operator == (ctError & agError1,ctError & agError2) { return (agError1.number()==agError2.number()); } }
namespace private_area {}
// E r r o r Inline //----------------------------------------------------------------------------- namespace public_area { //---------------------------------------------------------------------------------Copy Constructor /*METHOD clError */ /* Builds an error from another one. */ inline clError::clError(ctError & agError) : atMessage(agError.atMessage), atNumber(agError.atNumber), atModule(agError.atModule), atMethod(agError.atMethod), atFile(agError.atFile), atLine(agError.atLine) {} //------------------------------------------------------------------------------Default Constructor /*METHOD clError */ /* Builds a default error. */ inline clError::clError(void) : atMessage(), atNumber(), atModule(), atMethod(), atFile(), atLine(0) {} }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef public_area #undef private_area #endif |
//================================================================================================== // S t a n d a r d Implementation // E r r o r // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "standard/error.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define STANDARD_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/file_name.hpp> /*NEED*/ #include <bpp/standard/class.hpp> /*NEED*/ #include <bpp/standard/error.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area standardError #define private_area standardError_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area { using namespace standardBasicString; }
static_module_name("Standard/Error");
// Initialization //-------------------------------------------------------------------------------- #undef iniStandardError static_constant(private_area::clInitializer,goInitializer);
// Errors //---------------------------------------------------------------------------------------- namespace public_area { static_error erInvalidErrorNumber; static_error erNone; static_error erUnexpected;
static_error erDataLocationParameterMissing; static_error erTemporaryLocationParameterMissing;
testing_mode ( static_error erTestingLocationParameterMissing; )
static_error erCreateThread; static_error erMutexNotAvailable; static_error erMutexUnlocked; }
// Constants & Variables //------------------------------------------------------------------------- dynamic_constant(clErrorS,goErrorS); static_constant(tyBoolean,goErrorThrown); dynamic_constant(ctError,goCurrentError); static_constant(clMutex,goErrorMutex);
event_spy_mode ( dynamic_constant(clEventKindS,goEventKindS); dynamic_constant(clStringS,goMethodS); dynamic_constant(clStringS,goModuleS); static_constant(clMutex,goSpyMutex);
static_constant(tcString,goEventTraceFileName); static_constant(tyCardinal,goTraceSize); )
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //-----------------------------------------------------------------------------------------OutError /*FUNCTION*/ /* Displays information about an error. */ function void outError(ctError & agError) { using namespace environment;
environment_private::clOutFile lcFout;
nextLine(); inform("-=-=- E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"); out(" The following error has occurred:",true,true); out(" Number = ",false,true); out(agError.number(),true); out(" Message = ",false,true); out(agError.message(),true); out(" Module = ",false,true); out(agError.module(),true); out(" Method = ",false,true); out(agError.method(),true); out(" File = ",false,true); out(agError.file(),true); out(" Line = ",false,true); out(agError.line(),true); nextLine(); out(" Flags = ",false,true); outFlags(); nextLine(); out(" Environment Variable = ",false,true); out(BPP_TOOLS_ENVIRONMENT_VARIABLE,true); out(" Random Seed = ",false,true); out(environment::randomSeed(),true); out(" Starting Date = ",false,true); out(environment::startingDate(),true); out(" Elapsed Hundredths = ",false,true); out(tyInteger(currentClock()-startingClock()),true);
event_spy_mode ( nextLine(); out(" For more details, see the '",false,true); out(private_area::goEventTraceFileName); out("' file.",true); )
out("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-",true,true);
event_spy_mode ( lcFout.open(private_area::goEventTraceFileName,ios::out|ios::trunc); lcFout << "===============================================================================" << end_line; lcFout << " E v e n t s T r a c e Debugging Information" << end_line; lcFout << "===============================================================================" << end_line; lcFout << end_line; outInformation(lcFout); lcFout << end_line; lcFout << "[>] Last Events Registered:" << end_line; lcFout << end_line; outTrace(lcFout); lcFout << end_line; outError(lcFout,agError); lcFout << end_line; lcFout << "===============================================================================" << end_line; lcFout.close(); ) } //-----------------------------------------------------------------------------------------OutError /*FUNCTION*/ /* Writes into a stream information about an error. */ function void outError(private_area::clOutStream & agStream,ctError & agError) { using namespace environment;
agStream << "[!] -=-=- E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; agStream << " The following error has occurred:" << end_line; agStream << " Number = " << agError.number() << end_line; agStream << " Message = " << agError.message() << end_line; agStream << " Module = " << agError.module() << end_line; agStream << " Method = " << agError.method() << end_line; agStream << " File = " << agError.file() << end_line; agStream << " Line = " << agError.line() << end_line; agStream << end_line; agStream << " Flags = "; outFlags(agStream); agStream << end_line; agStream << " Environment Variable = " << BPP_TOOLS_ENVIRONMENT_VARIABLE << end_line; agStream << " Random Seed = " << randomSeed() << end_line; agStream << " Starting Date = " << startingDate() << end_line; agStream << " Elapsed Hundredths = " << tyInteger(currentClock()-startingClock()) << end_line; agStream << " -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; } //-----------------------------------------------------------------------------------------OutError /*FUNCTION*/ /* Displays information about a non declared error. */ function void outError(tcString agMessage) { using namespace environment;
environment_private::clOutFile lcFout;
nextLine(); inform("-=-=- E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"); out(" The following error has occurred:",true,true); out(" Message = ",false,true); out(agMessage,true); nextLine(); out(" Flags = ",false,true); outFlags(); nextLine(); out(" Environment Variable = ",false,true); out(BPP_TOOLS_ENVIRONMENT_VARIABLE,true); out(" Random Seed = ",false,true); out(randomSeed(),true); out(" Starting Date = ",false,true); out(startingDate(),true); out(" Elapsed Hundredths = ",false,true); out(tyInteger(currentClock()-startingClock()),true);
event_spy_mode ( nextLine(); out(" For more details, see the '",false,true); out(private_area::goEventTraceFileName); out("' file.",true); )
out("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-",true,true);
event_spy_mode ( lcFout.open(private_area::goEventTraceFileName,ios::out|ios::trunc); lcFout << "===============================================================================" << end_line; lcFout << " E v e n t s T r a c e Debugging Information" << end_line; lcFout << "===============================================================================" << end_line; lcFout << end_line; outInformation(lcFout); lcFout << end_line; lcFout << "[>] Last Events Registered:" << end_line; lcFout << end_line; outTrace(lcFout); lcFout << end_line; outError(lcFout,agMessage); lcFout << end_line; lcFout << "===============================================================================" << end_line; lcFout.close(); ) } //-----------------------------------------------------------------------------------------OutError /*FUNCTION*/ /* Writes into a stream information about a non declared error. */ function void outError(private_area::clOutStream & agStream,tcString agMessage) { using namespace environment;
agStream << "[!] -=-=- E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; agStream << " The following error has occurred:" << end_line; agStream << " Message = " << agMessage << end_line; agStream << end_line; agStream << " Flags = "; outFlags(agStream); agStream << end_line; agStream << " Environment Variable = " << BPP_TOOLS_ENVIRONMENT_VARIABLE << end_line; agStream << " Random Seed = " << randomSeed() << end_line; agStream << " Starting Date = " << startingDate() << end_line; agStream << " Elapsed Hundredths = " << (tyInteger(currentClock()-startingClock())) << end_line; agStream << " -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; } //-------------------------------------------------------------------------------------OutException /*FUNCTION*/ /* Displays information about an STL exception. */ function void outException(ctException & agException) { using namespace environment;
environment_private::clOutFile lcFout;
nextLine(); inform("-=-=- S T L E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"); out(" The following error has occurred:",true,true); out(" Message = ",false,true); out(agException.what(),true); nextLine(); out(" Flags = ",false,true); outFlags(); nextLine(); out(" Environment Variable = ",false,true); out(BPP_TOOLS_ENVIRONMENT_VARIABLE,true); out(" Random Seed = ",false,true); out(randomSeed(),true); out(" Starting Date = ",false,true); out(startingDate(),true); out(" Elapsed Hundredths = ",false,true); out(tyInteger(currentClock()-startingClock()),true);
event_spy_mode ( nextLine(); out(" For more details, see the '",false,true); out(private_area::goEventTraceFileName); out("' file.",true); )
out("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-",true,true);
event_spy_mode ( lcFout.open(private_area::goEventTraceFileName,ios::out|ios::trunc); lcFout << "===============================================================================" << end_line; lcFout << " E v e n t s T r a c e Debugging Information" << end_line; lcFout << "===============================================================================" << end_line; lcFout << end_line; outInformation(lcFout); lcFout << end_line; lcFout << "[>] Last Events Registered:" << end_line; lcFout << end_line; outTrace(lcFout); lcFout << end_line; outException(lcFout,agException); lcFout << end_line; lcFout << "===============================================================================" << end_line; lcFout.close(); ) } //-------------------------------------------------------------------------------------OutException /*FUNCTION*/ /* Writes into a stream information about an STL exception. */ function void outException(private_area::clOutStream & agStream,ctException & agException) { using namespace environment;
agStream << "[!] -=-=- S T L E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; agStream << " The following error has occurred:" << end_line; agStream << " Message = " << agException.what() << end_line; agStream << end_line; agStream << " Flags = "; outFlags(agStream); agStream << end_line; agStream << " Environment Variable = " << BPP_TOOLS_ENVIRONMENT_VARIABLE << end_line; agStream << " Random Seed = " << randomSeed() << end_line; agStream << " Starting Date = " << startingDate() << end_line; agStream << " Elapsed Hundredths = " << (tyInteger(currentClock()-startingClock())) << end_line; agStream << " -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; } //-------------------------------------------------------------------------------OutUnexpectedError /*FUNCTION*/ /* Displays the context of the program when an unexpected error occurs. */ function void outUnexpectedError(void) { using namespace environment;
environment_private::clOutFile lcFout;
nextLine(); inform("-=-=- E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"); out(" An unexpected error has occurred.",true,true); nextLine(); out(" Flags = ",false,true); outFlags(); nextLine(); out(" Environment Variable = ",false,true); out(BPP_TOOLS_ENVIRONMENT_VARIABLE,true); out(" Random Seed = ",false,true); out(randomSeed(),true); out(" Starting Date = ",false,true); out(startingDate(),true); out(" Elapsed Hundredths = ",false,true); out(tyInteger(currentClock()-startingClock()),true);
event_spy_mode ( nextLine(); out(" For more details, see the '",false,true); out(private_area::goEventTraceFileName); out("' file.",true); )
out("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-",true,true);
event_spy_mode ( lcFout.open(private_area::goEventTraceFileName,ios::out|ios::trunc); lcFout << "===============================================================================" << end_line; lcFout << " E v e n t s T r a c e Debugging Information" << end_line; lcFout << "===============================================================================" << end_line; lcFout << end_line; outInformation(lcFout); lcFout << end_line; lcFout << "[>] Last Events Registered:" << end_line; lcFout << end_line; outTrace(lcFout); lcFout << end_line; outUnexpectedError(lcFout); lcFout << end_line; lcFout << "===============================================================================" << end_line; lcFout.close(); ) } //------------------------------------------------------------------------------OutUnexepectedError /*FUNCTION*/ /* Writes into a stream the context of the program when an unexpected error occurs. */ function void outUnexpectedError(private_area::clOutStream & agStream) { using namespace environment;
agStream << "[!] -=-=- E R R O R -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; agStream << " An unexpected error has occurred." << end_line; agStream << end_line; agStream << " Flags = "; outFlags(agStream); agStream << end_line; agStream << " Environment Variable = " << BPP_TOOLS_ENVIRONMENT_VARIABLE << end_line; agStream << " Random Seed = " << randomSeed() << end_line; agStream << " Starting Date = " << startingDate() << end_line; agStream << " Elapsed Hundredths = " << (tyInteger(currentClock()-startingClock())) << end_line; agStream << " -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << end_line; } //-----------------------------------------------------------------------------------------OutTrace event_spy_mode ( /*FUNCTION*/ /* Writes into a stream the trace of the method and function calls. */ function void outTrace(private_area::clOutStream & agStream) { using namespace private_area;
safe_yes ( private_area::goSpyMutex.lock(); )
clString lcBlankSpace("");
tyCardinal lcCounter = goEventKindS->size();
if (goEventKindS->size()==0) agStream << " None" << end_line;
while (lcCounter>0) { lcCounter--;
if ((*goEventKindS)[lcCounter]==start) { agStream << " Event: " << lcBlankSpace << "=> " << (*goModuleS)[lcCounter] << " - "; agStream << (*goMethodS)[lcCounter] << end_line; lcBlankSpace+=" "; } else { if (lcBlankSpace.size()>2) lcBlankSpace.resize(lcBlankSpace.size()-3); agStream << " Event: " << lcBlankSpace << "<= " << (*goModuleS)[lcCounter] << " - "; agStream << (*goMethodS)[lcCounter] << end_line; } }
safe_yes ( private_area::goSpyMutex.release(); ) } ) //---------------------------------------------------------------------------------------ClearError /*FUNCTION*/ /* Clears any pending error that is currently being thrown. */ function void clearError(void) { safe_yes ( private_area::goErrorMutex.lock(); ) private_area::goErrorThrown=false; private_area::goCurrentError=&erNone; safe_yes ( private_area::goErrorMutex.release(); ) } //---------------------------------------------------------------------------------------ThrowError /*FUNCTION*/ /* Throws an error. */ function void throwError(ctError & agError) { safe_yes ( private_area::goErrorMutex.lock(); )
if (private_area::goErrorThrown) { private_area::outError(standardError::currentError()); private_area::outError(agError); safe_yes ( private_area::goErrorMutex.release(); ) environment::terminate(); } else { private_area::goErrorThrown=true; private_area::goCurrentError=&agError; safe_yes ( private_area::goErrorMutex.release(); ) throw agError; } } }
namespace private_area { //----------------------------------------------------------------------------SendCreateThreadError function void sendCreateThreadError(void) { erCreateThread.module()="Standard/Thread"; erCreateThread.method()="createThread"; erCreateThread.file()=__FILE__; erCreateThread.line()=__LINE__+1; throwError(erCreateThread); } //-----------------------------------------------------------------------SendMutexNotAvailableError function void sendMutexNotAvailableError(void) { erMutexUnlocked.module()="Standard/Thread"; erMutexUnlocked.method()="mutex::lock/release/tryLock"; erMutexUnlocked.file()=__FILE__; erMutexUnlocked.line()=__LINE__+1; throwError(erMutexNotAvailable); } //---------------------------------------------------------------------------SendMutexUnlockedError function void sendMutexUnlockedError(void) { erMutexUnlocked.module()="Standard/Thread"; erMutexUnlocked.method()="mutex::release"; erMutexUnlocked.file()=__FILE__; erMutexUnlocked.line()=__LINE__+1; throwError(erMutexUnlocked); } }
// E r r o r Implementation //---------------------------------------------------------------------- namespace public_area { //-------------------------------------------------------------------------------------------Create /*METHOD clError */ /* Declares an error with a given message. */ property void clError::create(tcString agMessage) { safe_yes ( private_area::goErrorMutex.lock(); ) atMessage=agMessage; atNumber=private_area::goErrorS->size(); atMethod=""; atModule=""; private_area::goErrorS->push_back(this); safe_yes ( private_area::goErrorMutex.release(); ) } }
// E v e n t S p y Implementation //--------------------------------------------------------------- #ifdef EVENT_SPY_MODE namespace private_area { //--------------------------------------------------------------------------------------Constructor property clEventSpy::clEventSpy(tcString agMethod,tcString agModule) : atMethod(agMethod), atModule(agModule) { safe_yes ( private_area::goSpyMutex.lock(); ) goEventKindS->insert(goEventKindS->begin(),start); goMethodS->insert(goMethodS->begin(),agMethod); goModuleS->insert(goModuleS->begin(),agModule);
if (goEventKindS->size()>goTraceSize) { goEventKindS->pop_back(); goMethodS->pop_back(); goModuleS->pop_back(); }
safe_yes ( private_area::goSpyMutex.release(); ) } //---------------------------------------------------------------------------------------Destructor property clEventSpy::~clEventSpy(void) { safe_yes ( private_area::goSpyMutex.lock(); ) goEventKindS->insert(goEventKindS->begin(),end); goMethodS->insert(goMethodS->begin(),atMethod); goModuleS->insert(goModuleS->begin(),atModule);
if (goEventKindS->size()>goTraceSize) { goEventKindS->pop_back(); goMethodS->pop_back(); goModuleS->pop_back(); }
safe_yes ( private_area::goSpyMutex.release(); ) } } #endif
// I n i t i a l i z e r Implementation //--------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------------Start property void clInitializer::start(void) { if (atCounter++ == 0) { try { #include <bpp/modules.hpp> /*NEED*/ registerStop(this); environment::informInitialization(goModuleName);
event_spy_mode ( goEventKindS = new clEventKindS; goMethodS = new clStringS; goModuleS = new clStringS;
goEventTraceFileName = EVENT_TRACE_FILE; goTraceSize = EVENT_TRACE_SIZE; )
method_name("initializer::constructor");
goErrorS = new clErrorS; goErrorThrown = false; goCurrentError = &erNone;
erInvalidErrorNumber.create("Invalid error number."); erNone.create("No error."); erUnexpected.create("Unexpected error.");
erDataLocationParameterMissing.create("The 'data_location' parameter is missing."); erTemporaryLocationParameterMissing.create("The 'temporary_location' parameter is missing.");
if (environment::parameters().count(clString("data_location"))==0) send_error(erDataLocationParameterMissing);
if (environment::parameters().count(clString("temporary_location"))==0) send_error(erTemporaryLocationParameterMissing);
testing_mode ( erTestingLocationParameterMissing.create("The 'testing_location' parameter is missing.");
if (environment::parameters().count(clString("testing_location"))==0) send_error(erTestingLocationParameterMissing); )
// Thread Module Initialization // standardClass_private::goDemangleMutex = new standardThread::clMutex(); standardThread_private::goDisplayMutex = new standardThread::clMutex(); standardThread_private::goMallocMutex = new standardThread::clMutex(); standardThread_private::sendCreateThreadError = private_area::sendCreateThreadError; standardThread_private::sendMutexNotAvailableError = private_area::sendMutexNotAvailableError; standardThread_private::sendMutexUnlockedError = private_area::sendMutexUnlockedError;
erCreateThread.create("Can't create a new thread."); erMutexNotAvailable.create("The mutex facility is not available."); erMutexUnlocked.create("The mutex is unlocked."); }
initializer_catch; } } //---------------------------------------------------------------------------------------------Stop property void clInitializer::stop(void) { environment::informTermination(goModuleName);
delete goErrorS;
event_spy_mode ( delete goEventKindS; delete goMethodS; delete goModuleS; ) } }
// End //------------------------------------------------------------------------------------------- } |
|