1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Add _FMT variants for all THROW macros so format types are checked by the compiler.

This commit is contained in:
David Steele 2018-05-03 11:24:29 -04:00
parent 6a40c916d4
commit c3a8fbe706
40 changed files with 246 additions and 194 deletions

View File

@ -136,7 +136,7 @@
</release-item>
<release-item>
<p>Add <code>THROWP_</code>* macro variants for error handling. These macros allow an <code>ErrorType</code> pointer to be passed and are required for functions that may return different errors based on a parameter.</p>
<p>Error handling improvments. Add <code>THROWP_</code>* macro variants for error handling. These macros allow an <code>ErrorType</code> pointer to be passed and are required for functions that may return different errors based on a parameter. Add <code>_FMT</code> variants for all <code>THROW</code> macros so format types are checked by the compiler.</p>
</release-item>
<release-item>

View File

@ -54,7 +54,7 @@ cipherBlockNew(CipherMode mode, const char *cipherName, const unsigned char *pas
const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipherName);
if (!cipher)
THROW(AssertError, "unable to load cipher '%s'", cipherName);
THROW_FMT(AssertError, "unable to load cipher '%s'", cipherName);
// Lookup digest. If not defined it will be set to sha1.
const EVP_MD *digest = NULL;
@ -65,7 +65,7 @@ cipherBlockNew(CipherMode mode, const char *cipherName, const unsigned char *pas
digest = EVP_sha1();
if (!digest)
THROW(AssertError, "unable to load digest '%s'", digestName);
THROW_FMT(AssertError, "unable to load digest '%s'", digestName);
// Allocate memory to hold process state
CipherBlock *this = NULL;

View File

@ -33,7 +33,7 @@ archiveAsyncStatus(ArchiveMode archiveMode, const String *walSegment, bool confe
// If more than one status file was found then assert - this could be a bug in the async process
if (strLstSize(fileList) != 1)
{
THROW(
THROW_FMT(
AssertError, "multiple status files found in '%s' for WAL segment '%s'",
strPtr(storagePath(storageSpool(), spoolQueue)), strPtr(walSegment));
}
@ -55,11 +55,11 @@ archiveAsyncStatus(ArchiveMode archiveMode, const String *walSegment, bool confe
// Error if linefeed not found
if (linefeedPtr == NULL)
THROW(FormatError, "%s content must have at least two lines", strPtr(statusFile));
THROW_FMT(FormatError, "%s content must have at least two lines", strPtr(statusFile));
// Error if message is zero-length
if (strlen(linefeedPtr + 1) == 0)
THROW(FormatError, "%s message must be > 0", strPtr(statusFile));
THROW_FMT(FormatError, "%s message must be > 0", strPtr(statusFile));
// Get contents
code = varIntForce(varNewStr(strNewN(strPtr(content), (size_t)(linefeedPtr - strPtr(content)))));
@ -89,7 +89,7 @@ archiveAsyncStatus(ArchiveMode archiveMode, const String *walSegment, bool confe
{
// Error status files must have content
if (strSize(content) == 0)
THROW(AssertError, "status file '%s' has no content", strPtr(statusFile));
THROW_FMT(AssertError, "status file '%s' has no content", strPtr(statusFile));
// Throw error using the code passed in the file
THROW_CODE(code, strPtr(message));

View File

@ -110,7 +110,7 @@ cmdArchivePush()
// If the WAL segment was not pushed then error
if (!pushed)
{
THROW(
THROW_FMT(
ArchiveTimeoutError, "unable to push WAL segment '%s' asynchronously after %lg second(s)",
strPtr(walSegment), cfgOptionDbl(cfgOptArchiveTimeout));
}

View File

@ -294,7 +294,7 @@ helpRender()
if (cfgDefOptionId(optionName) != -1)
optionId = cfgOptionIdFromDefId(cfgDefOptionId(optionName), 0);
else
THROW(OptionInvalidError, "option '%s' is not valid for command '%s'", optionName, commandName);
THROW_FMT(OptionInvalidError, "option '%s' is not valid for command '%s'", optionName, commandName);
}
// Output option summary and description

View File

@ -12,7 +12,7 @@ For very important asserts that are shipped with the production code
#define ASSERT(condition) \
{ \
if (!(condition)) \
THROW(AssertError, "assertion '%s' failed", #condition); \
THROW_FMT(AssertError, "assertion '%s' failed", #condition); \
}
/***********************************************************************************************************************************
@ -23,7 +23,7 @@ be too expensive to ship with the production code.
#define ASSERT_DEBUG(condition) \
{ \
if (!(condition)) \
THROW(AssertError, "debug assertion '%s' failed", #condition); \
THROW_FMT(AssertError, "debug assertion '%s' failed", #condition); \
}
#else
#define ASSERT_DEBUG(condition)

View File

@ -12,7 +12,7 @@ Binary to String Encode/Decode
Macro to handle invalid encode type errors
***********************************************************************************************************************************/
#define ENCODE_TYPE_INVALID_ERROR(encodeType) \
THROW(AssertError, "invalid encode type %d", encodeType);
THROW_FMT(AssertError, "invalid encode type %u", encodeType);
/***********************************************************************************************************************************
Encode binary data to a printable string

View File

@ -165,7 +165,7 @@ decodeToBinValidateBase64(const char *source)
size_t sourceSize = strlen(source);
if (sourceSize % 4 != 0)
THROW(FormatError, "base64 size %d is not evenly divisible by 4", sourceSize);
THROW_FMT(FormatError, "base64 size %zu is not evenly divisible by 4", sourceSize);
// Check all characters
for (unsigned int sourceIdx = 0; sourceIdx < sourceSize; sourceIdx++)
@ -185,7 +185,7 @@ decodeToBinValidateBase64(const char *source)
{
// Error on any invalid characters
if (decodeBase64Lookup[(int)source[sourceIdx]] == -1)
THROW(FormatError, "base64 invalid character found at position %d", sourceIdx);
THROW_FMT(FormatError, "base64 invalid character found at position %u", sourceIdx);
}
}
}

View File

@ -105,7 +105,7 @@ errorTypeFromCode(int code)
// Error if type was not found
if (result == NULL)
THROW(AssertError, "could not find error type for code '%d'", code);
THROW_FMT(AssertError, "could not find error type for code '%d'", code);
return result;
}
@ -261,7 +261,7 @@ errorInternalTry(const char *fileName, int fileLine)
{
// If try total has been exceeded then throw an error
if (errorContext.tryTotal >= ERROR_TRY_MAX)
errorInternalThrow(&AssertError, fileName, fileLine, "too many nested try blocks");
errorInternalThrowFmt(&AssertError, fileName, fileLine, "too many nested try blocks");
// Increment try total
errorContext.tryTotal++;
@ -341,19 +341,47 @@ errorInternalProcess(bool catch)
Throw an error
***********************************************************************************************************************************/
void
errorInternalThrow(const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...)
errorInternalThrow(const ErrorType *errorType, const char *fileName, int fileLine, const char *message)
{
// Setup error data
errorContext.error.errorType = errorType;
errorContext.error.fileName = fileName;
errorContext.error.fileLine = fileLine;
// Create message
// Assign message to the error
strcpy(messageBuffer, message);
errorContext.error.message = (const char *)messageBuffer;
// Propogate the error
errorInternalPropagate();
}
void
errorInternalThrowFmt(const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...)
{
// Format message
va_list argument;
va_start(argument, format);
vsnprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, format, argument);
va_end(argument);
errorInternalThrow(errorType, fileName, fileLine, messageBufferTemp);
}
/***********************************************************************************************************************************
Throw a system error
***********************************************************************************************************************************/
void
errorInternalThrowSys(int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *message)
{
// Setup error data
errorContext.error.errorType = errorType;
errorContext.error.fileName = fileName;
errorContext.error.fileLine = fileLine;
// Append the system message
snprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, "%s: [%d] %s", message, errNo, strerror(errNo));
// Assign message to the error
strcpy(messageBuffer, messageBufferTemp);
errorContext.error.message = (const char *)messageBuffer;
@ -362,18 +390,15 @@ errorInternalThrow(const ErrorType *errorType, const char *fileName, int fileLin
errorInternalPropagate();
}
/***********************************************************************************************************************************
Throw an error
***********************************************************************************************************************************/
void
errorInternalThrowSys(int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...)
errorInternalThrowSysFmt(int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...)
{
// Setup error data
errorContext.error.errorType = errorType;
errorContext.error.fileName = fileName;
errorContext.error.fileLine = fileLine;
// Create message
// Format message
va_list argument;
va_start(argument, format);
size_t messageSize = (size_t)vsnprintf(messageBufferTemp, ERROR_MESSAGE_BUFFER_SIZE - 1, format, argument);

View File

@ -117,26 +117,40 @@ error information to stderr.
The seldom used "THROWP" variants allow an error to be thrown with a pointer to the error type.
***********************************************************************************************************************************/
#define THROW(errorType, ...) \
errorInternalThrow(&errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROWP(errorType, ...) \
errorInternalThrow(errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROW(errorType, message) \
errorInternalThrow(&errorType, __FILE__, __LINE__, message)
#define THROW_FMT(errorType, ...) \
errorInternalThrowFmt(&errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROWP(errorType, message) \
errorInternalThrow(errorType, __FILE__, __LINE__, message)
#define THROWP_FMT(errorType, ...) \
errorInternalThrowFmt(errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROW_CODE(errorCode, ...) \
errorInternalThrow(errorTypeFromCode(errorCode), __FILE__, __LINE__, __VA_ARGS__)
#define THROW_CODE(errorCode, message) \
errorInternalThrow(errorTypeFromCode(errorCode), __FILE__, __LINE__, message)
#define THROW_CODE_FMT(errorCode, ...) \
errorInternalThrowFmt(errorTypeFromCode(errorCode), __FILE__, __LINE__, __VA_ARGS__)
/***********************************************************************************************************************************
Throw an error when a system call fails
***********************************************************************************************************************************/
#define THROW_SYS_ERROR(errorType, ...) \
errorInternalThrowSys(errno, &errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROWP_SYS_ERROR(errorType, ...) \
errorInternalThrowSys(errno, errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROW_SYS_ERROR(errorType, message) \
errorInternalThrowSys(errno, &errorType, __FILE__, __LINE__, message)
#define THROW_SYS_ERROR_FMT(errorType, ...) \
errorInternalThrowSysFmt(errno, &errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROWP_SYS_ERROR(errorType, message) \
errorInternalThrowSys(errno, errorType, __FILE__, __LINE__, message)
#define THROWP_SYS_ERROR_FMT(errorType, ...) \
errorInternalThrowSysFmt(errno, errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROW_SYS_ERROR_CODE(errNo, errorType, ...) \
errorInternalThrowSys(errNo, &errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROWP_SYS_ERROR_CODE(errNo, errorType, ...) \
errorInternalThrowSys(errNo, errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROW_SYS_ERROR_CODE(errNo, errorType, message) \
errorInternalThrowSys(errNo, &errorType, __FILE__, __LINE__, message)
#define THROW_SYS_ERROR_CODE_FMT(errNo, errorType, ...) \
errorInternalThrowSysFmt(errNo, &errorType, __FILE__, __LINE__, __VA_ARGS__)
#define THROWP_SYS_ERROR_CODE(errNo, errorType, message) \
errorInternalThrowSys(errNo, errorType, __FILE__, __LINE__, message)
#define THROWP_SYS_ERROR_CODE_FMT(errNo, errorType, ...) \
errorInternalThrowSysFmt(errNo, errorType, __FILE__, __LINE__, __VA_ARGS__)
/***********************************************************************************************************************************
Rethrow the current error
@ -157,7 +171,14 @@ bool errorInternalStateFinal();
bool errorInternalProcess(bool catch);
void errorInternalPropagate() __attribute__((__noreturn__));
void errorInternalThrow(
const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...) __attribute__((__noreturn__));
void errorInternalThrowSys(int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...);
const ErrorType *errorType, const char *fileName, int fileLine, const char *message) __attribute__((__noreturn__));
void errorInternalThrowFmt(
const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...)
__attribute__((__noreturn__)) __attribute__((format(printf, 4, 5)));
void errorInternalThrowSys(
int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *message);
void errorInternalThrowSysFmt(
int errNo, const ErrorType *errorType, const char *fileName, int fileLine, const char *format, ...)
__attribute__((format(printf, 5, 6)));
#endif

View File

@ -76,7 +76,7 @@ iniGet(const Ini *this, const String *section, const String *key)
// If value is null replace it with default
if (result == NULL)
THROW(FormatError, "section '%s', key '%s' does not exist", strPtr(section), strPtr(key));
THROW_FMT(FormatError, "section '%s', key '%s' does not exist", strPtr(section), strPtr(key));
return result;
}
@ -161,7 +161,7 @@ iniParse(Ini *this, const String *content)
{
// Make sure the section ends with ]
if (linePtr[strSize(line) - 1] != ']')
THROW(FormatError, "ini section should end with ] at line %d: %s", lineIdx + 1, linePtr);
THROW_FMT(FormatError, "ini section should end with ] at line %u: %s", lineIdx + 1, linePtr);
// Assign section
section = strNewN(linePtr + 1, strSize(line) - 2);
@ -170,19 +170,19 @@ iniParse(Ini *this, const String *content)
else
{
if (section == NULL)
THROW(FormatError, "key/value found outside of section at line %d: %s", lineIdx + 1, linePtr);
THROW_FMT(FormatError, "key/value found outside of section at line %u: %s", lineIdx + 1, linePtr);
// Find the =
const char *lineEqual = strstr(linePtr, "=");
if (lineEqual == NULL)
THROW(FormatError, "missing '=' in key/value at line %d: %s", lineIdx + 1, linePtr);
THROW_FMT(FormatError, "missing '=' in key/value at line %u: %s", lineIdx + 1, linePtr);
// Extract the key
String *key = strTrim(strNewN(linePtr, (size_t)(lineEqual - linePtr)));
if (strSize(key) == 0)
THROW(FormatError, "key is zero-length at line %d: %s", lineIdx++, linePtr);
THROW_FMT(FormatError, "key is zero-length at line %u: %s", lineIdx++, linePtr);
// Extract the value
Variant *value = varNewStr(strTrim(strNew(lineEqual + 1)));

View File

@ -13,5 +13,5 @@ void
ioHandleWriteOneStr(int handle, const String *string)
{
if (write(handle, strPtr(string), strSize(string)) != (int)strSize(string))
THROW_SYS_ERROR(FileWriteError, "unable to write to %u byte(s) to handle", strSize(string));
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write to %zu byte(s) to handle", strSize(string));
}

View File

@ -99,7 +99,7 @@ lockAcquireFile(const String *lockFile, double lockTimeout, bool failOnNoLock)
strPtr(lockFile));
}
THROW(
THROW_FMT(
LockAcquireError, "unable to acquire lock on file '%s': %s%s",
strPtr(lockFile), strerror(errNo), errorHint == NULL ? "" : strPtr(errorHint));
}

View File

@ -79,7 +79,7 @@ logLevelEnum(const char *logLevel)
// If the log level was not found
if (result == LOG_LEVEL_TOTAL)
THROW(AssertError, "log level '%s' not found", logLevel);
THROW_FMT(AssertError, "log level '%s' not found", logLevel);
return result;
}
@ -88,7 +88,7 @@ const char *
logLevelStr(LogLevel logLevel)
{
if (logLevel >= LOG_LEVEL_TOTAL)
THROW(AssertError, "invalid log level '%d'", logLevel);
THROW_FMT(AssertError, "invalid log level '%u'", logLevel);
return logLevelList[logLevel];
}

View File

@ -69,7 +69,7 @@ memAllocInternal(size_t size, bool zero)
// Error when malloc fails
if (buffer == NULL)
THROW(MemoryError, "unable to allocate %lu bytes", size);
THROW_FMT(MemoryError, "unable to allocate %zu bytes", size);
// Zero the memory when requested
if (zero)
@ -90,7 +90,7 @@ memReAllocInternal(void *bufferOld, size_t sizeOld, size_t sizeNew, bool zeroNew
// Error when realloc fails
if (bufferNew == NULL)
THROW(MemoryError, "unable to reallocate %lu bytes", sizeNew);
THROW_FMT(MemoryError, "unable to reallocate %zu bytes", sizeNew);
// Zero the new memory when requested - old memory is left untouched else why bother with a realloc?
if (zeroNew)
@ -171,7 +171,7 @@ memContextNew(const char *name)
{
// Check context name length
if (strlen(name) == 0 || strlen(name) > MEM_CONTEXT_NAME_SIZE)
THROW(AssertError, "context name length must be > 0 and <= %d", MEM_CONTEXT_NAME_SIZE);
THROW_FMT(AssertError, "context name length must be > 0 and <= %d", MEM_CONTEXT_NAME_SIZE);
// Find space for the new context
unsigned int contextIdx = memContextNewIndex(memContextCurrent(), true);
@ -216,7 +216,7 @@ memContextCallback(MemContext *this, void (*callbackFunction)(void *), void *cal
// Error if callback has already been set - there may be valid use cases for this but error until one is found
if (this->callbackFunction)
THROW(AssertError, "callback is already set for context '%s'", this->name);
THROW_FMT(AssertError, "callback is already set for context '%s'", this->name);
// Set callback function and argument
this->callbackFunction = callbackFunction;
@ -443,7 +443,7 @@ memContextFree(MemContext *this)
// Current context cannot be freed unless it is top (top is never really freed, just the stuff under it)
if (this == memContextCurrent() && this != memContextTop())
THROW(AssertError, "cannot free current context '%s'", this->name);
THROW_FMT(AssertError, "cannot free current context '%s'", this->name);
// Error if context is not active
if (this->state != memContextStateActive)

View File

@ -82,7 +82,7 @@ lstGet(const List *this, unsigned int listIdx)
{
// Ensure list index is in range
if (listIdx >= this->listSize)
THROW(AssertError, "cannot get index %d from list with %d value(s)", listIdx, this->listSize);
THROW_FMT(AssertError, "cannot get index %u from list with %u value(s)", listIdx, this->listSize);
// Return pointer to list item
return this->list + (listIdx * this->itemSize);

View File

@ -449,7 +449,7 @@ strTrunc(String *this, int idx)
{
// If the index position is outside the array boundaries then error
if (idx < 0 || (size_t)idx > this->size)
THROW(AssertError, "index passed is outside the string boundaries");
THROW_FMT(AssertError, "index passed is outside the string boundaries");
if (this->size > 0)
{

View File

@ -172,7 +172,7 @@ varEq(const Variant *this1, const Variant *this2)
case varTypeKeyValue:
case varTypeVariantList:
THROW(AssertError, "unable to test equality for %s", variantTypeName[this1->type]);
THROW_FMT(AssertError, "unable to test equality for %s", variantTypeName[this1->type]);
}
}
}
@ -256,7 +256,7 @@ varBoolForce(const Variant *this)
// If string was not found then not a boolean
if (boolIdx == sizeof(boolString) / sizeof(char *))
THROW(FormatError, "unable to convert str '%s' to bool", string);
THROW_FMT(FormatError, "unable to convert str '%s' to bool", string);
// False if in first half of list, true if in second half
result = boolIdx / (sizeof(boolString) / sizeof(char *) / 2);
@ -265,7 +265,7 @@ varBoolForce(const Variant *this)
}
default:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeBool]);
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeBool]);
}
return result;
@ -334,7 +334,7 @@ varDblForce(const Variant *this)
if (result == 0 && strcmp(strPtr(varStr(this)), "0") != 0)
{
THROW(
THROW_FMT(
FormatError, "unable to force %s '%s' to %s", variantTypeName[this->type], strPtr(varStr(this)),
variantTypeName[varTypeDouble]);
}
@ -343,7 +343,7 @@ varDblForce(const Variant *this)
}
default:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeDouble]);
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeDouble]);
}
return result;
@ -399,7 +399,7 @@ varIntForce(const Variant *this)
int64_t resultTest = varInt64(this);
if (resultTest > 2147483647 || resultTest < -2147483648)
THROW(
THROW_FMT(
AssertError, "unable to convert %s %" PRId64 " to %s", variantTypeName[this->type], resultTest,
variantTypeName[varTypeInt]);
@ -412,13 +412,13 @@ varIntForce(const Variant *this)
result = atoi(strPtr(varStr(this)));
if (result == 0 && strcmp(strPtr(varStr(this)), "0") != 0)
THROW(FormatError, "unable to convert str '%s' to int", strPtr(varStr(this)));
THROW_FMT(FormatError, "unable to convert str '%s' to int", strPtr(varStr(this)));
break;
}
default:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt]);
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt]);
}
return result;
@ -441,7 +441,7 @@ varInt64(const Variant *this)
{
// Only valid for int
if (this->type != varTypeInt64)
THROW(AssertError, "variant type is not %s", variantTypeName[varTypeInt64]);
THROW_FMT(AssertError, "variant type is not %s", variantTypeName[varTypeInt64]);
// Get the int
return *((int64_t *)varData(this));
@ -483,7 +483,7 @@ varInt64Force(const Variant *this)
snprintf(buffer, sizeof(buffer), "%" PRId64, result);
if (strcmp(strPtr(varStr(this)), buffer) != 0)
THROW(
THROW_FMT(
FormatError, "unable to convert %s '%s' to %s", variantTypeName[varTypeString], strPtr(varStr(this)),
variantTypeName[varTypeInt64]);
@ -491,7 +491,7 @@ varInt64Force(const Variant *this)
}
default:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt64]);
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt64]);
}
return result;
@ -651,7 +651,7 @@ varStrForce(const Variant *this)
case varTypeKeyValue:
case varTypeVariantList:
THROW(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeString]);
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeString]);
}
return result;
@ -691,7 +691,7 @@ varVarLst(const Variant *this)
{
// Only valid for key/value
if (this->type != varTypeVariantList)
THROW(AssertError, "variant type is not '%s'", variantTypeName[varTypeVariantList]);
THROW_FMT(AssertError, "variant type is not '%s'", variantTypeName[varTypeVariantList]);
// Get the string
result = *((VariantList **)varData(this));

View File

@ -178,7 +178,7 @@ void
cfgCommandCheck(ConfigCommand commandId)
{
if (commandId >= CFG_COMMAND_TOTAL)
THROW(AssertError, "command id %d invalid - must be >= 0 and < %d", commandId, CFG_COMMAND_TOTAL);
THROW_FMT(AssertError, "command id %u invalid - must be >= 0 and < %d", commandId, CFG_COMMAND_TOTAL);
}
/***********************************************************************************************************************************
@ -222,7 +222,7 @@ cfgCommandId(const char *commandName)
break;
if (commandId == cfgCmdNone)
THROW(AssertError, "invalid command '%s'", commandName);
THROW_FMT(AssertError, "invalid command '%s'", commandName);
return commandId;
}
@ -341,7 +341,7 @@ void
cfgOptionCheck(ConfigOption optionId)
{
if (optionId >= CFG_OPTION_TOTAL)
THROW(AssertError, "option id %d invalid - must be >= 0 and < %d", optionId, CFG_OPTION_TOTAL);
THROW_FMT(AssertError, "option id %u invalid - must be >= 0 and < %d", optionId, CFG_OPTION_TOTAL);
}
/***********************************************************************************************************************************
@ -400,7 +400,7 @@ cfgOptionDefault(ConfigOption optionId)
break;
default:
THROW( // {uncoverable - others types do not have defaults yet}
THROW_FMT( // {uncoverable - others types do not have defaults yet}
AssertError, "type for option '%s' does not support defaults", cfgOptionName(optionId));
}
}
@ -548,7 +548,7 @@ cfgOptionBool(ConfigOption optionId)
cfgOptionCheck(optionId);
if (varType(configOptionValue[optionId].value) != varTypeBool)
THROW(AssertError, "option '%s' is not type 'bool'", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' is not type 'bool'", cfgOptionName(optionId));
return varBool(configOptionValue[optionId].value);
}
@ -559,7 +559,7 @@ cfgOptionDbl(ConfigOption optionId)
cfgOptionCheck(optionId);
if (varType(configOptionValue[optionId].value) != varTypeDouble)
THROW(AssertError, "option '%s' is not type 'double'", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' is not type 'double'", cfgOptionName(optionId));
return varDbl(configOptionValue[optionId].value);
}
@ -570,7 +570,7 @@ cfgOptionInt(ConfigOption optionId)
cfgOptionCheck(optionId);
if (varType(configOptionValue[optionId].value) != varTypeInt64)
THROW(AssertError, "option '%s' is not type 'int64'", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' is not type 'int64'", cfgOptionName(optionId));
return varIntForce(configOptionValue[optionId].value);
}
@ -581,7 +581,7 @@ cfgOptionInt64(ConfigOption optionId)
cfgOptionCheck(optionId);
if (varType(configOptionValue[optionId].value) != varTypeInt64)
THROW(AssertError, "option '%s' is not type 'int64'", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' is not type 'int64'", cfgOptionName(optionId));
return varInt64(configOptionValue[optionId].value);
}
@ -592,7 +592,7 @@ cfgOptionKv(ConfigOption optionId)
cfgOptionCheck(optionId);
if (varType(configOptionValue[optionId].value) != varTypeKeyValue)
THROW(AssertError, "option '%s' is not type 'KeyValue'", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' is not type 'KeyValue'", cfgOptionName(optionId));
return varKv(configOptionValue[optionId].value);
}
@ -611,7 +611,7 @@ cfgOptionLst(ConfigOption optionId)
MEM_CONTEXT_END();
}
else if (varType(configOptionValue[optionId].value) != varTypeVariantList)
THROW(AssertError, "option '%s' is not type 'VariantList'", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' is not type 'VariantList'", cfgOptionName(optionId));
return varVarLst(configOptionValue[optionId].value);
}
@ -626,7 +626,7 @@ cfgOptionStr(ConfigOption optionId)
if (configOptionValue[optionId].value != NULL)
{
if (varType(configOptionValue[optionId].value) != varTypeString)
THROW(AssertError, "option '%s' is not type 'String'", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' is not type 'String'", cfgOptionName(optionId));
result = varStr(configOptionValue[optionId].value);
}
@ -688,7 +688,7 @@ cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value)
if (varType(value) == varTypeKeyValue)
configOptionValue[optionId].value = varDup(value);
else
THROW(AssertError, "option '%s' must be set with KeyValue variant", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' must be set with KeyValue variant", cfgOptionName(optionId));
break;
}
@ -698,7 +698,7 @@ cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value)
if (varType(value) == varTypeVariantList)
configOptionValue[optionId].value = varDup(value);
else
THROW(AssertError, "option '%s' must be set with VariantList variant", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' must be set with VariantList variant", cfgOptionName(optionId));
break;
}
@ -707,7 +707,7 @@ cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value)
if (varType(value) == varTypeString)
configOptionValue[optionId].value = varDup(value);
else
THROW(AssertError, "option '%s' must be set with String variant", cfgOptionName(optionId));
THROW_FMT(AssertError, "option '%s' must be set with String variant", cfgOptionName(optionId));
break;
}

View File

@ -259,14 +259,14 @@ void
cfgDefCommandCheck(ConfigDefineCommand commandDefId)
{
if (commandDefId >= cfgDefCommandTotal())
THROW(AssertError, "command def id %d invalid - must be >= 0 and < %d", commandDefId, cfgDefCommandTotal());
THROW_FMT(AssertError, "command def id %u invalid - must be >= 0 and < %u", commandDefId, cfgDefCommandTotal());
}
void
cfgDefOptionCheck(ConfigDefineOption optionDefId)
{
if (optionDefId >= cfgDefOptionTotal())
THROW(AssertError, "option def id %d invalid - must be >= 0 and < %d", optionDefId, cfgDefOptionTotal());
THROW_FMT(AssertError, "option def id %u invalid - must be >= 0 and < %u", optionDefId, cfgDefOptionTotal());
}
static void
@ -317,7 +317,7 @@ cfgDefOptionAllowListValue(ConfigDefineCommand commandDefId, ConfigDefineOption
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeAllowList);
if (valueId < 0 || valueId >= dataDefListSize)
THROW(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
THROW_FMT(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
}
@ -426,7 +426,7 @@ cfgDefOptionDependValue(ConfigDefineCommand commandDefId, ConfigDefineOption opt
CONFIG_DEFINE_DATA_FIND(commandDefId, optionDefId, configDefDataTypeDepend);
if (valueId < 0 || valueId >= dataDefListSize)
THROW(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
THROW_FMT(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
}
@ -492,7 +492,7 @@ cfgDefOptionHelpNameAltValue(ConfigDefineOption optionDefId, int valueId)
CONFIG_DEFINE_DATA_FIND(-1, optionDefId, configDefDataTypeHelpNameAlt);
if (valueId < 0 || valueId >= dataDefListSize)
THROW(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
THROW_FMT(AssertError, "value id %d invalid - must be >= 0 and < %d", valueId, dataDefListSize);
return (char *)dataDefList[valueId];
}

View File

@ -77,7 +77,7 @@ cfgLoadUpdateOption()
cfgOptionSet(cfgOptProtocolTimeout, cfgSourceDefault, varNewDbl(cfgOptionDbl(cfgOptDbTimeout) + 30));
else
{
THROW(OptionInvalidValueError,
THROW_FMT(OptionInvalidValueError,
"'%f' is not valid for '%s' option\nHINT '%s' option (%f) should be greater than '%s' option (%f).",
cfgOptionDbl(cfgOptProtocolTimeout), cfgOptionName(cfgOptProtocolTimeout),
cfgOptionName(cfgOptProtocolTimeout), cfgOptionDbl(cfgOptProtocolTimeout), cfgOptionName(cfgOptDbTimeout),
@ -105,7 +105,7 @@ cfgLoadUpdateOption()
for (unsigned int optionIdx = 0; optionIdx < cfgOptionIndexTotal(cfgOptRepoHost); optionIdx++)
{
if (cfgOptionTest(cfgOptRepoHost + optionIdx))
THROW(ConfigError, "pg and repo hosts cannot both be configured as remote");
THROW_FMT(ConfigError, "pg and repo hosts cannot both be configured as remote");
}
}
}

View File

@ -142,7 +142,7 @@ convertToByte(String **value, double *valueDbl)
break;
default:
THROW( // {uncoverable - regex covers all cases but default required}
THROW_FMT( // {uncoverable - regex covers all cases but default required}
AssertError, "character %c is not a valid type", strArray[chrPos]);
}
}
@ -160,7 +160,7 @@ convertToByte(String **value, double *valueDbl)
*value = result;
}
else
THROW(FormatError, "value '%s' is not valid", strPtr(*value));
THROW_FMT(FormatError, "value '%s' is not valid", strPtr(*value));
}
/***********************************************************************************************************************************
@ -383,7 +383,7 @@ configParse(unsigned int argListSize, const char *argList[])
// don't have any control over what the user passes), so modify the error code and message.
CATCH(AssertError)
{
THROW(CommandInvalidError, "invalid command '%s'", argList[optind - 1]);
THROW_FMT(CommandInvalidError, "invalid command '%s'", argList[optind - 1]);
}
TRY_END();
@ -407,14 +407,14 @@ configParse(unsigned int argListSize, const char *argList[])
// If the option is unknown then error
case '?':
{
THROW(OptionInvalidError, "invalid option '%s'", argList[optind - 1]);
THROW_FMT(OptionInvalidError, "invalid option '%s'", argList[optind - 1]);
break;
}
// If the option is missing an argument then error
case ':':
{
THROW(OptionInvalidError, "option '%s' requires argument", argList[optind - 1]);
THROW_FMT(OptionInvalidError, "option '%s' requires argument", argList[optind - 1]);
break;
}
@ -446,23 +446,23 @@ configParse(unsigned int argListSize, const char *argList[])
// Make sure option is not negated more than once. It probably wouldn't hurt anything to accept this case
// but there's no point in allowing the user to be sloppy.
if (parseOptionList[optionId].negate && negate)
THROW(OptionInvalidError, "option '%s' is negated multiple times", cfgOptionName(optionId));
THROW_FMT(OptionInvalidError, "option '%s' is negated multiple times", cfgOptionName(optionId));
// Make sure option is not reset more than once. Same justification as negate.
if (parseOptionList[optionId].reset && reset)
THROW(OptionInvalidError, "option '%s' is reset multiple times", cfgOptionName(optionId));
THROW_FMT(OptionInvalidError, "option '%s' is reset multiple times", cfgOptionName(optionId));
// Don't allow an option to be both negated and reset
if ((parseOptionList[optionId].reset && negate) || (parseOptionList[optionId].negate && reset))
THROW(OptionInvalidError, "option '%s' cannot be negated and reset", cfgOptionName(optionId));
THROW_FMT(OptionInvalidError, "option '%s' cannot be negated and reset", cfgOptionName(optionId));
// Don't allow an option to be both set and negated
if (parseOptionList[optionId].negate != negate)
THROW(OptionInvalidError, "option '%s' cannot be set and negated", cfgOptionName(optionId));
THROW_FMT(OptionInvalidError, "option '%s' cannot be set and negated", cfgOptionName(optionId));
// Don't allow an option to be both set and reset
if (parseOptionList[optionId].reset != reset)
THROW(OptionInvalidError, "option '%s' cannot be set and reset", cfgOptionName(optionId));
THROW_FMT(OptionInvalidError, "option '%s' cannot be set and reset", cfgOptionName(optionId));
// Add the argument
strLstAdd(parseOptionList[optionId].valueList, strNew(optarg));
@ -481,7 +481,7 @@ configParse(unsigned int argListSize, const char *argList[])
{
// If there are args then error
if (argFound)
THROW(CommandRequiredError, "no command found");
THROW_FMT(CommandRequiredError, "no command found");
// Otherwise set the comand to help
cfgCommandHelpSet(true);
@ -582,7 +582,7 @@ configParse(unsigned int argListSize, const char *argList[])
if (optionFoundName != NULL)
{
THROW(
THROW_FMT(
OptionInvalidError, "configuration file contains duplicate options ('%s', '%s') in section '[%s]'",
strPtr(key), strPtr(varStr(optionFoundName)), strPtr(section));
}
@ -622,8 +622,10 @@ configParse(unsigned int argListSize, const char *argList[])
const Variant *value = iniGetDefault(config, section, key, NULL);
if (varType(value) == varTypeString && strSize(varStr(value)) == 0)
THROW(OptionInvalidValueError, "section '%s', key '%s' must have a value", strPtr(section),
strPtr(key));
{
THROW_FMT(
OptionInvalidValueError, "section '%s', key '%s' must have a value", strPtr(section), strPtr(key));
}
parseOptionList[optionId].found = true;
parseOptionList[optionId].source = cfgSourceConfig;
@ -634,7 +636,7 @@ configParse(unsigned int argListSize, const char *argList[])
if (strcasecmp(strPtr(varStr(value)), "n") == 0)
parseOptionList[optionId].negate = true;
else if (strcasecmp(strPtr(varStr(value)), "y") != 0)
THROW(OptionInvalidError, "boolean option '%s' must be 'y' or 'n'", strPtr(key));
THROW_FMT(OptionInvalidError, "boolean option '%s' must be 'y' or 'n'", strPtr(key));
}
// Else add the string value
else if (varType(value) == varTypeString)
@ -677,7 +679,7 @@ configParse(unsigned int argListSize, const char *argList[])
// Error if the option is not valid for this command
if (parseOption->found && !cfgDefOptionValid(commandDefId, optionDefId))
{
THROW(
THROW_FMT(
OptionInvalidError, "option '%s' not valid for command '%s'", cfgOptionName(optionId),
cfgCommandName(cfgCommand()));
}
@ -685,7 +687,7 @@ configParse(unsigned int argListSize, const char *argList[])
// Error if this option is secure and cannot be passed on the command line
if (parseOption->found && parseOption->source == cfgSourceParam && cfgDefOptionSecure(optionDefId))
{
THROW(
THROW_FMT(
OptionInvalidError,
"option '%s' is not allowed on the command-line\n"
"HINT: this option could expose secrets in the process list.\n"
@ -698,7 +700,7 @@ configParse(unsigned int argListSize, const char *argList[])
!(cfgDefOptionType(cfgOptionDefIdFromId(optionId)) == cfgDefOptTypeHash ||
cfgDefOptionType(cfgOptionDefIdFromId(optionId)) == cfgDefOptTypeList))
{
THROW(OptionInvalidError, "option '%s' cannot have multiple arguments", cfgOptionName(optionId));
THROW_FMT(OptionInvalidError, "option '%s' cannot have multiple arguments", cfgOptionName(optionId));
}
// Is the option valid for this command? If not, mark it as resolved since there is nothing more to do.
@ -760,7 +762,7 @@ configParse(unsigned int argListSize, const char *argList[])
// if (optionSet)
if (optionSet && parseOption->source == cfgSourceParam)
{
THROW(
THROW_FMT(
OptionInvalidError, "option '%s' not valid without option '%s'", cfgOptionName(optionId),
cfgOptionName(dependOptionId));
}
@ -819,17 +821,20 @@ configParse(unsigned int argListSize, const char *argList[])
}
// Build the error string
String *error = strNew("option '%s' not valid without option '%s'");
String *errorValue = strNew("");
if (strLstSize(dependValueList) == 1)
strCat(error, " = %s");
errorValue = strNewFmt(" = %s", strPtr(strLstGet(dependValueList, 0)));
else if (strLstSize(dependValueList) > 1)
strCat(error, " in (%s)");
errorValue = strNewFmt(" in (%s)", strPtr(strLstJoin(dependValueList, ", ")));
// Throw the error
THROW(
OptionInvalidError, strPtr(error), cfgOptionName(optionId), strPtr(dependOptionName),
strPtr(strLstJoin(dependValueList, ", ")));
OptionInvalidError,
strPtr(
strNewFmt(
"option '%s' not valid without option '%s'%s", cfgOptionName(optionId),
strPtr(dependOptionName), strPtr(errorValue))));
}
}
}
@ -853,7 +858,7 @@ configParse(unsigned int argListSize, const char *argList[])
if (equal == NULL)
{
THROW(
THROW_FMT(
OptionInvalidError, "key/value '%s' not valid for '%s' option",
strPtr(strLstGet(parseOption->valueList, listIdx)), cfgOptionName(optionId));
}
@ -897,7 +902,7 @@ configParse(unsigned int argListSize, const char *argList[])
}
CATCH_ANY()
{
THROW(
THROW_FMT(
OptionInvalidValueError, "'%s' is not valid for '%s' option", strPtr(value),
cfgOptionName(optionId));
}
@ -908,7 +913,7 @@ configParse(unsigned int argListSize, const char *argList[])
(valueDbl < cfgDefOptionAllowRangeMin(commandDefId, optionDefId) ||
valueDbl > cfgDefOptionAllowRangeMax(commandDefId, optionDefId)))
{
THROW(
THROW_FMT(
OptionInvalidValueError, "'%s' is out of range for '%s' option", strPtr(value),
cfgOptionName(optionId));
}
@ -918,7 +923,7 @@ configParse(unsigned int argListSize, const char *argList[])
if (cfgDefOptionAllowList(commandDefId, optionDefId) &&
!cfgDefOptionAllowListValueValid(commandDefId, optionDefId, strPtr(value)))
{
THROW(
THROW_FMT(
OptionInvalidValueError, "'%s' is not allowed for '%s' option", strPtr(value),
cfgOptionName(optionId));
}
@ -944,7 +949,7 @@ configParse(unsigned int argListSize, const char *argList[])
if (cfgDefOptionSection(optionDefId) == cfgDefSectionStanza)
hint = "\nHINT: does this stanza exist?";
THROW(
THROW_FMT(
OptionRequiredError, "%s command requires option: %s%s", cfgCommandName(cfgCommand()),
cfgOptionName(optionId), hint);
}

View File

@ -37,7 +37,7 @@ pgVersionMap(uint32_t controlVersion, uint32_t catalogVersion)
result = PG_VERSION_83;
else
{
THROW(
THROW_FMT(
VersionNotSupportedError,
"unexpected control version = %u and catalog version = %u\n"
"HINT: is this version of PostgreSQL supported?",

View File

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

View File

@ -34,7 +34,7 @@ storageDriverPosixExists(const String *path)
if (stat(strPtr(path), &statFile) == -1)
{
if (errno != ENOENT)
THROW_SYS_ERROR(FileOpenError, "unable to stat '%s'", strPtr(path));
THROW_SYS_ERROR_FMT(FileOpenError, "unable to stat '%s'", strPtr(path));
}
// Else found
else
@ -57,7 +57,7 @@ storageDriverPosixInfo(const String *file, bool ignoreMissing)
if (lstat(strPtr(file), &statFile) == -1)
{
if (errno != ENOENT || !ignoreMissing)
THROW_SYS_ERROR(FileOpenError, "unable to get info for '%s'", strPtr(file));
THROW_SYS_ERROR_FMT(FileOpenError, "unable to get info for '%s'", strPtr(file));
}
// On success load info into a structure
else
@ -74,7 +74,7 @@ storageDriverPosixInfo(const String *file, bool ignoreMissing)
else if (S_ISLNK(statFile.st_mode))
result.type = storageTypeLink;
else
THROW(FileInfoError, "invalid type for '%s'", strPtr(file));
THROW_FMT(FileInfoError, "invalid type for '%s'", strPtr(file));
result.mode = statFile.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}
@ -100,7 +100,7 @@ storageDriverPosixList(const String *path, bool errorOnMissing, const String *ex
if (!dir)
{
if (errorOnMissing || errno != ENOENT)
THROW_SYS_ERROR(PathOpenError, "unable to open path '%s' for read", strPtr(path));
THROW_SYS_ERROR_FMT(PathOpenError, "unable to open path '%s' for read", strPtr(path));
}
else
{
@ -165,11 +165,11 @@ storageDriverPosixMove(StorageFileReadPosix *source, StorageFileWritePosix *dest
if (errno == ENOENT)
{
if (!storageDriverPosixExists(sourceFile))
THROW_SYS_ERROR(FileMissingError, "unable to move missing file '%s'", strPtr(sourceFile));
THROW_SYS_ERROR_FMT(FileMissingError, "unable to move missing file '%s'", strPtr(sourceFile));
if (!storageFileWritePosixCreatePath(destination))
{
THROW_SYS_ERROR(
THROW_SYS_ERROR_FMT(
PathMissingError, "unable to move '%s' to missing path '%s'", strPtr(sourceFile), strPtr(destinationPath));
}
@ -182,7 +182,7 @@ storageDriverPosixMove(StorageFileReadPosix *source, StorageFileWritePosix *dest
result = false;
}
else
THROW_SYS_ERROR(FileMoveError, "unable to move '%s' to '%s'", strPtr(sourceFile), strPtr(destinationFile));
THROW_SYS_ERROR_FMT(FileMoveError, "unable to move '%s' to '%s'", strPtr(sourceFile), strPtr(destinationFile));
}
// Sync paths on success
else
@ -219,7 +219,7 @@ storageDriverPosixPathCreate(const String *path, bool errorOnExists, bool noPare
}
// Ignore path exists if allowed
else if (errno != EEXIST || errorOnExists)
THROW_SYS_ERROR(PathCreateError, "unable to create path '%s'", strPtr(path));
THROW_SYS_ERROR_FMT(PathCreateError, "unable to create path '%s'", strPtr(path));
}
}
@ -253,7 +253,7 @@ storageDriverPosixPathRemove(const String *path, bool errorOnMissing, bool recur
storageDriverPosixPathRemove(file, false, true);
// Else error
else
THROW_SYS_ERROR(PathRemoveError, "unable to remove path/file '%s'", strPtr(file));
THROW_SYS_ERROR_FMT(PathRemoveError, "unable to remove path/file '%s'", strPtr(file));
}
}
}
@ -263,7 +263,7 @@ storageDriverPosixPathRemove(const String *path, bool errorOnMissing, bool recur
if (rmdir(strPtr(path)) == -1)
{
if (errorOnMissing || errno != ENOENT)
THROW_SYS_ERROR(PathRemoveError, "unable to remove path '%s'", strPtr(path));
THROW_SYS_ERROR_FMT(PathRemoveError, "unable to remove path '%s'", strPtr(path));
}
}
MEM_CONTEXT_TEMP_END();
@ -299,6 +299,6 @@ storageDriverPosixRemove(const String *file, bool errorOnMissing)
if (unlink(strPtr(file)) == -1)
{
if (errorOnMissing || errno != ENOENT)
THROW_SYS_ERROR(FileRemoveError, "unable to remove '%s'", strPtr(file));
THROW_SYS_ERROR_FMT(FileRemoveError, "unable to remove '%s'", strPtr(file));
}
}

View File

@ -28,7 +28,7 @@ storageFilePosixOpen(
if (result == -1)
{
if (errno != ENOENT || !ignoreMissing)
THROWP_SYS_ERROR(errorType, "unable to open '%s' for %s", strPtr(name), purpose);
THROWP_SYS_ERROR_FMT(errorType, "unable to open '%s' for %s", strPtr(name), purpose);
}
return result;
@ -48,7 +48,7 @@ storageFilePosixSync(int handle, const String *name, const ErrorType *errorType,
if (closeOnError)
close(handle);
THROWP_SYS_ERROR_CODE(errNo, errorType, "unable to sync '%s'", strPtr(name));
THROWP_SYS_ERROR_CODE_FMT(errNo, errorType, "unable to sync '%s'", strPtr(name));
}
}
@ -59,5 +59,5 @@ void
storageFilePosixClose(int handle, const String *name, const ErrorType *errorType)
{
if (close(handle) == -1)
THROWP_SYS_ERROR(errorType, "unable to close '%s'", strPtr(name));
THROWP_SYS_ERROR_FMT(errorType, "unable to close '%s'", strPtr(name));
}

View File

@ -96,7 +96,7 @@ storageFileReadPosix(StorageFileReadPosix *this)
// Error occurred during write
if (actualBytes == -1)
THROW_SYS_ERROR(FileReadError, "unable to read '%s'", strPtr(this->name));
THROW_SYS_ERROR_FMT(FileReadError, "unable to read '%s'", strPtr(this->name));
// If no data was read then free the buffer and mark the file as EOF
if (actualBytes == 0)

View File

@ -114,7 +114,7 @@ storageFileWritePosix(StorageFileWritePosix *this, const Buffer *buffer)
// Write the data
if (write(this->handle, bufPtr(buffer), bufSize(buffer)) != (ssize_t)bufSize(buffer))
THROW_SYS_ERROR(FileWriteError, "unable to write '%s'", strPtr(this->name));
THROW_SYS_ERROR_FMT(FileWriteError, "unable to write '%s'", strPtr(this->name));
}
/***********************************************************************************************************************************
@ -139,7 +139,7 @@ storageFileWritePosixClose(StorageFileWritePosix *this)
if (!this->noAtomic)
{
if (rename(strPtr(this->nameTmp), strPtr(this->name)) == -1)
THROW_SYS_ERROR(FileMoveError, "unable to move '%s' to '%s'", strPtr(this->nameTmp), strPtr(this->name));
THROW_SYS_ERROR_FMT(FileMoveError, "unable to move '%s' to '%s'", strPtr(this->nameTmp), strPtr(this->name));
}
// Sync the path

View File

@ -105,7 +105,7 @@ storageSpoolPathExpression(const String *expression, const String *path)
result = strNewFmt("archive/%s/out/%s", strPtr(storageSpoolStanza), strPtr(path));
}
else
THROW(AssertError, "invalid expression '%s'", strPtr(expression));
THROW_FMT(AssertError, "invalid expression '%s'", strPtr(expression));
return result;
}

View File

@ -310,7 +310,7 @@ storagePath(const Storage *this, const String *pathExp)
if (!strBeginsWith(pathExp, this->path) ||
!(strSize(pathExp) == strSize(this->path) || *(strPtr(pathExp) + strSize(this->path)) == '/'))
{
THROW(AssertError, "absolute path '%s' is not in base path '%s'", strPtr(pathExp), strPtr(this->path));
THROW_FMT(AssertError, "absolute path '%s' is not in base path '%s'", strPtr(pathExp), strPtr(this->path));
}
}
@ -326,14 +326,14 @@ storagePath(const Storage *this, const String *pathExp)
if ((strPtr(pathExp))[0] == '<')
{
if (this->pathExpressionFunction == NULL)
THROW(AssertError, "expression '%s' not valid without callback function", strPtr(pathExp));
THROW_FMT(AssertError, "expression '%s' not valid without callback function", strPtr(pathExp));
// Get position of the expression end
char *end = strchr(strPtr(pathExp), '>');
// Error if end is not found
if (end == NULL)
THROW(AssertError, "end > not found in path expression '%s'", strPtr(pathExp));
THROW_FMT(AssertError, "end > not found in path expression '%s'", strPtr(pathExp));
// Create a string from the expression
String *expression = strNewN(strPtr(pathExp), (size_t)(end - strPtr(pathExp) + 1));
@ -345,11 +345,11 @@ storagePath(const Storage *this, const String *pathExp)
{
// Error if path separator is not found
if (end[1] != '/')
THROW(AssertError, "'/' should separate expression and path '%s'", strPtr(pathExp));
THROW_FMT(AssertError, "'/' should separate expression and path '%s'", strPtr(pathExp));
// Only create path if there is something after the path separator
if (end[2] == 0)
THROW(AssertError, "path '%s' should not end in '/'", strPtr(pathExp));
THROW_FMT(AssertError, "path '%s' should not end in '/'", strPtr(pathExp));
path = strNew(end + 2);
}
@ -359,7 +359,7 @@ storagePath(const Storage *this, const String *pathExp)
// Evaluated path cannot be NULL
if (pathEvaluated == NULL)
THROW(AssertError, "evaluated path '%s' cannot be null", strPtr(pathExp));
THROW_FMT(AssertError, "evaluated path '%s' cannot be null", strPtr(pathExp));
// Assign evaluated path to path
pathExp = pathEvaluated;

View File

@ -53,7 +53,7 @@ sub run
$self->testResult(sub {decodeToBin(ENCODE_TYPE_BASE64, $tEncodedData)}, $tData, 'decode binary');
#---------------------------------------------------------------------------------------------------------------------------
$self->testException(sub {encodeToStr(-1, '')}, ERROR_ASSERT, 'invalid encode type -1');
$self->testException(sub {encodeToStr(99999, '')}, ERROR_ASSERT, 'invalid encode type 99999');
$self->testException(
sub {decodeToBin(ENCODE_TYPE_BASE64, "XX")}, ERROR_FORMAT, 'base64 size 2 is not evenly divisible by 4');
}

View File

@ -52,14 +52,14 @@ Test that an expected error is actually thrown and error when it isn't
TEST_ERROR_catch = true; \
\
if (strcmp(errorMessage(), errorMessageExpected) != 0 || errorType() != &errorTypeExpected) \
THROW( \
THROW_FMT( \
AssertError, "expected error %s, '%s' but got %s, '%s'", errorTypeName(&errorTypeExpected), errorMessageExpected, \
errorName(), errorMessage()); \
} \
TRY_END(); \
\
if (!TEST_ERROR_catch) \
THROW( \
THROW_FMT( \
AssertError, "statement '%s' returned but error %s, '%s' was expected", #statement, errorTypeName(&errorTypeExpected), \
errorMessageExpected); \
}
@ -72,7 +72,7 @@ Test error with a formatted expected message
char TEST_ERROR_FMT_buffer[8192]; \
\
if (snprintf(TEST_ERROR_FMT_buffer, sizeof(TEST_ERROR_FMT_buffer), __VA_ARGS__) >= (int)sizeof(TEST_ERROR_FMT_buffer)) \
THROW(AssertError, "error message needs more than the %d characters available", sizeof(TEST_ERROR_FMT_buffer)); \
THROW_FMT(AssertError, "error message needs more than the %zu characters available", sizeof(TEST_ERROR_FMT_buffer)); \
\
TEST_ERROR(statement, errorTypeExpected, TEST_ERROR_FMT_buffer); \
}
@ -87,8 +87,8 @@ Format the test type into the given buffer -- or return verbatim if char *
#define TEST_TYPE_FORMAT_SPRINTF(format, value) \
if (snprintf((char *)value##Str, TEST_RESULT_FORMAT_SIZE + 1, format, value) > TEST_RESULT_FORMAT_SIZE) \
{ \
THROW( \
AssertError, "formatted type '" format "' needs more than the %d characters available", TEST_RESULT_FORMAT_SIZE); \
THROW_FMT( \
AssertError, "formatted type '%" format "' needs more than the %d characters available", TEST_RESULT_FORMAT_SIZE); \
}
#define TEST_TYPE_FORMAT(type, format, value) \
@ -152,7 +152,7 @@ parameters.
CATCH_ANY() \
{ \
/* No errors were expected so error */ \
THROW( \
THROW_FMT( \
AssertError, "statement '%s' threw error %s, '%s' but result <%s> expected", \
#statement, errorName(), errorMessage(), TEST_RESULT_resultExpectedStr); \
} \
@ -169,7 +169,7 @@ parameters.
formatMacro(type, format, TEST_RESULT_result); \
\
/* Throw error */ \
THROW( \
THROW_FMT( \
AssertError, "\n\nSTATEMENT: %s\n\nRESULT IS:\n%s\n\nBUT EXPECTED:\n%s\n\n", \
#statement, TEST_RESULT_resultStr, TEST_RESULT_resultExpectedStr); \
} \
@ -191,7 +191,7 @@ Test that a void statement returns and does not throw an error
CATCH_ANY() \
{ \
/* No errors were expected so error */ \
THROW(AssertError, "statement '%s' threw error %s, '%s' but void expected", #statement, errorName(), errorMessage()); \
THROW_FMT(AssertError, "statement '%s' threw error %s, '%s' but void expected", #statement, errorName(), errorMessage()); \
} \
TRY_END(); \
}
@ -212,7 +212,7 @@ Test that a statement does not error and assign it to the specified variable if
CATCH_ANY() \
{ \
/* No errors were expected so error */ \
THROW(AssertError, "statement '%s' threw error %s, '%s' but result expected", #statement, errorName(), errorMessage()); \
THROW_FMT(AssertError, "statement '%s' threw error %s, '%s' but result expected", #statement, errorName(), errorMessage());\
} \
TRY_END(); \
}
@ -259,6 +259,6 @@ Macros to ease the use of common data types
TEST_RESULT_STR_PARAM(statement, resultExpected, !=, __VA_ARGS__);
#define TEST_RESULT_U16_HEX(statement, resultExpected, ...) \
TEST_RESULT(statement, resultExpected, uint16_t, "0x%04X", TEST_TYPE_FORMAT, ==, TEST_TYPE_COMPARE, __VA_ARGS__);
TEST_RESULT(statement, resultExpected, uint16_t, "%04X", TEST_TYPE_FORMAT, ==, TEST_TYPE_COMPARE, __VA_ARGS__);
#endif

View File

@ -53,7 +53,7 @@ testLogResult(const char *expected)
String *actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stdoutFile))));
if (!strEqZ(actual, expected))
THROW(AssertError, "\n\nexpected log:\n\n%s\n\nbut actual log was:\n\n%s\n\n", expected, strPtr(actual));
THROW_FMT(AssertError, "\n\nexpected log:\n\n%s\n\nbut actual log was:\n\n%s\n\n", expected, strPtr(actual));
close(logHandleStdOut);
logHandleStdOut = open(strPtr(stdoutFile), O_WRONLY | O_CREAT | O_TRUNC, 0640);
@ -70,7 +70,7 @@ testLogErrResult(const char *expected)
String *actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stderrFile))));
if (!strEqZ(actual, expected))
THROW(AssertError, "\n\nexpected error log:\n\n%s\n\nbut actual error log was:\n\n%s\n\n", expected, strPtr(actual));
THROW_FMT(AssertError, "\n\nexpected error log:\n\n%s\n\nbut actual error log was:\n\n%s\n\n", expected, strPtr(actual));
close(logHandleStdErr);
logHandleStdErr = open(strPtr(stderrFile), O_WRONLY | O_CREAT | O_TRUNC, 0640);
@ -85,12 +85,12 @@ testLogFinal()
String *actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stdoutFile))));
if (!strEqZ(actual, ""))
THROW(AssertError, "\n\nexpected log to be empty but actual log was:\n\n%s\n\n", strPtr(actual));
THROW_FMT(AssertError, "\n\nexpected log to be empty but actual log was:\n\n%s\n\n", strPtr(actual));
actual = strTrim(strNewBuf(storageGetNP(storageNewReadNP(storageLocal(), stderrFile))));
if (!strEqZ(actual, ""))
THROW(AssertError, "\n\nexpected error log to be empty but actual error log was:\n\n%s\n\n", strPtr(actual));
THROW_FMT(AssertError, "\n\nexpected error log to be empty but actual error log was:\n\n%s\n\n", strPtr(actual));
}
#endif

View File

@ -136,7 +136,7 @@ testRun()
THROW_SYS_ERROR(AssertError, "unable to find child process"); // {uncoverable+}
if (WEXITSTATUS(processStatus) != 0)
THROW(AssertError, "perl exited with error %d", WEXITSTATUS(processStatus));
THROW_FMT(AssertError, "perl exited with error %d", WEXITSTATUS(processStatus));
}
// -------------------------------------------------------------------------------------------------------------------------
@ -162,7 +162,7 @@ testRun()
THROW_SYS_ERROR(AssertError, "unable to find child process"); // {uncoverable+}
if (WEXITSTATUS(processStatus) != 0)
THROW(AssertError, "perl exited with error %d", WEXITSTATUS(processStatus));
THROW_FMT(AssertError, "perl exited with error %d", WEXITSTATUS(processStatus));
}
// Make sure the process times out when there is nothing to get

View File

@ -86,8 +86,8 @@ testRun()
TEST_RESULT_INT(destinationDecode[1], 0xFF, "check for overrun");
TEST_RESULT_INT(decodeToBinSize(encodeBase64, decode), 1, "check size");
TEST_ERROR(decodeToBin(-1, decode, destinationDecode), AssertError, "invalid encode type -1");
TEST_ERROR(decodeToBinSize(-1, decode), AssertError, "invalid encode type -1");
TEST_ERROR(decodeToBin(9999, decode, destinationDecode), AssertError, "invalid encode type 9999");
TEST_ERROR(decodeToBinSize(9999, decode), AssertError, "invalid encode type 9999");
TEST_ERROR(decodeToBin(encodeBase64, "cc$=", destinationDecode), FormatError, "base64 invalid character found at position 2");
// -------------------------------------------------------------------------------------------------------------------------
@ -103,6 +103,6 @@ testRun()
TEST_RESULT_BOOL(decodeToBinValid(encodeBase64, "CCCCCCCCCCC"), false, "base64 string not valid");
TEST_RESULT_BOOL(decodeToBinValid(encodeBase64, "CCCCCCCCCCCC"), true, "base64 string valid");
TEST_ERROR(decodeToBinValid(-999, "CCCCCCCCCCCC"), AssertError, "invalid encode type -999");
TEST_ERROR(decodeToBinValid(9999, "CCCCCCCCCCCC"), AssertError, "invalid encode type 9999");
}
}

View File

@ -178,7 +178,7 @@ testRun()
}
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("THROW_CODE()"))
if (testBegin("THROW_CODE() and THROW_CODE_FMT()"))
{
TRY_BEGIN()
{
@ -191,6 +191,18 @@ testRun()
}
TRY_END();
// -------------------------------------------------------------------------------------------------------------------------
TRY_BEGIN()
{
THROW_CODE_FMT(122, "message %d", 1);
}
CATCH_ANY()
{
assert(errorCode() == 122);
assert(strcmp(errorMessage(), "message 1") == 0);
}
TRY_END();
// -------------------------------------------------------------------------------------------------------------------------
TRY_BEGIN()
{
@ -205,7 +217,7 @@ testRun()
}
// -----------------------------------------------------------------------------------------------------------------------------
if (testBegin("THROW_SYS_ERROR()"))
if (testBegin("THROW_SYS_ERROR() and THROW_SYS_ERROR_FMT()"))
{
TRY_BEGIN()
{
@ -219,5 +231,19 @@ testRun()
assert(strcmp(errorMessage(), "message: [7] Argument list too long") == 0);
}
TRY_END();
// -------------------------------------------------------------------------------------------------------------------------
TRY_BEGIN()
{
errno = EIO;
THROW_SYS_ERROR_FMT(AssertError, "message %d", 1);
}
CATCH_ANY()
{
printf("%s\n", errorMessage());
assert(errorCode() == AssertError.code);
assert(strcmp(errorMessage(), "message 1: [5] Input/output error") == 0);
}
TRY_END();
}
}

View File

@ -38,7 +38,7 @@ testRun()
THROW_SYS_ERROR(AssertError, "unable to find child process"); // {uncoverable+}
if (WEXITSTATUS(processStatus) != 0)
THROW(AssertError, "perl exited with error %d", WEXITSTATUS(processStatus));
THROW_FMT(AssertError, "perl exited with error %d", WEXITSTATUS(processStatus));
}
}
}

