2017-10-16 10:09:56 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error Handler
|
|
|
|
***********************************************************************************************************************************/
|
2019-04-26 08:08:23 -04:00
|
|
|
#include "build.auto.h"
|
|
|
|
|
2017-10-16 10:09:56 -04:00
|
|
|
#include <stdarg.h>
|
2018-04-06 21:46:45 -04:00
|
|
|
#include <stdio.h>
|
2017-10-16 10:09:56 -04:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2017-11-02 08:14:13 -04:00
|
|
|
#include "common/error.h"
|
2018-05-18 11:57:32 -04:00
|
|
|
#include "common/stackTrace.h"
|
2017-10-16 10:09:56 -04:00
|
|
|
|
2018-02-08 16:11:47 -05:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Represents an error type
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
struct ErrorType
|
|
|
|
{
|
|
|
|
const int code;
|
|
|
|
const char *name;
|
|
|
|
const struct ErrorType *parentType;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Macro for defining new error types
|
|
|
|
#define ERROR_DEFINE(code, name, parentType) \
|
|
|
|
const ErrorType name = {code, #name, &parentType}
|
|
|
|
|
|
|
|
// Include error type definitions
|
|
|
|
#include "common/error.auto.c"
|
|
|
|
|
2017-10-16 10:09:56 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Maximum allowed number of nested try blocks
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define ERROR_TRY_MAX 32
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
States for each try
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
typedef enum {errorStateBegin, errorStateTry, errorStateCatch, errorStateFinal, errorStateEnd} ErrorState;
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Track error handling
|
|
|
|
***********************************************************************************************************************************/
|
2018-05-18 11:57:32 -04:00
|
|
|
static struct
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
// Array of jump buffers
|
|
|
|
jmp_buf jumpList[ERROR_TRY_MAX];
|
|
|
|
|
|
|
|
// State of each try
|
|
|
|
int tryTotal;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
ErrorState state;
|
|
|
|
bool uncaught;
|
|
|
|
} tryList[ERROR_TRY_MAX + 1];
|
|
|
|
|
|
|
|
// Last error
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
const ErrorType *errorType; // Error type
|
|
|
|
const char *fileName; // Source file where the error occurred
|
2018-05-18 11:57:32 -04:00
|
|
|
const char *functionName; // Function where the error occurred
|
2017-10-16 10:09:56 -04:00
|
|
|
int fileLine; // Source file line where the error occurred
|
|
|
|
const char *message; // Description of the error
|
2018-05-18 11:57:32 -04:00
|
|
|
const char *stackTrace; // Stack trace
|
2017-10-16 10:09:56 -04:00
|
|
|
} error;
|
|
|
|
} errorContext;
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Message buffer and buffer size
|
|
|
|
|
|
|
|
The message buffer is statically allocated so there is some space to store error messages. Not being able to allocate such a small
|
|
|
|
amount of memory seems pretty unlikely so just keep the code simple and let the loader deal with massively constrained memory
|
|
|
|
situations.
|
|
|
|
|
|
|
|
The temp buffer is required because the error message being passed might be the error already stored in the message buffer.
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define ERROR_MESSAGE_BUFFER_SIZE 8192
|
|
|
|
|
|
|
|
static char messageBuffer[ERROR_MESSAGE_BUFFER_SIZE];
|
|
|
|
static char messageBufferTemp[ERROR_MESSAGE_BUFFER_SIZE];
|
2018-05-18 11:57:32 -04:00
|
|
|
static char stackTraceBuffer[ERROR_MESSAGE_BUFFER_SIZE];
|
2017-10-16 10:09:56 -04:00
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
2018-02-08 16:11:47 -05:00
|
|
|
Error type code
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
int
|
|
|
|
errorTypeCode(const ErrorType *errorType)
|
|
|
|
{
|
|
|
|
return errorType->code;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Get error type using a code
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const ErrorType *
|
|
|
|
errorTypeFromCode(int code)
|
|
|
|
{
|
|
|
|
// Search for error type by code
|
|
|
|
int errorTypeIdx = 0;
|
|
|
|
const ErrorType *result = errorTypeList[errorTypeIdx];
|
|
|
|
|
|
|
|
while (result != NULL)
|
|
|
|
{
|
|
|
|
if (result->code == code)
|
|
|
|
break;
|
|
|
|
|
|
|
|
result = errorTypeList[++errorTypeIdx];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error if type was not found
|
|
|
|
if (result == NULL)
|
2019-01-14 21:34:22 +02:00
|
|
|
result = &UnknownError;
|
2018-02-08 16:11:47 -05:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error type name
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const char *
|
|
|
|
errorTypeName(const ErrorType *errorType)
|
|
|
|
{
|
|
|
|
return errorType->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error type parent
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const ErrorType *
|
|
|
|
errorTypeParent(const ErrorType *errorType)
|
|
|
|
{
|
|
|
|
return errorType->parentType;
|
|
|
|
}
|
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Get the depth of the current try statement (0 if none)
|
|
|
|
***********************************************************************************************************************************/
|
2018-08-03 19:19:14 -04:00
|
|
|
unsigned int errorTryDepth(void)
|
2018-05-18 11:57:32 -04:00
|
|
|
{
|
|
|
|
return (unsigned int)errorContext.tryTotal;
|
|
|
|
}
|
|
|
|
|
2018-02-08 16:11:47 -05:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Does the child error type extend the parent error type?
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
bool
|
|
|
|
errorTypeExtends(const ErrorType *child, const ErrorType *parent)
|
|
|
|
{
|
2018-05-05 09:38:09 -04:00
|
|
|
const ErrorType *find = child;
|
|
|
|
|
|
|
|
do
|
2018-02-08 16:11:47 -05:00
|
|
|
{
|
2018-05-05 09:38:09 -04:00
|
|
|
find = errorTypeParent(find);
|
|
|
|
|
|
|
|
// Parent was found
|
|
|
|
if (find == parent)
|
2018-02-08 16:11:47 -05:00
|
|
|
return true;
|
|
|
|
}
|
2018-05-05 09:38:09 -04:00
|
|
|
while (find != errorTypeParent(find));
|
2018-02-08 16:11:47 -05:00
|
|
|
|
|
|
|
// Parent was not found
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
2017-10-16 10:09:56 -04:00
|
|
|
Error type
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const ErrorType *
|
2018-08-03 19:19:14 -04:00
|
|
|
errorType(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorContext.error.errorType;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error code (pulled from error type)
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
int
|
2018-08-03 19:19:14 -04:00
|
|
|
errorCode(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorTypeCode(errorType());
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error filename
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const char *
|
2018-08-03 19:19:14 -04:00
|
|
|
errorFileName(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorContext.error.fileName;
|
|
|
|
}
|
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error function name
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const char *
|
2018-08-03 19:19:14 -04:00
|
|
|
errorFunctionName(void)
|
2018-05-18 11:57:32 -04:00
|
|
|
{
|
|
|
|
return errorContext.error.functionName;
|
|
|
|
}
|
|
|
|
|
2017-10-16 10:09:56 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error file line number
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
int
|
2018-08-03 19:19:14 -04:00
|
|
|
errorFileLine(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorContext.error.fileLine;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error message
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const char *
|
2018-08-03 19:19:14 -04:00
|
|
|
errorMessage(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorContext.error.message;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error name (pulled from error type)
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const char *
|
2018-08-03 19:19:14 -04:00
|
|
|
errorName(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorTypeName(errorType());
|
|
|
|
}
|
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Error stack trace
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
const char *
|
2018-08-03 19:19:14 -04:00
|
|
|
errorStackTrace(void)
|
2018-05-18 11:57:32 -04:00
|
|
|
{
|
|
|
|
return errorContext.error.stackTrace;
|
|
|
|
}
|
|
|
|
|
2017-10-16 10:09:56 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Is this error an instance of the error type?
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
bool
|
|
|
|
errorInstanceOf(const ErrorType *errorTypeTest)
|
|
|
|
{
|
|
|
|
return errorType() == errorTypeTest || errorTypeExtends(errorType(), errorTypeTest);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Return current error context state
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
static ErrorState
|
2018-08-03 19:19:14 -04:00
|
|
|
errorInternalState(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorContext.tryList[errorContext.tryTotal].state;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
True when in try state
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
bool
|
2018-08-03 19:19:14 -04:00
|
|
|
errorInternalStateTry(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorInternalState() == errorStateTry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
True when in catch state and the expected error matches
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
bool
|
|
|
|
errorInternalStateCatch(const ErrorType *errorTypeCatch)
|
|
|
|
{
|
2018-05-05 09:38:09 -04:00
|
|
|
if (errorInternalState() == errorStateCatch && errorInstanceOf(errorTypeCatch))
|
|
|
|
return errorInternalProcess(true);
|
|
|
|
|
|
|
|
return false;
|
2017-10-16 10:09:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
True when in final state
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
bool
|
2018-08-03 19:19:14 -04:00
|
|
|
errorInternalStateFinal(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return errorInternalState() == errorStateFinal;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Return jump buffer for current try
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
jmp_buf *
|
2018-08-03 19:19:14 -04:00
|
|
|
errorInternalJump(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
return &errorContext.jumpList[errorContext.tryTotal - 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Begin the try block
|
|
|
|
***********************************************************************************************************************************/
|
2018-01-31 18:22:25 -05:00
|
|
|
bool
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalTry(const char *fileName, const char *functionName, int fileLine)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
// If try total has been exceeded then throw an error
|
|
|
|
if (errorContext.tryTotal >= ERROR_TRY_MAX)
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrowFmt(&AssertError, fileName, functionName, fileLine, "too many nested try blocks");
|
2017-10-16 10:09:56 -04:00
|
|
|
|
|
|
|
// Increment try total
|
|
|
|
errorContext.tryTotal++;
|
|
|
|
|
|
|
|
// Setup try
|
|
|
|
errorContext.tryList[errorContext.tryTotal].state = errorStateBegin;
|
|
|
|
errorContext.tryList[errorContext.tryTotal].uncaught = false;
|
|
|
|
|
|
|
|
// Try setup was successful
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Propogate the error up so it can be caught
|
|
|
|
***********************************************************************************************************************************/
|
2018-01-31 18:22:25 -05:00
|
|
|
void
|
2018-08-03 19:19:14 -04:00
|
|
|
errorInternalPropagate(void)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
// Mark the error as uncaught
|
|
|
|
errorContext.tryList[errorContext.tryTotal].uncaught = true;
|
|
|
|
|
|
|
|
// If there is a parent try then jump to it
|
|
|
|
if (errorContext.tryTotal > 0)
|
|
|
|
longjmp(errorContext.jumpList[errorContext.tryTotal - 1], 1);
|
|
|
|
|
|
|
|
// If there was no try to catch this error then output to stderr
|
2018-05-05 09:38:09 -04:00
|
|
|
fprintf(stderr, "\nUncaught %s: %s\n thrown at %s:%d\n\n", errorName(), errorMessage(), errorFileName(), errorFileLine());
|
|
|
|
fflush(stderr);
|
2017-10-16 10:09:56 -04:00
|
|
|
|
|
|
|
// Exit with failure
|
2018-05-05 09:38:09 -04:00
|
|
|
exit(UnhandledError.code);
|
2017-10-16 10:09:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Process the error through each try and state
|
|
|
|
***********************************************************************************************************************************/
|
2018-01-31 18:22:25 -05:00
|
|
|
bool
|
|
|
|
errorInternalProcess(bool catch)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
// If a catch statement then return
|
|
|
|
if (catch)
|
|
|
|
{
|
|
|
|
errorContext.tryList[errorContext.tryTotal].uncaught = false;
|
|
|
|
return true;
|
|
|
|
}
|
2018-05-18 11:57:32 -04:00
|
|
|
// Else if just entering error state clean up the stack
|
|
|
|
else if (errorContext.tryList[errorContext.tryTotal].state == errorStateTry)
|
|
|
|
stackTraceClean(errorTryDepth());
|
2017-10-16 10:09:56 -04:00
|
|
|
|
|
|
|
// Increment the state
|
|
|
|
errorContext.tryList[errorContext.tryTotal].state++;
|
|
|
|
|
|
|
|
// If the error has been caught then increment the state
|
|
|
|
if (errorContext.tryList[errorContext.tryTotal].state == errorStateCatch &&
|
|
|
|
!errorContext.tryList[errorContext.tryTotal].uncaught)
|
|
|
|
{
|
|
|
|
errorContext.tryList[errorContext.tryTotal].state++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return if not done
|
|
|
|
if (errorContext.tryList[errorContext.tryTotal].state < errorStateEnd)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Remove the try
|
|
|
|
errorContext.tryTotal--;
|
|
|
|
|
|
|
|
// If not caught in the last try then propogate
|
|
|
|
if (errorContext.tryList[errorContext.tryTotal + 1].uncaught)
|
|
|
|
errorInternalPropagate();
|
|
|
|
|
|
|
|
// Nothing left to process
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Throw an error
|
|
|
|
***********************************************************************************************************************************/
|
2018-01-31 18:22:25 -05:00
|
|
|
void
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrow(const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message)
|
2017-10-16 10:09:56 -04:00
|
|
|
{
|
|
|
|
// Setup error data
|
|
|
|
errorContext.error.errorType = errorType;
|
|
|
|
errorContext.error.fileName = fileName;
|
2018-05-18 11:57:32 -04:00
|
|
|
errorContext.error.functionName = functionName;
|
2017-10-16 10:09:56 -04:00
|
|
|
errorContext.error.fileLine = fileLine;
|
|
|
|
|
2018-05-03 11:24:29 -04:00
|
|
|
// Assign message to the error
|
2018-05-21 08:06:31 -04:00
|
|
|
strncpy(messageBuffer, message, sizeof(messageBuffer));
|
|
|
|
messageBuffer[sizeof(messageBuffer) - 1] = 0;
|
|
|
|
|
2018-05-03 11:24:29 -04:00
|
|
|
errorContext.error.message = (const char *)messageBuffer;
|
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
// Generate the stack trace for the error
|
|
|
|
if (stackTraceToZ(
|
|
|
|
stackTraceBuffer, sizeof(stackTraceBuffer), fileName, functionName, (unsigned int)fileLine) >= sizeof(stackTraceBuffer))
|
|
|
|
{
|
|
|
|
// Indicate that the stack trace was truncated
|
|
|
|
}
|
|
|
|
|
|
|
|
errorContext.error.stackTrace = (const char *)stackTraceBuffer;
|
|
|
|
|
2018-05-03 11:24:29 -04:00
|
|
|
// Propogate the error
|
|
|
|
errorInternalPropagate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrowFmt(
|
|
|
|
const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...)
|
2018-05-03 11:24:29 -04:00
|
|
|
{
|
|
|
|
// Format message
|
2017-10-16 10:09:56 -04:00
|
|
|
va_list argument;
|
|
|
|
va_start(argument, format);
|
|
|
|
vsnprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, format, argument);
|
2018-01-16 13:29:27 -05:00
|
|
|
va_end(argument);
|
2017-10-16 10:09:56 -04:00
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrow(errorType, fileName, functionName, fileLine, messageBufferTemp);
|
2018-05-03 11:24:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Throw a system error
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
void
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrowSys(
|
2019-05-11 14:51:51 -04:00
|
|
|
#ifdef DEBUG_COVERAGE
|
|
|
|
bool error,
|
|
|
|
#else
|
|
|
|
int errNo,
|
|
|
|
#endif
|
|
|
|
const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message)
|
2018-05-03 11:24:29 -04:00
|
|
|
{
|
2019-05-11 14:51:51 -04:00
|
|
|
#ifdef DEBUG_COVERAGE
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
int errNo = errno;
|
|
|
|
#endif
|
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
// Format message with system message appended
|
2019-04-29 18:03:32 -04:00
|
|
|
if (errNo == 0)
|
|
|
|
{
|
|
|
|
strncpy(messageBufferTemp, message, ERROR_MESSAGE_BUFFER_SIZE - 1);
|
|
|
|
messageBufferTemp[sizeof(messageBuffer) - 1] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
snprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, "%s: [%d] %s", message, errNo, strerror(errNo));
|
2018-05-03 11:24:29 -04:00
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrow(errorType, fileName, functionName, fileLine, messageBufferTemp);
|
2019-05-11 14:51:51 -04:00
|
|
|
|
|
|
|
#ifdef DEBUG_COVERAGE
|
|
|
|
}
|
|
|
|
#endif
|
2018-03-18 13:32:19 -04:00
|
|
|
}
|
2018-01-16 13:29:27 -05:00
|
|
|
|
2018-01-31 18:22:25 -05:00
|
|
|
void
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrowSysFmt(
|
2019-05-11 14:51:51 -04:00
|
|
|
#ifdef DEBUG_COVERAGE
|
|
|
|
bool error,
|
|
|
|
#else
|
|
|
|
int errNo,
|
|
|
|
#endif
|
|
|
|
const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...)
|
2018-01-16 13:29:27 -05:00
|
|
|
{
|
2019-05-11 14:51:51 -04:00
|
|
|
#ifdef DEBUG_COVERAGE
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
int errNo = errno;
|
|
|
|
#endif
|
|
|
|
|
2018-05-03 11:24:29 -04:00
|
|
|
// Format message
|
2018-03-24 14:11:29 -04:00
|
|
|
va_list argument;
|
|
|
|
va_start(argument, format);
|
|
|
|
size_t messageSize = (size_t)vsnprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, format, argument);
|
|
|
|
va_end(argument);
|
2018-01-16 13:29:27 -05:00
|
|
|
|
2018-03-24 14:11:29 -04:00
|
|
|
// Append the system message
|
2019-04-29 18:03:32 -04:00
|
|
|
if (errNo != 0)
|
|
|
|
snprintf(messageBufferTemp + messageSize, ERROR_MESSAGE_BUFFER_SIZE - 1 - messageSize, ": [%d] %s", errNo, strerror(errNo));
|
2018-01-16 13:29:27 -05:00
|
|
|
|
2018-05-18 11:57:32 -04:00
|
|
|
errorInternalThrow(errorType, fileName, functionName, fileLine, messageBufferTemp);
|
2019-05-11 14:51:51 -04:00
|
|
|
|
|
|
|
#ifdef DEBUG_COVERAGE
|
|
|
|
}
|
|
|
|
#endif
|
2018-01-16 13:29:27 -05:00
|
|
|
}
|