1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-03-03 14:52:21 +02:00

Simplify try..catch..finally names.

This commit is contained in:
David Steele 2017-11-13 21:22:13 -05:00
parent bcdfc7d0b5
commit cf7da546a3
14 changed files with 108 additions and 104 deletions

View File

@ -43,6 +43,10 @@
<release-item>
<p>Enable additional warnings for C builds.</p>
</release-item>
<release-item>
<p>Simplify try..catch..finally names.</p>
</release-item>
</release-refactor-list>
</release-core-list>

View File

@ -50,13 +50,13 @@ This turned out to be a dead end because Perl 5.10 does not support croak_sv(),
Error handling macros that throw a Perl error when a C error is caught
***********************************************************************************************************************************/
#define ERROR_XS_BEGIN() \
ERROR_TRY()
TRY()
#define ERROR_XS() \
croak("PGBRCLIB:%d:%s:%d:%s", errorCode(), errorFileName(), errorFileLine(), errorMessage());
#define ERROR_XS_END() \
ERROR_CATCH_ANY() \
CATCH_ANY() \
{ \
ERROR_XS(); \
}
@ -72,16 +72,16 @@ Core context handling macros, only intended to be called from other macros
volatile bool MEM_CONTEXT_XS_croak = false; \
\
/* Try the statement block */ \
ERROR_TRY()
TRY()
#define MEM_CONTEXT_XS_CORE_END() \
/* Set error to be croak to Perl later */ \
ERROR_CATCH_ANY() \
CATCH_ANY() \
{ \
MEM_CONTEXT_XS_croak = true; \
} \
/* Free the context on error */ \
ERROR_FINALLY() \
FINALLY() \
{ \
memContextSwitch(MEM_CONTEXT_XS_memContextOld); \
}
@ -94,11 +94,11 @@ Simplifies creation of the memory context in contructors and includes error hand
/* Attempt to create the memory context */ \
MemContext *MEM_CONTEXT_XS_memContext = NULL; \
\
ERROR_TRY() \
TRY() \
{ \
MEM_CONTEXT_XS_memContext = memContextNew(contextName); \
} \
ERROR_CATCH_ANY() \
CATCH_ANY() \
{ \
ERROR_XS() \
} \

View File