View File

@ -25,21 +25,11 @@ testRun()
optionIdInvalidHighError, sizeof(optionIdInvalidHighError), "option id %d invalid - must be >= 0 and < %d",
CFG_OPTION_TOTAL, CFG_OPTION_TOTAL);
char optionIdInvalidLowError[256];
snprintf(
optionIdInvalidLowError, sizeof(optionIdInvalidLowError), "option id -1 invalid - must be >= 0 and < %d",
CFG_OPTION_TOTAL);
char commandIdInvalidHighError[256];
snprintf(
commandIdInvalidHighError, sizeof(commandIdInvalidHighError), "command id %d invalid - must be >= 0 and < %d",
CFG_COMMAND_TOTAL, CFG_COMMAND_TOTAL);
char commandIdInvalidLowError[256];
snprintf(
commandIdInvalidLowError, sizeof(commandIdInvalidLowError), "command id -1 invalid - must be >= 0 and < %d",
CFG_COMMAND_TOTAL);
// -------------------------------------------------------------------------------------------------------------------------
TEST_ERROR(cfgCommandId(BOGUS_STR), AssertError, "invalid command 'BOGUS'");
TEST_RESULT_INT(cfgCommandId("archive-push"), cfgCmdArchivePush, "command id from name");
@ -47,7 +37,6 @@ testRun()
TEST_ERROR(cfgCommandDefIdFromId(CFG_COMMAND_TOTAL), AssertError, commandIdInvalidHighError);
TEST_RESULT_INT(cfgCommandDefIdFromId(cfgCmdBackup), cfgDefCmdBackup, "command id to def id");
TEST_ERROR(cfgCommandName(-1), AssertError, commandIdInvalidLowError);
TEST_RESULT_STR(cfgCommandName(cfgCmdBackup), "backup", "command name from id");
TEST_RESULT_INT(cfgOptionDefIdFromId(cfgOptPgHost + 6), cfgDefOptPgHost, "option id to def id");
@ -65,7 +54,6 @@ testRun()
TEST_RESULT_INT(cfgOptionIndexTotal(cfgOptPgPath), 8, "option index total");
TEST_RESULT_INT(cfgOptionIndexTotal(cfgOptLogLevelConsole), 1, "option index total");
TEST_ERROR(cfgOptionName(-1), AssertError, optionIdInvalidLowError);
TEST_RESULT_STR(cfgOptionName(cfgOptBackupStandby), "backup-standby", "option id from name");
}

