mirror of
https://github.com/throwtheswitch/cexception.git
synced 2026-09-17 07:39:57 +00:00
switched format of catches to pass in a variable to fill, more like C++.
git-svn-id: http://cexception.svn.sourceforge.net/svnroot/cexception/trunk@5 50f63946-2846-0410-8d77-f904c773002e
This commit is contained in:
+28
-19
@@ -3,36 +3,45 @@
|
||||
volatile EXCEPTION_FRAME_T ExceptionFrames[EXCEPTION_NUM_ID];
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// ThrowDetailed
|
||||
// Throw
|
||||
//------------------------------------------------------------------------------------------
|
||||
//
|
||||
// PARAMETERS: None
|
||||
//
|
||||
// DESCRIPTION: throws a software exception with details
|
||||
// DESCRIPTION: throws a software exception
|
||||
//
|
||||
// RETURNS: None
|
||||
//
|
||||
//------------------------------------------------------------------------------------------
|
||||
void ThrowDetailed(unsigned int ExceptionID, unsigned int Details)
|
||||
void Throw(EXCEPTION_T ExceptionID)
|
||||
{
|
||||
MY_FRAME.Exception = ExceptionID;
|
||||
MY_FRAME.Details = Details;
|
||||
longjmp(*MY_FRAME.pFrame, 1);
|
||||
unsigned int MY_ID = EXCEPTION_GET_ID;
|
||||
ExceptionFrames[MY_ID].Exception = ExceptionID;
|
||||
longjmp(*ExceptionFrames[MY_ID].pFrame, 1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Rethrow
|
||||
// Explaination of what it's all for:
|
||||
//------------------------------------------------------------------------------------------
|
||||
//
|
||||
// PARAMETERS: None
|
||||
//
|
||||
// DESCRIPTION: rethrows a software exception that has already been thrown
|
||||
//
|
||||
// RETURNS: None
|
||||
//
|
||||
//------------------------------------------------------------------------------------------
|
||||
void Rethrow()
|
||||
{
|
||||
longjmp(*MY_FRAME.pFrame, 1);
|
||||
}
|
||||
/*
|
||||
#define Try
|
||||
{ <- give us some local scope. most compilers are happy with this
|
||||
jmp_buf *PrevFrame, NewFrame; <- prev frame points to the last try block's frame. new frame gets created on stack for this Try block
|
||||
unsigned int MY_ID = EXCEPTION_GET_ID; <- look up this task's id for use in frame array. always 0 if single-tasking
|
||||
PrevFrame = ExceptionFrames[EXCEPTION_GET_ID].pFrame; <- set pointer to point at old frame (which array is currently pointing at)
|
||||
ExceptionFrames[MY_ID].pFrame = &NewFrame; <- set array to point at my new frame instead, now
|
||||
ExceptionFrames[MY_ID].Exception = EXCEPTION_NONE; <- initialize my exception id to be NONE
|
||||
if (setjmp(NewFrame) == 0) { <- do setjmp. it returns 1 if longjump called, otherwise 0
|
||||
if (&PrevFrame) <- this is here to force proper scoping. it requires braces or a single line to be but after Try, otherwise won't compile. This is always true at this point.
|
||||
|
||||
#define Catch(e)
|
||||
else { } <- this also forces proper scoping. Without this they could stick their own 'else' in and it would get ugly
|
||||
ExceptionFrames[MY_ID].Exception = EXCEPTION_NONE; <- no errors happened, so just set the exception id to NONE (in case it was corrupted)
|
||||
}
|
||||
else <- an exception occurred
|
||||
{ e = ExceptionFrames[MY_ID].Exception; e=e;} <- assign the caught exception id to the variable passed in.
|
||||
ExceptionFrames[MY_ID].pFrame = PrevFrame; <- make the pointer in the array point at the previous frame again, as if NewFrame never existed.
|
||||
} <- finish off that local scope we created to have our own variables
|
||||
if (ExceptionFrames[EXCEPTION_GET_ID].Exception != EXCEPTION_NONE) <- start the actual 'catch' processing if we have an exception id saved away
|
||||
*/
|
||||
|
||||
|
||||
+21
-19
@@ -15,40 +15,42 @@
|
||||
#define EXCEPTION_GET_ID (0) //use the first index always because there is only one anyway
|
||||
#endif
|
||||
|
||||
#ifndef EXCEPTION_T
|
||||
#define EXCEPTION_T unsigned int
|
||||
#endif
|
||||
|
||||
//exception frame structures
|
||||
typedef struct {
|
||||
jmp_buf* pFrame;
|
||||
volatile unsigned int Exception;
|
||||
volatile unsigned int Details;
|
||||
volatile EXCEPTION_T Exception;
|
||||
} EXCEPTION_FRAME_T;
|
||||
|
||||
//actual root frame storage (only one if single-tasking)
|
||||
extern volatile EXCEPTION_FRAME_T ExceptionFrames[];
|
||||
|
||||
#define MY_FRAME (ExceptionFrames[EXCEPTION_GET_ID])
|
||||
#define MY_FRAME_FAST (ExceptionFrames[MY_ID])
|
||||
#define EXCEPTION_ID (MY_FRAME.Exception)
|
||||
#define EXCEPTION_DETAILS (MY_FRAME.Details)
|
||||
|
||||
//Try (see C file for explanation)
|
||||
#define Try \
|
||||
{ \
|
||||
jmp_buf *PrevFrame, NewFrame; \
|
||||
unsigned int MY_ID = EXCEPTION_GET_ID; \
|
||||
PrevFrame = MY_FRAME.pFrame; \
|
||||
MY_FRAME_FAST.pFrame = &NewFrame; \
|
||||
MY_FRAME_FAST.Details = 0; \
|
||||
MY_FRAME_FAST.Exception = EXCEPTION_NONE; \
|
||||
PrevFrame = ExceptionFrames[EXCEPTION_GET_ID].pFrame; \
|
||||
ExceptionFrames[MY_ID].pFrame = &NewFrame; \
|
||||
ExceptionFrames[MY_ID].Exception = EXCEPTION_NONE; \
|
||||
if (setjmp(NewFrame) == 0) { \
|
||||
if (&PrevFrame)
|
||||
if (&PrevFrame)
|
||||
|
||||
#define Catch \
|
||||
//Catch (see C file for explanation)
|
||||
#define Catch(e) \
|
||||
else { } \
|
||||
MY_FRAME_FAST.Exception = EXCEPTION_NONE; \
|
||||
ExceptionFrames[MY_ID].Exception = EXCEPTION_NONE; \
|
||||
} \
|
||||
MY_FRAME_FAST.pFrame = PrevFrame; \
|
||||
else \
|
||||
{ e = ExceptionFrames[MY_ID].Exception; e=e; } \
|
||||
ExceptionFrames[MY_ID].pFrame = PrevFrame; \
|
||||
} \
|
||||
if (MY_FRAME.Exception != EXCEPTION_NONE)
|
||||
if (ExceptionFrames[EXCEPTION_GET_ID].Exception != EXCEPTION_NONE)
|
||||
|
||||
#define Throw(id) ThrowDetailed(id, __LINE__)
|
||||
void ThrowDetailed(unsigned int ExceptionID, unsigned int Details);
|
||||
void Rethrow(void);
|
||||
//Throw an Error
|
||||
void Throw(EXCEPTION_T ExceptionID);
|
||||
|
||||
#endif // _CEXCEPTION_H
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef _EXCEPTION_H
|
||||
#define _EXCEPTION_H
|
||||
|
||||
// Define the reserved value representing NO EXCEPTION
|
||||
#define EXCEPTION_NONE (0x5A5A5A5A)
|
||||
|
||||
// Multi-Tasking environments will need a couple of macros defined to make this library
|
||||
// properly handle multiple exception stacks. You will need to include and required
|
||||
// definitions, then define the following macros:
|
||||
// EXCEPTION_GET_ID - returns the id of the current task indexed 0 to (numtasks - 1)
|
||||
// EXCEPTION_NUM_ID - returns the number of tasks that might be returned
|
||||
//
|
||||
// For example, Quadros might include the following implementation:
|
||||
#ifndef TEST
|
||||
#include "OSAPI.h"
|
||||
#define EXCEPTION_GET_ID() (KS_GetTaskID())
|
||||
#define EXCEPTION_NUM_ID (NTASKS + 1)
|
||||
#endif
|
||||
|
||||
// INCLUDE THE ACTUAL CEXCEPTION LIBRARY
|
||||
#include "CException.h"
|
||||
|
||||
#endif // _EXCEPTION_H
|
||||
Reference in New Issue
Block a user