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:
parent
bcdfc7d0b5
commit
cf7da546a3
@ -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>
|
||||
|
||||
|
14
libc/LibC.h
14
libc/LibC.h
@ -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() \
|
||||
} \
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -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)
|
||||
|
@ -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(); \
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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++)
|
||||
|
@ -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); \
|
||||
} \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user