View File

@ -20,24 +20,13 @@ testRun()
optionIdInvalidHighError, sizeof(optionIdInvalidHighError), "option def id %u invalid - must be >= 0 and < %u",
cfgDefOptionTotal(), cfgDefOptionTotal());
char optionIdInvalidLowError[256];
snprintf(
optionIdInvalidLowError, sizeof(optionIdInvalidLowError), "option def id -1 invalid - must be >= 0 and < %u",
cfgDefOptionTotal());
char commandIdInvalidHighError[256];
snprintf(
commandIdInvalidHighError, sizeof(commandIdInvalidHighError), "command def id %u invalid - must be >= 0 and < %u",
cfgDefCommandTotal(), cfgDefCommandTotal());
char commandIdInvalidLowError[256];
snprintf(
commandIdInvalidLowError, sizeof(commandIdInvalidLowError), "command def id -1 invalid - must be >= 0 and < %u",
cfgDefCommandTotal());
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_STR(cfgDefOptionName(cfgDefOptConfig), "config", "option name");
TEST_ERROR(cfgDefOptionName(-1), AssertError, optionIdInvalidLowError);
TEST_RESULT_INT(cfgDefOptionId("repo-host"), cfgDefOptRepoHost, "define id");
TEST_RESULT_INT(cfgDefOptionId(BOGUS_STR), -1, "invalid define id");
@ -69,7 +58,7 @@ testRun()
TEST_RESULT_DOUBLE(
cfgDefOptionAllowRangeMax(cfgDefCmdArchivePush, cfgDefOptArchivePushQueueMax), 4503599627370496, "range max");
TEST_ERROR(cfgDefOptionDefault(-1, cfgDefOptCompressLevel), AssertError, commandIdInvalidLowError);
TEST_ERROR(cfgDefOptionDefault(cfgDefCommandTotal(), cfgDefOptCompressLevel), AssertError, commandIdInvalidHighError);
TEST_ERROR(cfgDefOptionDefault(cfgDefCmdBackup, cfgDefOptionTotal()), AssertError, optionIdInvalidHighError);
TEST_RESULT_STR(cfgDefOptionDefault(cfgDefCmdBackup, cfgDefOptCompressLevel), "6", "option default exists");
TEST_RESULT_STR(cfgDefOptionDefault(cfgDefCmdRestore, cfgDefOptType), "default", "command default exists");
@ -114,11 +103,9 @@ testRun()
TEST_RESULT_INT(cfgDefOptionSection(cfgDefOptPgPath), cfgDefSectionStanza, "stanza section");
TEST_RESULT_INT(cfgDefOptionSection(cfgDefOptType), cfgDefSectionCommandLine, "command line only");
TEST_ERROR(cfgDefOptionSecure(-1), AssertError, optionIdInvalidLowError);
TEST_RESULT_BOOL(cfgDefOptionSecure(cfgDefOptRepoS3Key), true, "option secure");
TEST_RESULT_BOOL(cfgDefOptionSecure(cfgDefOptRepoHost), false, "option not secure");
TEST_ERROR(cfgDefOptionType(-1), AssertError, optionIdInvalidLowError);
TEST_RESULT_INT(cfgDefOptionType(cfgDefOptType), cfgDefOptTypeString, "string type");
TEST_RESULT_INT(cfgDefOptionType(cfgDefOptCompress), cfgDefOptTypeBoolean, "boolean type");

View File

@ -16,7 +16,7 @@ storageTestPathExpression(const String *expression, const String *path)
if (strcmp(strPtr(expression), "<TEST>") == 0)
result = strNewFmt("test%s", path == NULL ? "" : strPtr(strNewFmt("/%s", strPtr(path))));
else if (strcmp(strPtr(expression), "<NULL>") != 0)
THROW(AssertError, "invalid expression '%s'", strPtr(expression));
THROW_FMT(AssertError, "invalid expression '%s'", strPtr(expression));
return result;
}