/* .+ .identifier : $Id: Chf.h,v 2.2 2001/01/25 11:56:44 cibrario Exp $ .context : CHF, Condition Handling Facility .title : $RCSfile: Chf.h,v $, main header .kind : C header .author : Ivan Cibrario B. .site : CSTV-CNR .creation : 2-May-1996 .keywords : * .description : This is the main header of the Condition Handling Facility .include : stdio.h setjmp.h (Win32: tchar.h) .notes : $Log: Chf.h,v $ Revision 2.2 2001/01/25 11:56:44 cibrario Added partial Win32 support (Windows CE only). Revision 2.1 2000/05/26 14:10:08 cibrario - Revised unwind context passing mechanism; redefined CHF_NULL_CONTEXT - New macros: CHF_NULL_HANDLER, CHF_MAJOR_RELEASE_NUMBER, CHF_MINOR_RELEASE_NUMBER - New ChfAction value: CHF_UNWIND_KEEP; fixed spelling of ChfAction value: CHF_SIGNALLING -> CHF_SIGNALING - Added structured condition handling macros: ChfTry, ChfCatch, ChfEndTry Revision 1.6 1997/01/15 13:41:20 cibrario Defined the new data type ChfPointer, a generic (void *) pointer. Each condition handler can have a private handler context pointer, of type ChfPointer, that the function ChfPushHandler() stores and that is passed to the handler when it's activated. Fixed a wrong adjustment of the condition handlers stack pointer after an unwind operation. Revision 1.5 1996/10/04 09:45:30 cibrario Updated the condition message format in the private header ChfPriv.h to improve internationalization Revision 1.4 1996/09/25 13:21:11 cibrario Added macro CHF_LIBRARY_ID; it contains the current ID of the CHF library. The module chf_init.o will contain it as a static char[] variable. Revision 1.2 1996/06/11 13:02:10 cibrario Added prototype for ChfGetTopCondition() Revision 1.1 1996/05/28 12:56:47 cibrario Initial revision .- */ /* ------------------------------------------------------------------------- Win32 & UNICODE support ------------------------------------------------------------------------- */ #ifdef _WIN32 #define ChfChar TCHAR #define ChfText(x) _T(x) #define ChfSigjmp_buf jmp_buf #define ChfSigsetjmp(x,y) setjmp(x) #define ChfSiglongjmp(x,y) longjmp(x,y) #else #define ChfChar char #define ChfText(x) x #define ChfSigjmp_buf sigjmp_buf #define ChfSigsetjmp(x,y) sigsetjmp(x,y) #define ChfSiglongjmp(x,y) siglongjmp(x,y) #endif /* ------------------------------------------------------------------------- CHF implementation limits and other symbolic constants ------------------------------------------------------------------------- */ #define CHF_MAX_MESSAGE_LENGTH 256 #define CHF_UNKNOWN_LINE_NUMBER (-1) #define CHF_UNKNOWN_FILE_NAME (ChfChar *)NULL #define CHF_NULL_DESCRIPTOR (ChfDescriptor *)NULL #define CHF_NULL_CONTEXT (void *)NULL #define CHF_NULL_POINTER (ChfPointer *)NULL #define CHF_NULL_HANDLER (ChfHandler)NULL #define CHF_LIBRARY_ID ChfText("$Id: Chf.h,v 2.2 2001/01/25 11:56:44 cibrario Exp $") #define CHF_MAJOR_RELEASE_NUMBER 2 #define CHF_MINOR_RELEASE_NUMBER 2 #define CHF_MODULE_NAMES_SET 1 #define CHF_SET 2 #define CHF_ERRNO_SET 3 /* ------------------------------------------------------------------------- Condition codes ------------------------------------------------------------------------- */ #define CHF_S_OK 0 #define CHF_F_COND_STACK_FULL 1 /* Condition stack is full */ #define CHF_F_HDLR_STACK_FULL 2 /* Handler stack is full */ #define CHF_F_HDLR_STACK_EMPTY 3 /* Handler stack is empty */ #define CHF_F_BAD_STATE 4 /* Bad CHF state for req. operation */ #define CHF_F_INVALID_ACTION 5 /* Invalid action from handler: %d */ #define CHF_F_MALLOC 6 /* Dynamic memory allocation failed */ #define CHF_F_NOT_AVAILABLE 7 /* Function not available */ #define CHF_F_SETLOCALE 10 /* setlocale() failed */ #define CHF_F_CATOPEN 11 /* catopen() failed */ /* ------------------------------------------------------------------------- Type definitions ------------------------------------------------------------------------- */ typedef enum /* Condition severity codes */ { CHF_SUCCESS, CHF_INFO, CHF_WARNING, CHF_ERROR, CHF_FATAL } ChfSeverity; typedef enum /* Condition handler action codes */ { CHF_CONTINUE, /* Continue application */ CHF_RESIGNAL, /* Resignal to next handler */ CHF_UNWIND, /* Stack unwind */ CHF_UNWIND_KEEP /* Unwind, keep last cond. group */ } ChfAction; typedef int /* CHF options */ ChfOptions; #define CHF_DEFAULT 0x0000 /* default flags */ #define CHF_ABORT 0x0001 /* use abort() instead of exit() */ typedef enum /* Current CHF state */ { CHF_UNKNOWN, CHF_IDLE, CHF_SIGNALING, CHF_UNWINDING, CHF_SIGNAL_UNWINDING } ChfState; typedef struct ChfDescriptor_S /* Condition descriptor */ { int module_id; /* Module identifier */ int condition_code; /* Condition code */ ChfSeverity severity; /* Severity */ int line_number; /* Line # or CHF_UNK_LINE_NUMBER */ const ChfChar *file_name; /* File name or CHF_UNK_FILE_NAME */ ChfChar message[CHF_MAX_MESSAGE_LENGTH]; /* Partial message */ struct ChfDescriptor_S *next; /* Link to next descriptor */ } ChfDescriptor; typedef struct ChfTable_S /* Standalone message table */ { int module; /* Module identifier */ int code; /* Condition code */ ChfChar *msg_template; /* Message template */ } ChfTable; typedef /* Generic pointer */ void *ChfPointer; typedef /* Condition handler */ ChfAction (*ChfHandler)( const ChfDescriptor *, const ChfState, ChfPointer ); typedef /* Message retrieval 'get_message' function */ const ChfChar * (*ChfMrsGet)( void *, const int, const int, const ChfChar *default_message ); typedef /* Message retrieval 'exit' function */ void (*ChfMrsExit)( void * ); /* ------------------------------------------------------------------------- Condition generation macros ------------------------------------------------------------------------- */ #if defined(CHF_EXTENDED_INFO) #define ChfCondition \ ChfGenerate( \ CHF_MODULE_ID, \ ChfText(__FILE__), __LINE__, #ifdef _WIN32 #define ChfErrnoCondition #else #define ChfErrnoCondition \ ChfGenerate( \ CHF_ERRNO_SET, \ ChfText(__FILE__), __LINE__, \ errno, \ CHF_ERROR \ ) #endif #else #define ChfCondition \ ChfGenerate( \ CHF_MODULE_ID, \ CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER, #ifdef _WIN32 #define ChfErrnoCondition #else #define ChfErrnoCondition \ ChfGenerate( \ CHF_ERRNO_SET, \ CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER, \ errno, \ CHF_ERROR \ ) #endif #endif #define ChfEnd \ ) /* ------------------------------------------------------------------------- Structured condition handling ------------------------------------------------------------------------- */ #define ChfTry \ {\ ChfSigjmp_buf _chf_sigjmp_buf;\ if(ChfSigsetjmp(_chf_sigjmp_buf, 1) == 0)\ {\ ChfPushHandler(CHF_NULL_HANDLER, _chf_sigjmp_buf, CHF_NULL_POINTER); #define ChfCatch \ ChfPopHandler();\ }\ else\ { #define ChfEndTry \ ChfDiscard();\ }\ } /* ------------------------------------------------------------------------- Other macros ------------------------------------------------------------------------- */ #define ChfGetNextDescriptor(d) (d)->next #define ChfGetModuleId(d) (d)->module_id #define ChfGetConditionCode(d) (d)->condition_code #define ChfGetSeverity(d) (d)->severity #define ChfGetLineNumber(d) (d)->line_number #define ChfGetFileName(d) (d)->file_name #define ChfGetPartialMessage(d) (d)->message /* ------------------------------------------------------------------------- Function prototypes ------------------------------------------------------------------------- */ int ChfInit( /* Generic initialization */ const ChfChar *app_name, /* Application's name */ const ChfOptions options, /* Options */ void *mrs_data, /* Message retrieval private data */ ChfMrsGet mrs_get, /* 'GetMessage' function */ ChfMrsExit mrs_exit, /* 'Exit' function */ const int condition_stack_size, /* Size of the condition stack */ const int handler_stack_size, /* Size of the handler stack */ const int exit_code /* Abnormal exit code */ ); int ChfMsgcatInit( /* Initialization with msgcat subsystem */ const ChfChar *app_name, /* Application's name */ const ChfOptions options, /* Options */ const ChfChar *msgcat_name, /* Name of the message catalog */ const int condition_stack_size, /* Size of the condition stack */ const int handler_stack_size, /* Size of the handler stack */ const int exit_code /* Abnormal exit code */ ); int ChfStaticInit( /* Initialization with static message tables */ const ChfChar *app_name, /* Application's name */ const ChfOptions options, /* Options */ const ChfTable *table, /* Static message table */ const size_t table_size, /* Size of the message table */ const int condition_stack_size, /* Size of the condition stack */ const int handler_stack_size, /* Size of the handler stack */ const int exit_code /* Abnormal exit code */ ); int ChfWin32Init( /* Initialization within _WIN32 */ const ChfChar *app_name, /* Application's name */ const ChfOptions options, /* Options */ #ifndef _WIN32 void *instance, /* Fake arguments */ #else HINSTANCE instance, /* App. instance handle */ #endif const int condition_stack_size, /* Size of the condition stack */ const int handler_stack_size, /* Size of the handler stack */ const int exit_code /* Abnormal exit code */ ); void ChfExit( /* Exit */ void ); void ChfAbort( /* Abort application */ const int abort_code ); void ChfPushHandler( /* Push a new handler into the stack */ ChfHandler new_handler, /* Handler to be added */ void *unwind_context, /* Unwind context */ ChfPointer handler_context /* Private handler context */ ); void ChfPopHandler( /* Pop a handler */ void ); ChfChar *ChfBuildMessage( /* Build a condition message */ const ChfDescriptor *descriptor ); void ChfSignal( /* Signal the current conditions */ void ); void ChfDiscard( /* Discard the current conditions */ void ); void ChfGenerate( /* Generate a condition into the stack */ const int module_id, const ChfChar *file_name, const int line_number, const int condition_code, const ChfSeverity severity, ... ); const ChfChar *ChfGetMessage( /* Retrieve a condition message */ const int module_id, const int condition_code, const ChfChar *default_message ); const ChfDescriptor *ChfGetTopCondition( /* Retrieve top condition */ void );