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:
mvandervoord
2008-12-19 17:17:53 +00:00
parent ecc3e29299
commit 959e43da62
6 changed files with 268 additions and 178 deletions
+28 -19
View File
@@ -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
View File
@@ -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
-23
View File
@@ -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