@ -66,7 +66,7 @@ cipherBlockNew(CipherMode mode, const char *cipherName, const unsigned char *pas
const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipherName);
if (!cipher)
ERROR_THROW(AssertError, "unable to load cipher '%s'", cipherName);
THROW(AssertError, "unable to load cipher '%s'", cipherName);
// Lookup digest. If not defined it will be set to sha1.
const EVP_MD *volatile digest = digest = EVP_sha1();
@ -77,7 +77,7 @@ cipherBlockNew(CipherMode mode, const char *cipherName, const unsigned char *pas
digest = EVP_sha1();
if (!digest)
ERROR_THROW(AssertError, "unable to load digest '%s'", digestName);
THROW(AssertError, "unable to load digest '%s'", digestName);
// Allocate memory to hold process state
CipherBlock *this = NULL;
@ -166,7 +166,7 @@ cipherBlockProcess(CipherBlock *this, const unsigned char *source, int sourceSiz
// The first bytes of the file to decrypt should be equal to the magic. If not then this is not an
// encrypted file, or at least not in a format we recognize.
if (memcmp(this->header, CIPHER_BLOCK_MAGIC, CIPHER_BLOCK_MAGIC_SIZE) != 0)
ERROR_THROW(CipherError, "cipher header invalid");
THROW(CipherError, "cipher header invalid");
}
// Else copy what was provided into the header buffer and return 0
else
@ -194,13 +194,13 @@ cipherBlockProcess(CipherBlock *this, const unsigned char *source, int sourceSiz
// Create context to track cipher
if (!(this->cipherContext = EVP_CIPHER_CTX_new()))
ERROR_THROW(MemoryError, "unable to create context"); // {uncoverable - no failure path known}
THROW(MemoryError, "unable to create context"); // {uncoverable - no failure path known}
// Initialize cipher
if (EVP_CipherInit_ex(
this->cipherContext, this->cipher, NULL, key, initVector, this->mode == cipherModeEncrypt) != 1)
{
ERROR_THROW(MemoryError, "unable to initialize cipher"); // {uncoverable - no failure path known}
THROW(MemoryError, "unable to initialize cipher"); // {uncoverable - no failure path known}
}
this->saltDone = true;
@ -214,7 +214,7 @@ cipherBlockProcess(CipherBlock *this, const unsigned char *source, int sourceSiz
int destinationUpdateSize = 0;
if (!EVP_CipherUpdate(this->cipherContext, destination, &destinationUpdateSize, source, sourceSize))
ERROR_THROW(CipherError, "unable to process"); // {uncoverable - no failure path known}
THROW(CipherError, "unable to process"); // {uncoverable - no failure path known}
destinationSize += destinationUpdateSize;
@ -237,11 +237,11 @@ cipherBlockFlush(CipherBlock *this, unsigned char *destination)
// If no header was processed then error
if (!this->saltDone)
ERROR_THROW(CipherError, "cipher header missing");
THROW(CipherError, "cipher header missing");
// Only flush remaining data if some data was processed
if (!EVP_CipherFinal(this->cipherContext, destination, &iDestinationSize))
ERROR_THROW(CipherError, "unable to flush");
THROW(CipherError, "unable to flush");
// Return actual destination size
return iDestinationSize;

View File

@ -11,7 +11,7 @@ Binary to String Encode/Decode
Macro to handle invalid encode type errors
***********************************************************************************************************************************/
#define ENCODE_TYPE_INVALID_ERROR(encodeType) \
ERROR_THROW(AssertError, "invalid encode type %d", encodeType);
THROW(AssertError, "invalid encode type %d", encodeType);
/***********************************************************************************************************************************
Encode binary data to a printable string
@ -77,11 +77,11 @@ decodeToBinValid(EncodeType encodeType, const char *source)
{
volatile bool valid = true;
ERROR_TRY()
TRY()
{
decodeToBinValidate(encodeType, source);
}
ERROR_CATCH(FormatError)
CATCH(FormatError)
{
valid = false;
}

View File

@ -150,7 +150,7 @@ decodeToBinValidateBase64(const char *source)
int sourceSize = strlen(source);
if (sourceSize % 4 != 0)
ERROR_THROW(FormatError, "base64 size %d is not evenly divisible by 4", sourceSize);
THROW(FormatError, "base64 size %d is not evenly divisible by 4", sourceSize);
// Check all characters
for (int sourceIdx = 0; sourceIdx < sourceSize; sourceIdx++)
@ -160,17 +160,17 @@ decodeToBinValidateBase64(const char *source)
{
// Make sure they are only in the last two positions
if (sourceIdx < sourceSize - 2)
ERROR_THROW(FormatError, "base64 '=' character may only appear in last two positions");
THROW(FormatError, "base64 '=' character may only appear in last two positions");
// If second to last char is = then last char must also be
if (sourceIdx == sourceSize - 2 && source[sourceSize - 1] != 0x3d)
ERROR_THROW(FormatError, "base64 last character must be '=' if second to last is");
THROW(FormatError, "base64 last character must be '=' if second to last is");
}
else
{
// Error on any invalid characters
if (decodeBase64Lookup[(int)source[sourceIdx]] == -1)
ERROR_THROW(FormatError, "base64 invalid character found at position %d", sourceIdx);
THROW(FormatError, "base64 invalid character found at position %d", sourceIdx);
}
}
}

View File

@ -3,31 +3,31 @@ Error Handler
Implement a try ... catch ... finally error handler.
ERROR_TRY()
TRY()
{
<Do something that might throw an error>
}
ERROR_CATCH(Error1)
CATCH(Error1)
{
<Handle Error1>
}
ERROR_CATCH(Error2)
CATCH(Error2)
{
<Handle Error2>
}
ERROR_CATCH_ANY()
CATCH_ANY()
{
<Handle errors that are not Error1 or Error2>
}
ERROR_FINALLY()
FINALLY()
{
<Cleanup code that runs in all cases>
}
The ERROR_CATCH() and ERROR_FINALLY() blocks are optional but at least one must be specified. There is no need for an ERROR_TRY
block by itself because errors will automatically be propagated to the nearest try block in the call stack.
The CATCH() and FINALLY() blocks are optional but at least one must be specified. There is no need for an TRY block by itself
because errors will automatically be propagated to the nearest try block in the call stack.
Never call return from within any of the ERROR*() blocks.
Never call return from within any of the error-handling blocks.
***********************************************************************************************************************************/
#ifndef ERROR_H
#define ERROR_H
@ -51,7 +51,7 @@ bool errorInstanceOf(const ErrorType *errorTypeTest);
/***********************************************************************************************************************************
Begin a block where errors can be thrown
***********************************************************************************************************************************/
#define ERROR_TRY() \
#define TRY() \
if (errorInternalTry(__FILE__, __LINE__) && setjmp(*errorInternalJump()) >= 0) \
while (errorInternalProcess(false)) \
if (errorInternalStateTry())
@ -59,34 +59,34 @@ Begin a block where errors can be thrown
/***********************************************************************************************************************************
Catch a specific error thrown in the try block
***********************************************************************************************************************************/
#define ERROR_CATCH(errorTypeCatch) \
#define CATCH(errorTypeCatch) \
else if (errorInternalStateCatch(&errorTypeCatch))
/***********************************************************************************************************************************
Catch any error thrown in the try block
***********************************************************************************************************************************/
#define ERROR_CATCH_ANY() \
#define CATCH_ANY() \
else if (errorInternalStateCatch(&RuntimeError))
/***********************************************************************************************************************************
Code to run whether the try block was successful or not
***********************************************************************************************************************************/
#define ERROR_FINALLY() \
#define FINALLY() \
else if (errorInternalStateFinal())
/***********************************************************************************************************************************
Throw an error
Errors can be thrown any time, but if there is no ERROR_TRY block somewhere in the call stack then the program will exit and print
the error information to stderr.
Errors can be thrown any time, but if there is no TRY block somewhere in the call stack then the program will exit and print the
error information to stderr.
***********************************************************************************************************************************/
#define ERROR_THROW(errorType, ...) \
#define THROW(errorType, ...) \
errorInternalThrow(&errorType, __FILE__, __LINE__, __VA_ARGS__)
/***********************************************************************************************************************************
Rethrow the current error
***********************************************************************************************************************************/
#define ERROR_RETHROW() \
#define RETHROW() \
errorInternalPropagate()
/***********************************************************************************************************************************

View File

@ -57,7 +57,7 @@ static void *memAllocInternal(size_t size, bool zero)
// Error when malloc fails
if (!buffer)
ERROR_THROW(MemoryError, "unable to allocate %lu bytes", size);
THROW(MemoryError, "unable to allocate %lu bytes", size);
// Zero the memory when requested
if (zero)
@ -77,7 +77,7 @@ static void *memReAllocInternal(void *bufferOld, size_t sizeOld, size_t sizeNew,
// Error when realloc fails
if(!bufferNew)
ERROR_THROW(MemoryError, "unable to reallocate %lu bytes", sizeNew);
THROW(MemoryError, "unable to reallocate %lu bytes", sizeNew);
// Zero the new memory when requested - old memory is left untouched else why bother with a realloc?
if (zeroNew)
@ -94,7 +94,7 @@ static void memFreeInternal(void *buffer)
{
// Error if pointer is null
if(!buffer)
ERROR_THROW(MemoryError, "unable to free null pointer");
THROW(MemoryError, "unable to free null pointer");
// Free the buffer
free(buffer);
@ -108,7 +108,7 @@ memContextNew(const char *name)
{
// Check context name length
if (strlen(name) == 0 || strlen(name) > MEM_CONTEXT_NAME_SIZE)
ERROR_THROW(AssertError, "context name length must be > 0 and <= %d", MEM_CONTEXT_NAME_SIZE);
THROW(AssertError, "context name length must be > 0 and <= %d", MEM_CONTEXT_NAME_SIZE);
// Try to find space for the new context
int contextIdx;
@ -180,15 +180,15 @@ memContextCallback(MemContext *this, void (*callbackFunction)(void *), void *cal
{
// Error if context is not active
if (this->state != memContextStateActive)
ERROR_THROW(AssertError, "cannot assign callback to inactive context");
THROW(AssertError, "cannot assign callback to inactive context");
// Top context cannot have a callback
if (this == memContextTop())
ERROR_THROW(AssertError, "top context may not have a callback");
THROW(AssertError, "top context may not have a callback");
// Error if callback has already been set - there may be valid use cases for this but error until one is found
if (this->callbackFunction)
ERROR_THROW(AssertError, "callback is already set for context '%s'", this->name);
THROW(AssertError, "callback is already set for context '%s'", this->name);
// Set callback function and argument
this->callbackFunction = callbackFunction;
@ -269,7 +269,7 @@ memFree(void *buffer)
{
// Error if buffer is null
if (!buffer)
ERROR_THROW(AssertError, "unable to free null allocation");
THROW(AssertError, "unable to free null allocation");
// Find memory to free
int allocIdx;
@ -280,7 +280,7 @@ memFree(void *buffer)
// Error if the buffer was not found
if (allocIdx == memContextCurrent()->allocListSize)
ERROR_THROW(AssertError, "unable to find allocation");
THROW(AssertError, "unable to find allocation");
// Free the buffer
memFreeInternal(memContextCurrent()->allocList[allocIdx]);
@ -295,7 +295,7 @@ memContextSwitch(MemContext *this)
{
// Error if context is not active
if (this->state != memContextStateActive)
ERROR_THROW(AssertError, "cannot switch to inactive context");
THROW(AssertError, "cannot switch to inactive context");
MemContext *memContextOld = memContextCurrent();
contextCurrent = this;
@ -329,7 +329,7 @@ memContextName(MemContext *this)
{
// Error if context is not active
if (this->state != memContextStateActive)
ERROR_THROW(AssertError, "cannot get name for inactive context");
THROW(AssertError, "cannot get name for inactive context");
return this->name;
}
@ -346,15 +346,15 @@ memContextFree(MemContext *this)
// Top context cannot be freed
if (this == memContextTop())
ERROR_THROW(AssertError, "cannot free top context");
THROW(AssertError, "cannot free top context");
// Current context cannot be freed
if (this == memContextCurrent())
ERROR_THROW(AssertError, "cannot free current context '%s'", this->name);
THROW(AssertError, "cannot free current context '%s'", this->name);
// Error if context is not active
if (this->state != memContextStateActive)
ERROR_THROW(AssertError, "cannot free inactive context");
THROW(AssertError, "cannot free inactive context");
// Free child contexts
if (this->contextChildListSize > 0)

View File

@ -43,11 +43,11 @@ Memory context management functions
MemContext *context = memContextNew();
MemContext *contextOld = memContextSwitch(context);
ERROR_TRY()
TRY()
{
<Do something with the memory context>
}
ERROR_CATCH_ANY()
CATCH_ANY()
{
<only needed if the error renders the memory context useless - for instance in a constructor>
@ -100,14 +100,14 @@ MEM_CONTEXT_END();
MemContext *MEM_CONTEXT_memContextOld = memContextSwitch(memContext); \
\
/* Try the statement block */ \
ERROR_TRY()
TRY()
#define MEM_CONTEXT_OLD() \
MEM_CONTEXT_memContextOld
#define MEM_CONTEXT_END() \
/* Free the context on error */ \
ERROR_FINALLY() \
FINALLY() \
{ \
memContextSwitch(MEM_CONTEXT_OLD()); \
} \
@ -140,11 +140,11 @@ MEM_CONTEXT_NEW_END();
MEM_CONTEXT_NEW_BEGIN_memContext
#define MEM_CONTEXT_NEW_END() \
ERROR_CATCH_ANY() \
CATCH_ANY() \
{ \
memContextSwitch(MEM_CONTEXT_OLD()); \
memContextFree(MEM_CONTEXT_NEW()); \
ERROR_RETHROW(); \
RETHROW(); \
} \
MEM_CONTEXT_END(); \
}

View File

@ -59,7 +59,7 @@ void
cfgCommandCheck(ConfigCommand commandId)
{
if (commandId >= cfgCommandTotal())
ERROR_THROW(AssertError, "command id %d invalid - must be >= 0 and < %d", commandId, cfgCommandTotal());
THROW(AssertError, "command id %d invalid - must be >= 0 and < %d", commandId, cfgCommandTotal());
}
/***********************************************************************************************************************************
@ -88,7 +88,7 @@ cfgCommandId(const char *commandName)
break;
if (commandId == cfgCommandTotal())
ERROR_THROW(AssertError, "invalid command '%s'", commandName);
THROW(AssertError, "invalid command '%s'", commandName);
return commandId;
}
@ -119,7 +119,7 @@ void
cfgOptionCheck(ConfigOption optionId)
{
if (optionId >= cfgOptionTotal())
ERROR_THROW(AssertError, "option id %d invalid - must be >= 0 and < %d", optionId, cfgOptionTotal());
THROW(AssertError, "option id %d invalid - must be >= 0 and < %d", optionId, cfgOptionTotal());
}
/***********************************************************************************************************************************

View File

@ -224,14 +224,14 @@ void
cfgDefCommandCheck(ConfigDefineCommand commandDefId)
{
if (commandDefId >= cfgDefCommandTotal())
ERROR_THROW(AssertError, "command def id %d invalid - must be >= 0 and < %d", commandDefId, cfgDefCommandTotal());
THROW(AssertError, "command def id %d invalid - must be >= 0 and < %d", commandDefId, cfgDefCommandTotal());
}
void
cfgDefOptionCheck(ConfigDefineOption optionDefId)
{
if (optionDefId >= cfgDefOptionTotal())
ERROR_THROW(AssertError, "option def id %d invalid - must be >= 0 and < %d", optionDefId, cfgDefOptionTotal());
THROW(AssertError, "option def id %d invalid - must be >= 0 and < %d", optionDefId, cfgDefOptionTotal());
}
static void
@ -262,7 +262,7 @@ cfgDefOptionAllowListValue(ConfigDefineCommand commandDefId, ConfigDefineOption
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList);
if (valueId < 0 || valueId >= dataDefListSize)
ERROR_THROW(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
THROW(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
}
@ -371,7 +371,7 @@ cfgDefOptionDependValue(ConfigDefineCommand commandDefId, ConfigDefineOption opt
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend);
if (valueId < 0 || valueId >= dataDefListSize)
ERROR_THROW(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
THROW(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
}

View File

@ -209,7 +209,7 @@ pageChecksumBufferTest(
{
// If the buffer does not represent an even number of pages then error
if (pageBufferSize % pageSize != 0 || pageBufferSize / pageSize == 0)
ERROR_THROW(AssertError, "buffer size %lu, page size %lu are not divisible", pageBufferSize, pageSize);
THROW(AssertError, "buffer size %lu, page size %lu are not divisible", pageBufferSize, pageSize);
// Loop through all pages in the buffer
for (int pageIdx = 0; pageIdx < pageBufferSize / pageSize; pageIdx++)

View File

@ -30,22 +30,22 @@ Test that an expected error is actually thrown and error when it isn't.
printf(" l%04d - expect error: %s\n", __LINE__, errorMessageExpected); \
fflush(stdout); \
\
ERROR_TRY() \
TRY() \
{ \
statement; \
} \
ERROR_CATCH_ANY() \
CATCH_ANY() \
{ \
TEST_ERROR_catch = true; \
\
if (strcmp(errorMessage(), errorMessageExpected) != 0 || errorType() != &errorTypeExpected) \
ERROR_THROW( \
THROW( \
AssertError, "expected error %s, '%s' but got %s, '%s'", errorTypeName(&errorTypeExpected), errorMessageExpected, \
errorName(), errorMessage()); \
} \
\
if (!TEST_ERROR_catch) \
ERROR_THROW( \
THROW( \
AssertError, "statement '%s' returned but error %s, '%s' was expected", #statement, errorTypeName(&errorTypeExpected), \
errorMessageExpected); \
}
@ -64,14 +64,14 @@ TEST_TYPE_FORMAT - format the test type into the given buffer -- or return verba
char *value##Str = value##StrBuffer; \
\
if (TEST_TYPE_PTR(type) && *(void **)&value == NULL) \
value##Str = (char *)"NULL"; \
value##Str = (char *)"NULL"; \
else if (strcmp(#type, "char *") == 0) \
value##Str = *(char **)&value; \
else \
{ \
if (snprintf(value##Str, TEST_RESULT_FORMAT_SIZE + 1, format, value) > TEST_RESULT_FORMAT_SIZE) \
{ \
ERROR_THROW( \
THROW( \
AssertError, "formatted type '" format "' needs more than the %d characters available", TEST_RESULT_FORMAT_SIZE); \
} \
}
@ -85,7 +85,7 @@ parameters.
#define TEST_RESULT(statement, resultExpectedValue, type, format, typeOp, ...) \
{ \
/* Assign expected result to a local variable so the value can be manipulated as a pointer */ \
const type TEST_RESULT_resultExpected = (type)(resultExpectedValue); \
const type TEST_RESULT_resultExpected = (type)(resultExpectedValue); \
\
/* Output test info */ \
printf(" l%04d - ", __LINE__); \
@ -99,15 +99,15 @@ parameters.
/* Try to run the statement */ \
type TEST_RESULT_result; \
\
ERROR_TRY() \
TRY() \
{ \
TEST_RESULT_result = (type)(statement); \
} \
/* Catch any errors */ \
ERROR_CATCH_ANY() \
CATCH_ANY() \
{ \
/* No errors were expected so error */ \
ERROR_THROW( \
THROW( \
AssertError, "statement '%s' threw error %s, '%s' but result <%s> expected", \
#statement, errorName(), errorMessage(), TEST_RESULT_resultExpectedStr); \
} \
@ -128,7 +128,7 @@ parameters.
TEST_TYPE_FORMAT(type, format, TEST_RESULT_result); \
\
/* Throw error */ \
ERROR_THROW( \
THROW( \
AssertError, "statement '%s' result is '%s' but '%s' expected", \
#statement, TEST_RESULT_resultStr, TEST_RESULT_resultExpectedStr); \
} \

View File

@ -11,18 +11,18 @@ bool testTryRecurseFinally = false;
void testTryRecurse()
{
ERROR_TRY()
TRY()
{
testTryRecurseTotal++;
assert(errorContext.tryTotal == testTryRecurseTotal + 1);
testTryRecurse();
}
ERROR_CATCH(MemoryError)
CATCH(MemoryError)
{
testTryRecurseCatch = true; // {uncoverable - catch should never be executed}
}
ERROR_FINALLY()
FINALLY()
{
testTryRecurseFinally = true;
}
@ -40,22 +40,22 @@ void testRun()
}
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("ERROR_TRY() with no errors"))
if (testBegin("TRY() with no errors"))
{
bool tryDone = false;
bool catchDone = false;
bool finallyDone = false;
ERROR_TRY()
TRY()
{
assert(errorContext.tryTotal == 1);
tryDone = true;
}
ERROR_CATCH_ANY()
CATCH_ANY()
{
catchDone = true; // {uncoverable - catch should never be executed}
}
ERROR_FINALLY()
FINALLY()
{
assert(errorContext.tryList[1].state == errorStateFinal);
finallyDone = true;
@ -68,52 +68,52 @@ void testRun()
}
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("ERROR_TRY() with multiple catches"))
if (testBegin("TRY() with multiple catches"))
{
bool tryDone = false;
bool catchDone = false;
bool finallyDone = false;
ERROR_TRY()
TRY()
{
assert(errorContext.tryTotal == 1);
ERROR_TRY()
TRY()
{
assert(errorContext.tryTotal == 2);
ERROR_TRY()
TRY()
{
assert(errorContext.tryTotal == 3);
ERROR_TRY()
TRY()
{
assert(errorContext.tryTotal == 4);
tryDone = true;
ERROR_THROW(AssertError, BOGUS_STR);
THROW(AssertError, BOGUS_STR);
}
}
ERROR_CATCH(AssertError)
CATCH(AssertError)
{
// Finally below should run even though this error has been rethrown
ERROR_RETHROW();
RETHROW();
}
ERROR_FINALLY()
FINALLY()
{
finallyDone = true;
}
}
ERROR_CATCH_ANY()
CATCH_ANY()
{
ERROR_RETHROW();
RETHROW();
}
}
ERROR_CATCH(MemoryError)
CATCH(MemoryError)
{
assert(false); // {uncoverable - catch should never be executed}
}
ERROR_CATCH(RuntimeError)
CATCH(RuntimeError)
{
assert(errorContext.tryTotal == 1);
assert(errorContext.tryList[1].state == errorStateCatch);
@ -134,12 +134,12 @@ void testRun()
bool catchDone = false;
bool finallyDone = false;
ERROR_TRY()
TRY()
{
tryDone = true;
testTryRecurse();
}
ERROR_CATCH(AssertError)
CATCH(AssertError)
{
assert(errorCode() == AssertError.code);
assert(errorFileName() != NULL);
@ -151,7 +151,7 @@ void testRun()
assert(strcmp(errorTypeName(errorType()), AssertError.name) == 0);
catchDone = true;
}
ERROR_FINALLY()
FINALLY()
{
finallyDone = true;
}

View File

@ -230,7 +230,7 @@ void testRun()
MEM_CONTEXT_BEGIN(memContext)
{
TEST_RESULT_STR(memContextName(memContextCurrent()), "test-block", "context is now test-block");
ERROR_THROW(AssertError, "error in test block");
THROW(AssertError, "error in test block");
}
MEM_CONTEXT_END(),
AssertError, "error in test block");
@ -263,17 +263,17 @@ void testRun()
memContextTestName = "test-new-failed-block";
bool bCatch = false;
ERROR_TRY()
TRY()
{
MEM_CONTEXT_NEW_BEGIN(memContextTestName)
{
memContext = MEM_CONTEXT_NEW();
TEST_RESULT_STR(memContextName(memContext), memContextTestName, "context is now '%s'", memContextTestName);
ERROR_THROW(AssertError, "create failed");
THROW(AssertError, "create failed");
}
MEM_CONTEXT_NEW_END();
}
ERROR_CATCH(AssertError)
CATCH(AssertError)
{
bCatch = true;
}