* Added fallback handler for Throws that happen when no Try..Catch has been specified.

git-svn-id: http://cexception.svn.sourceforge.net/svnroot/cexception/trunk@18 50f63946-2846-0410-8d77-f904c773002e
This commit is contained in:
mvandervoord
2012-02-20 12:39:01 +00:00
parent 0571b990b6
commit 7de3228016
6 changed files with 95 additions and 26 deletions
+7 -3
View File
@@ -1,6 +1,6 @@
#include "CException.h"
volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID];
volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID] = { 0 };
//------------------------------------------------------------------------------------------
// Throw
@@ -9,11 +9,15 @@ void Throw(CEXCEPTION_T ExceptionID)
{
unsigned int MY_ID = CEXCEPTION_GET_ID;
CExceptionFrames[MY_ID].Exception = ExceptionID;
longjmp(*CExceptionFrames[MY_ID].pFrame, 1);
if (CExceptionFrames[MY_ID].pFrame)
{
longjmp(*CExceptionFrames[MY_ID].pFrame, 1);
}
CEXCEPTION_NO_CATCH_HANDLER(MY_ID);
}
//------------------------------------------------------------------------------------------
// Explaination of what it's all for:
// Explanation of what it's all for:
//------------------------------------------------------------------------------------------
/*
#define Try
+16
View File
@@ -3,6 +3,12 @@
#include <setjmp.h>
#ifdef __cplusplus
extern "C"
{
#endif
//To Use CException, you have a number of options:
//1. Just include it and run with the defaults
//2. Define any of the following symbols at the command line to override them
@@ -33,6 +39,11 @@
#define CEXCEPTION_T unsigned int
#endif
//This is an optional special handler for when there is no global Catch
#ifndef CEXCEPTION_NO_CATCH_HANDLER
#define CEXCEPTION_NO_CATCH_HANDLER(id)
#endif
//exception frame structures
typedef struct {
jmp_buf* pFrame;
@@ -67,4 +78,9 @@ extern volatile CEXCEPTION_FRAME_T CExceptionFrames[];
//Throw an Error
void Throw(CEXCEPTION_T ExceptionID);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _CEXCEPTION_H
+1 -1
View File
@@ -18,7 +18,7 @@ OUT_EXTENSION = '.out'
SRC_FILES = "lib/CException.c test/TestException.c test/TestException_Runner.c #{UNITY_DIR}/unity.c"
INC_DIRS = "-Ilib -Itest -I#{UNITY_DIR}"
LIB_DIRS = C_LIBS.empty? ? '' : "-L#{C_LIBS}"
SYMBOLS = '-DTEST -DEXCEPTION_USE_CONFIG_FILE'
SYMBOLS = '-DTEST -DCEXCEPTION_USE_CONFIG_FILE'
CLEAN.include("#{HERE}*.out")
+18 -1
View File
@@ -1,13 +1,30 @@
#ifndef _EXCEPTION_H
#define _EXCEPTION_H
#include "Unity.h"
extern volatile int TestingTheFallback;
//Optionally define the exception type (something like an int which can be directly assigned)
#define CEXCEPTION_T int
// Optionally define the reserved value representing NO EXCEPTION
#define CEXCEPTION_NONE (1234)
// Multi-Tasking environments will need a couple of macros defined to make this library
// Optionally define a special handler for unhandled exceptions
#define CEXCEPTION_NO_CATCH_HANDLER(id) \
{ \
if (!TestingTheFallback) \
{ \
TEST_FAIL_MESSAGE("Unexpected Exception!"); \
} \
else \
{ \
TestingTheFallback--; \
} \
}
// 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)
+37
View File
@@ -1,8 +1,12 @@
#include "unity.h"
#include "CException.h"
volatile int TestingTheFallback;
void setUp(void)
{
CExceptionFrames[0].pFrame = NULL;
TestingTheFallback = 0;
}
void tearDown(void)
@@ -289,3 +293,36 @@ void test_CanHaveNestedTryBlocksInASingleFunction_ThrowOutside(void)
TEST_ASSERT_EQUAL(0x01, e);
}
}
void test_AThrowWithoutATryCatchWillUseDefaultHandlerIfSpecified(void)
{
//Let the fallback handler know we're expecting it to get called this time, so don't fail
TestingTheFallback = 1;
Throw(0xBE);
//We know the fallback was run because it decrements the counter above
TEST_ASSERT_FALSE(TestingTheFallback);
}
void test_AThrowWithoutOutsideATryCatchWillUseDefaultHandlerEvenAfterTryCatch(void)
{
CEXCEPTION_T e;
Try
{
//It's not really important that we do anything here.
}
Catch(e)
{
//The entire purpose here is just to make sure things get set back to using the default handler when done
}
//Let the fallback handler know we're expecting it to get called this time, so don't fail
TestingTheFallback = 1;
Throw(0xBE);
//We know the fallback was run because it decrements the counter above
TEST_ASSERT_FALSE(TestingTheFallback);
}
+16 -21
View File
@@ -17,21 +17,14 @@ extern void test_CanHaveNestedTryBlocksInASingleFunction_ThrowInside(void);
extern void test_CanHaveNestedTryBlocksInASingleFunction_ThrowOutside(void);
extern void test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThisDoesntCorruptExceptionId(void);
extern void test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThatEachExceptionIdIndependent(void);
extern void test_AThrowWithoutATryCatchWillUseDefaultHandlerIfSpecified(void);
extern void test_AThrowWithoutOutsideATryCatchWillUseDefaultHandlerEvenAfterTryCatch(void);
static void runTest(UnityTestFunction test)
{
CEXCEPTION_T e;
if (TEST_PROTECT())
{
setUp();
Try
{
test();
}
Catch(e)
{
TEST_FAIL_MESSAGE("Unexpected exception!")
}
}
tearDown();
}
@@ -43,18 +36,20 @@ int main(void)
UnityBegin();
// RUN_TEST calls runTest
RUN_TEST(test_BasicTryDoesNothingIfNoThrow, 12);
RUN_TEST(test_BasicThrowAndCatch, 30);
RUN_TEST(test_BasicThrowAndCatch_WithMiniSyntax, 49);
RUN_TEST(test_VerifyVolatilesSurviveThrowAndCatch, 69);
RUN_TEST(test_ThrowFromASubFunctionAndCatchInRootFunc, 98);
RUN_TEST(test_ThrowAndCatchFromASubFunctionAndRethrowToCatchInRootFunc, 139);
RUN_TEST(test_ThrowAndCatchFromASubFunctionAndNoRethrowToCatchInRootFunc, 158);
RUN_TEST(test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThisDoesntCorruptExceptionId, 175);
RUN_TEST(test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThatEachExceptionIdIndependent, 193);
RUN_TEST(test_CanHaveMultipleTryBlocksInASingleFunction, 220);
RUN_TEST(test_CanHaveNestedTryBlocksInASingleFunction_ThrowInside, 245);
RUN_TEST(test_CanHaveNestedTryBlocksInASingleFunction_ThrowOutside, 269);
RUN_TEST(test_BasicTryDoesNothingIfNoThrow, 15);
RUN_TEST(test_BasicThrowAndCatch, 33);
RUN_TEST(test_BasicThrowAndCatch_WithMiniSyntax, 52);
RUN_TEST(test_VerifyVolatilesSurviveThrowAndCatch, 72);
RUN_TEST(test_ThrowFromASubFunctionAndCatchInRootFunc, 101);
RUN_TEST(test_ThrowAndCatchFromASubFunctionAndRethrowToCatchInRootFunc, 142);
RUN_TEST(test_ThrowAndCatchFromASubFunctionAndNoRethrowToCatchInRootFunc, 161);
RUN_TEST(test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThisDoesntCorruptExceptionId, 178);
RUN_TEST(test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThatEachExceptionIdIndependent, 196);
RUN_TEST(test_CanHaveMultipleTryBlocksInASingleFunction, 223);
RUN_TEST(test_CanHaveNestedTryBlocksInASingleFunction_ThrowInside, 248);
RUN_TEST(test_CanHaveNestedTryBlocksInASingleFunction_ThrowOutside, 272);
RUN_TEST(test_AThrowWithoutATryCatchWillUseDefaultHandlerIfSpecified, 296);
RUN_TEST(test_AThrowWithoutOutsideATryCatchWillUseDefaultHandlerEvenAfterTryCatch, 308);
UnityEnd();