1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-03-03 14:52:21 +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:
David Steele 2018-11-06 18:32:44 -05:00
parent 7de9584435
commit bef31f1802
6 changed files with 115 additions and 50 deletions

View File

@ -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>

View File

@ -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));
}

View File

@ -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);

View File

@ -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");

View 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");
}

View File

@ -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);
// -------------------------------------------------------------------------------------------------------------------------