mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-05 15:05:48 +02:00
Add base variants to all integer to string conversion functions.
Previously these functions were fixed at base 10 conversion. Add variants that can convert from any base.
This commit is contained in:
parent
7de9584435
commit
bef31f1802
@ -66,6 +66,10 @@
|
||||
<p>Correct current history item in <code>InfoPg</code> to always be in position 0.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <id>base</id> variants to all integer to string conversion functions.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>lstInsert()</code> to <code>List</code> object.</p>
|
||||
</release-item>
|
||||
|
@ -20,7 +20,7 @@ Check results of strto*() function for:
|
||||
* error in errno
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
cvtZToIntValid(int errNo, const char *value, const char *endPtr, const char *type)
|
||||
cvtZToIntValid(int errNo, int base, const char *value, const char *endPtr, const char *type)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(INT, errNo);
|
||||
@ -33,7 +33,7 @@ cvtZToIntValid(int errNo, const char *value, const char *endPtr, const char *typ
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (errNo != 0 || *value == '\0' || isspace(*value) || *endPtr != '\0')
|
||||
THROW_FMT(FormatError, "unable to convert string '%s' to %s", value, type);
|
||||
THROW_FMT(FormatError, "unable to convert base %d string '%s' to %s", base, value, type);
|
||||
|
||||
FUNCTION_TEST_RESULT_VOID();
|
||||
}
|
||||
@ -42,7 +42,7 @@ cvtZToIntValid(int errNo, const char *value, const char *endPtr, const char *typ
|
||||
Convert zero-terminated string to int64 and validate result
|
||||
***********************************************************************************************************************************/
|
||||
static int64_t
|
||||
cvtZToInt64Internal(const char *value, const char *type)
|
||||
cvtZToInt64Internal(const char *value, const char *type, int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CHARP, value);
|
||||
@ -55,10 +55,10 @@ cvtZToInt64Internal(const char *value, const char *type)
|
||||
// Convert from string
|
||||
errno = 0;
|
||||
char *endPtr = NULL;
|
||||
int64_t result = strtoll(value, &endPtr, 10);
|
||||
int64_t result = strtoll(value, &endPtr, base);
|
||||
|
||||
// Validate the result
|
||||
cvtZToIntValid(errno, value, endPtr, type);
|
||||
cvtZToIntValid(errno, base, value, endPtr, type);
|
||||
|
||||
FUNCTION_TEST_RESULT(INT64, result);
|
||||
}
|
||||
@ -67,7 +67,7 @@ cvtZToInt64Internal(const char *value, const char *type)
|
||||
Convert zero-terminated string to uint64 and validate result
|
||||
***********************************************************************************************************************************/
|
||||
static uint64_t
|
||||
cvtZToUInt64Internal(const char *value, const char *type)
|
||||
cvtZToUInt64Internal(const char *value, const char *type, int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CHARP, value);
|
||||
@ -80,10 +80,10 @@ cvtZToUInt64Internal(const char *value, const char *type)
|
||||
// Convert from string
|
||||
errno = 0;
|
||||
char *endPtr = NULL;
|
||||
uint64_t result = strtoull(value, &endPtr, 10);
|
||||
uint64_t result = strtoull(value, &endPtr, base);
|
||||
|
||||
// Validate the result
|
||||
cvtZToIntValid(errno, value, endPtr, type);
|
||||
cvtZToIntValid(errno, base, value, endPtr, type);
|
||||
|
||||
FUNCTION_TEST_RESULT(UINT64, result);
|
||||
}
|
||||
@ -226,6 +226,23 @@ cvtIntToZ(int value, char *buffer, size_t bufferSize)
|
||||
FUNCTION_TEST_RESULT(SIZE, result);
|
||||
}
|
||||
|
||||
int
|
||||
cvtZToIntBase(const char *value, int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CHARP, value);
|
||||
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
int64_t result = cvtZToInt64Internal(value, "int", base);
|
||||
|
||||
if (result > INT_MAX || result < INT_MIN)
|
||||
THROW_FMT(FormatError, "unable to convert base %d string '%s' to int", base, value);
|
||||
|
||||
FUNCTION_TEST_RESULT(INT, (int)result);
|
||||
}
|
||||
|
||||
int
|
||||
cvtZToInt(const char *value)
|
||||
{
|
||||
@ -235,12 +252,7 @@ cvtZToInt(const char *value)
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
int64_t result = cvtZToInt64Internal(value, "int");
|
||||
|
||||
if (result > INT_MAX || result < INT_MIN)
|
||||
THROW_FMT(FormatError, "unable to convert string '%s' to int", value);
|
||||
|
||||
FUNCTION_TEST_RESULT(INT, (int)result);
|
||||
FUNCTION_TEST_RESULT(INT, cvtZToIntBase(value, 10));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -265,6 +277,18 @@ cvtInt64ToZ(int64_t value, char *buffer, size_t bufferSize)
|
||||
FUNCTION_TEST_RESULT(SIZE, result);
|
||||
}
|
||||
|
||||
int64_t
|
||||
cvtZToInt64Base(const char *value, int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CHARP, value);
|
||||
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_TEST_RESULT(INT64, cvtZToInt64Internal(value, "int64", base));
|
||||
}
|
||||
|
||||
int64_t
|
||||
cvtZToInt64(const char *value)
|
||||
{
|
||||
@ -274,7 +298,7 @@ cvtZToInt64(const char *value)
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_TEST_RESULT(INT64, cvtZToInt64Internal(value, "int64"));
|
||||
FUNCTION_TEST_RESULT(INT64, cvtZToInt64Base(value, 10));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -343,6 +367,24 @@ cvtUIntToZ(unsigned int value, char *buffer, size_t bufferSize)
|
||||
FUNCTION_TEST_RESULT(SIZE, result);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
cvtZToUIntBase(const char *value, int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CHARP, value);
|
||||
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
uint64_t result = cvtZToUInt64Internal(value, "unsigned int", base);
|
||||
|
||||
// Don't allow negative numbers even though strtoull() does and check max value
|
||||
if (*value == '-' || result > UINT_MAX)
|
||||
THROW_FMT(FormatError, "unable to convert base %d string '%s' to unsigned int", base, value);
|
||||
|
||||
FUNCTION_TEST_RESULT(UINT, (unsigned int)result);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
cvtZToUInt(const char *value)
|
||||
{
|
||||
@ -352,13 +394,7 @@ cvtZToUInt(const char *value)
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
uint64_t result = cvtZToUInt64Internal(value, "unsigned int");
|
||||
|
||||
// Don't allow negative numbers even though strtoull() does and check max value
|
||||
if (*value == '-' || result > UINT_MAX)
|
||||
THROW_FMT(FormatError, "unable to convert string '%s' to unsigned int", value);
|
||||
|
||||
FUNCTION_TEST_RESULT(UINT, (unsigned int)result);
|
||||
FUNCTION_TEST_RESULT(UINT, cvtZToUIntBase(value, 10));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -383,6 +419,24 @@ cvtUInt64ToZ(uint64_t value, char *buffer, size_t bufferSize)
|
||||
FUNCTION_TEST_RESULT(SIZE, result);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
cvtZToUInt64Base(const char *value, int base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(CHARP, value);
|
||||
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
uint64_t result = cvtZToUInt64Internal(value, "uint64", base);
|
||||
|
||||
// Don't allow negative numbers even though strtoull() does
|
||||
if (*value == '-')
|
||||
THROW_FMT(FormatError, "unable to convert base %d string '%s' to uint64", base, value);
|
||||
|
||||
FUNCTION_TEST_RESULT(UINT64, result);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
cvtZToUInt64(const char *value)
|
||||
{
|
||||
@ -392,11 +446,5 @@ cvtZToUInt64(const char *value)
|
||||
FUNCTION_TEST_ASSERT(value != NULL);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
uint64_t result = cvtZToUInt64Internal(value, "uint64");
|
||||
|
||||
// Don't allow negative numbers even though strtoull() does
|
||||
if (*value == '-')
|
||||
THROW_FMT(FormatError, "unable to convert string '%s' to uint64", value);
|
||||
|
||||
FUNCTION_TEST_RESULT(UINT64, result);
|
||||
FUNCTION_TEST_RESULT(UINT64, cvtZToUInt64Base(value, 10));
|
||||
}
|
||||
|
@ -17,9 +17,11 @@ double cvtZToDouble(const char *value);
|
||||
|
||||
size_t cvtIntToZ(int value, char *buffer, size_t bufferSize);
|
||||
int cvtZToInt(const char *value);
|
||||
int cvtZToIntBase(const char *value, int base);
|
||||
|
||||
size_t cvtInt64ToZ(int64_t value, char *buffer, size_t bufferSize);
|
||||
int64_t cvtZToInt64(const char *value);
|
||||
int64_t cvtZToInt64Base(const char *value, int base);
|
||||
|
||||
size_t cvtModeToZ(mode_t value, char *buffer, size_t bufferSize);
|
||||
|
||||
@ -27,9 +29,11 @@ size_t cvtSizeToZ(size_t value, char *buffer, size_t bufferSize);
|
||||
|
||||
size_t cvtUIntToZ(unsigned int value, char *buffer, size_t bufferSize);
|
||||
unsigned int cvtZToUInt(const char *value);
|
||||
unsigned int cvtZToUIntBase(const char *value, int base);
|
||||
|
||||
size_t cvtUInt64ToZ(uint64_t value, char *buffer, size_t bufferSize);
|
||||
uint64_t cvtZToUInt64(const char *value);
|
||||
uint64_t cvtZToUInt64Base(const char *value, int base);
|
||||
|
||||
const char *cvtBoolToConstZ(bool value);
|
||||
size_t cvtBoolToZ(bool value, char *buffer, size_t bufferSize);
|
||||
|
@ -62,7 +62,8 @@ testRun(void)
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))),
|
||||
bufNewZ(BOGUS_STR "\nmessage"));
|
||||
TEST_ERROR(archiveAsyncStatus(archiveModePush, segment, false), FormatError, "unable to convert string 'BOGUS' to int");
|
||||
TEST_ERROR(
|
||||
archiveAsyncStatus(archiveModePush, segment, false), FormatError, "unable to convert base 10 string 'BOGUS' to int");
|
||||
|
||||
storagePutNP(storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_OUT "/%s.ok", strPtr(segment))), NULL);
|
||||
TEST_RESULT_BOOL(archiveAsyncStatus(archiveModePush, segment, false), true, "ok file");
|
||||
|
@ -67,9 +67,12 @@ testRun(void)
|
||||
TEST_RESULT_INT(cvtIntToZ(1234567890, buffer, STACK_TRACE_PARAM_MAX), 10, "convert int to string");
|
||||
TEST_RESULT_STR(buffer, "1234567890", " check buffer");
|
||||
|
||||
TEST_ERROR(cvtZToInt("FEF"), FormatError, "unable to convert string 'FEF' to int");
|
||||
TEST_ERROR(cvtZToInt("9223372036854775807"), FormatError, "unable to convert string '9223372036854775807' to int");
|
||||
TEST_ERROR(cvtZToInt("-9223372036854775807"), FormatError, "unable to convert string '-9223372036854775807' to int");
|
||||
TEST_ERROR(cvtZToInt("FEF"), FormatError, "unable to convert base 10 string 'FEF' to int");
|
||||
TEST_ERROR(cvtZToInt("9223372036854775807"), FormatError, "unable to convert base 10 string '9223372036854775807' to int");
|
||||
TEST_ERROR(
|
||||
cvtZToInt("-9223372036854775807"), FormatError, "unable to convert base 10 string '-9223372036854775807' to int");
|
||||
|
||||
TEST_RESULT_INT(cvtZToIntBase("-FF", 16), -255, "convert string to int");
|
||||
TEST_RESULT_DOUBLE(cvtZToInt("0"), 0, "convert string to int");
|
||||
TEST_RESULT_DOUBLE(cvtZToInt("1234567890"), 1234567890, "convert string to int");
|
||||
TEST_RESULT_DOUBLE(cvtZToInt("-1234567890"), -1234567890, "convert string to int");
|
||||
@ -107,9 +110,10 @@ testRun(void)
|
||||
TEST_RESULT_INT(cvtUIntToZ(4294967295, buffer, STACK_TRACE_PARAM_MAX), 10, "convert unsigned int to string");
|
||||
TEST_RESULT_STR(buffer, "4294967295", " check buffer");
|
||||
|
||||
TEST_ERROR(cvtZToUInt("-1"), FormatError, "unable to convert string '-1' to unsigned int");
|
||||
TEST_ERROR(cvtZToUInt("5000000000"), FormatError, "unable to convert string '5000000000' to unsigned int");
|
||||
TEST_ERROR(cvtZToUInt("-1"), FormatError, "unable to convert base 10 string '-1' to unsigned int");
|
||||
TEST_ERROR(cvtZToUInt("5000000000"), FormatError, "unable to convert base 10 string '5000000000' to unsigned int");
|
||||
|
||||
TEST_RESULT_UINT(cvtZToUIntBase("FF", 16), 255, "convert string to unsigned int");
|
||||
TEST_RESULT_UINT(cvtZToUInt("3333333333"), 3333333333U, "convert string to unsigned int");
|
||||
}
|
||||
|
||||
@ -123,13 +127,16 @@ testRun(void)
|
||||
TEST_RESULT_INT(cvtInt64ToZ(9223372036854775807, buffer, STACK_TRACE_PARAM_MAX), 19, "convert int64 to string");
|
||||
TEST_RESULT_STR(buffer, "9223372036854775807", " check buffer");
|
||||
|
||||
TEST_ERROR(cvtZToInt64("123INV"), FormatError, "unable to convert string '123INV' to int64");
|
||||
TEST_ERROR(cvtZToInt64("FEF"), FormatError, "unable to convert string 'FEF' to int64");
|
||||
TEST_ERROR(cvtZToInt64(""), FormatError, "unable to convert string '' to int64");
|
||||
TEST_ERROR(cvtZToInt64(" 1"), FormatError, "unable to convert string ' 1' to int64");
|
||||
TEST_ERROR(cvtZToInt64("\t1"), FormatError, "unable to convert string '\t1' to int64");
|
||||
TEST_ERROR(cvtZToInt64("1\t"), FormatError, "unable to convert string '1\t' to int64");
|
||||
TEST_ERROR(cvtZToInt64("9223372036854775808"), FormatError, "unable to convert string '9223372036854775808' to int64");
|
||||
TEST_ERROR(cvtZToInt64("123INV"), FormatError, "unable to convert base 10 string '123INV' to int64");
|
||||
TEST_ERROR(cvtZToInt64("FEF"), FormatError, "unable to convert base 10 string 'FEF' to int64");
|
||||
TEST_ERROR(cvtZToInt64(""), FormatError, "unable to convert base 10 string '' to int64");
|
||||
TEST_ERROR(cvtZToInt64(" 1"), FormatError, "unable to convert base 10 string ' 1' to int64");
|
||||
TEST_ERROR(cvtZToInt64("\t1"), FormatError, "unable to convert base 10 string '\t1' to int64");
|
||||
TEST_ERROR(cvtZToInt64("1\t"), FormatError, "unable to convert base 10 string '1\t' to int64");
|
||||
TEST_ERROR(
|
||||
cvtZToInt64("9223372036854775808"), FormatError, "unable to convert base 10 string '9223372036854775808' to int64");
|
||||
|
||||
TEST_RESULT_INT(cvtZToInt64Base("-FF", 16), -255, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZToInt64("0"), 0, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZToInt64("9223372036854775807"), 9223372036854775807, "convert string to int64");
|
||||
TEST_RESULT_INT(cvtZToInt64("-9223372036854775807"), -9223372036854775807, "convert string to int64");
|
||||
@ -145,11 +152,12 @@ testRun(void)
|
||||
TEST_RESULT_INT(cvtUInt64ToZ(0xFFFFFFFFFFFFFFFF, buffer, STACK_TRACE_PARAM_MAX), 20, "convert uint64 to string");
|
||||
TEST_RESULT_STR(buffer, "18446744073709551615", " check buffer");
|
||||
|
||||
TEST_ERROR(cvtZToUInt64("FEF"), FormatError, "unable to convert string 'FEF' to uint64");
|
||||
TEST_ERROR(cvtZToUInt64(" 10"), FormatError, "unable to convert string ' 10' to uint64"); // number but leading space
|
||||
TEST_ERROR(cvtZToUInt64("10 "), FormatError, "unable to convert string '10 ' to uint64"); // number but trailing space
|
||||
TEST_ERROR(cvtZToUInt64("-1"), FormatError, "unable to convert string '-1' to uint64"); // number but trailing space
|
||||
TEST_ERROR(cvtZToUInt64("FEF"), FormatError, "unable to convert base 10 string 'FEF' to uint64");
|
||||
TEST_ERROR(cvtZToUInt64(" 10"), FormatError, "unable to convert base 10 string ' 10' to uint64");
|
||||
TEST_ERROR(cvtZToUInt64("10 "), FormatError, "unable to convert base 10 string '10 ' to uint64");
|
||||
TEST_ERROR(cvtZToUInt64("-1"), FormatError, "unable to convert base 10 string '-1' to uint64");
|
||||
|
||||
TEST_RESULT_UINT(cvtZToUInt64Base("FF", 16), 255, "convert string to uint64");
|
||||
TEST_RESULT_DOUBLE(cvtZToUInt64("18446744073709551615"), 18446744073709551615U, "convert string to uint64");
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(
|
||||
varInt64Force(varNewStrZ("9223372036854775808")), FormatError,
|
||||
"unable to convert string '9223372036854775808' to int64");
|
||||
"unable to convert base 10 string '9223372036854775808' to int64");
|
||||
TEST_ERROR(varInt64Force(varNewVarLst(varLstNew())), AssertError, "unable to force VariantList to int64");
|
||||
TEST_ERROR(varInt64Force(varNewUInt64(9223372036854775808U)), FormatError,
|
||||
"unable to convert uint64 9223372036854775808 to int64");
|
||||
@ -162,8 +162,8 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(
|
||||
varUInt64Force(varNewStrZ("18446744073709551616")), FormatError,
|
||||
"unable to convert string '18446744073709551616' to uint64"); // string value is out of bounds for uint64
|
||||
TEST_ERROR(varUInt64Force(varNewStrZ(" 16")), FormatError,"unable to convert string ' 16' to uint64");
|
||||
"unable to convert base 10 string '18446744073709551616' to uint64"); // string value is out of bounds for uint64
|
||||
TEST_ERROR(varUInt64Force(varNewStrZ(" 16")), FormatError,"unable to convert base 10 string ' 16' to uint64");
|
||||
TEST_ERROR(varUInt64Force(varNewVarLst(varLstNew())), AssertError, "unable to force VariantList to uint64");
|
||||
TEST_ERROR(varUInt64Force(varNewInt64(-1)), FormatError, "unable to convert int64 -1 to uint64");
|
||||
TEST_ERROR(varUInt64Force(varNewInt(-1)), FormatError, "unable to convert int -1 to uint64");
|
||||
@ -250,7 +250,7 @@ testRun(void)
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
string = varNewStr(strNew("not-an-int"));
|
||||
TEST_ERROR(varIntForce(string), FormatError, "unable to convert string 'not-an-int' to int");
|
||||
TEST_ERROR(varIntForce(string), FormatError, "unable to convert base 10 string 'not-an-int' to int");
|
||||
varFree(string);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user