You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-17 01:12:23 +02:00
Improve String and StringList modules.
This commit is contained in:
@ -13,18 +13,20 @@ Contains information about the string
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
struct String
|
struct String
|
||||||
{
|
{
|
||||||
|
MemContext *memContext;
|
||||||
size_t size;
|
size_t size;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Create a new string from another string
|
Create a new string from a zero-terminated string
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
String *
|
String *
|
||||||
strNew(const char *string)
|
strNew(const char *string)
|
||||||
{
|
{
|
||||||
// Create object
|
// Create object
|
||||||
String *this = memNew(sizeof(String));
|
String *this = memNew(sizeof(String));
|
||||||
|
this->memContext = memContextCurrent();
|
||||||
this->size = strlen(string);
|
this->size = strlen(string);
|
||||||
|
|
||||||
// Allocate and assign string
|
// Allocate and assign string
|
||||||
@ -43,6 +45,7 @@ strNewFmt(const char *format, ...)
|
|||||||
{
|
{
|
||||||
// Create object
|
// Create object
|
||||||
String *this = memNew(sizeof(String));
|
String *this = memNew(sizeof(String));
|
||||||
|
this->memContext = memContextCurrent();
|
||||||
|
|
||||||
// Determine how long the allocated string needs to be
|
// Determine how long the allocated string needs to be
|
||||||
va_list argumentList;
|
va_list argumentList;
|
||||||
@ -60,6 +63,28 @@ strNewFmt(const char *format, ...)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Create a new string from a string with a specific length
|
||||||
|
|
||||||
|
The string may or may not be zero-terminated but we'll use that nomeclature since we're not concerned about the end of the string.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
String *
|
||||||
|
strNewSzN(const char *string, size_t size)
|
||||||
|
{
|
||||||
|
// Create object
|
||||||
|
String *this = memNew(sizeof(String));
|
||||||
|
this->memContext = memContextCurrent();
|
||||||
|
this->size = size;
|
||||||
|
|
||||||
|
// Allocate and assign string
|
||||||
|
this->buffer = memNewRaw(this->size + 1);
|
||||||
|
strncpy(this->buffer, string, this->size);
|
||||||
|
this->buffer[this->size] = 0;
|
||||||
|
|
||||||
|
// Return buffer
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Append a string
|
Append a string
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
@ -70,9 +95,13 @@ strCat(String *this, const char *cat)
|
|||||||
int sizeGrow = strlen(cat);
|
int sizeGrow = strlen(cat);
|
||||||
|
|
||||||
// Allocate and append string
|
// Allocate and append string
|
||||||
this->buffer = memGrowRaw(this->buffer, this->size + sizeGrow + 1);
|
MEM_CONTEXT_BEGIN(this->memContext)
|
||||||
strcpy(this->buffer + this->size, cat);
|
{
|
||||||
|
this->buffer = memGrowRaw(this->buffer, this->size + sizeGrow + 1);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END();
|
||||||
|
|
||||||
|
strcpy(this->buffer + this->size, cat);
|
||||||
this->size += sizeGrow;
|
this->size += sizeGrow;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -91,7 +120,11 @@ strCatFmt(String *this, const char *format, ...)
|
|||||||
va_end(argumentList);
|
va_end(argumentList);
|
||||||
|
|
||||||
// Allocate and append string
|
// Allocate and append string
|
||||||
this->buffer = memGrowRaw(this->buffer, this->size + sizeGrow + 1);
|
MEM_CONTEXT_BEGIN(this->memContext)
|
||||||
|
{
|
||||||
|
this->buffer = memGrowRaw(this->buffer, this->size + sizeGrow + 1);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END();
|
||||||
|
|
||||||
va_start(argumentList, format);
|
va_start(argumentList, format);
|
||||||
vsnprintf(this->buffer + this->size, sizeGrow + 1, format, argumentList);
|
vsnprintf(this->buffer + this->size, sizeGrow + 1, format, argumentList);
|
||||||
@ -103,6 +136,34 @@ strCatFmt(String *this, const char *format, ...)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Duplicate a string from an existing string
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
String *
|
||||||
|
strDup(const String *this)
|
||||||
|
{
|
||||||
|
String *result = NULL;
|
||||||
|
|
||||||
|
if (this != NULL)
|
||||||
|
result = strNew(strPtr(this));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Are two strings equal?
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
bool
|
||||||
|
strEq(const String *this1, const String *this2)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (this1->size == this2->size)
|
||||||
|
result = strcmp(strPtr(this1), strPtr(this2)) == 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Return string ptr
|
Return string ptr
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
@ -121,12 +182,64 @@ strSize(const String *this)
|
|||||||
return this->size;
|
return this->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Return string size
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
String *
|
||||||
|
strTrim(String *this)
|
||||||
|
{
|
||||||
|
// Nothing to trim if size is zero
|
||||||
|
if (this->size > 0)
|
||||||
|
{
|
||||||
|
// Find the beginning of the string skipping all whitespace
|
||||||
|
char *begin = this->buffer;
|
||||||
|
|
||||||
|
while (*begin != 0 && (*begin == ' ' || *begin == '\t' || *begin == '\r' || *begin == '\n'))
|
||||||
|
begin++;
|
||||||
|
|
||||||
|
// Find the end of the string skipping all whitespace
|
||||||
|
char *end = this->buffer + (this->size - 1);
|
||||||
|
|
||||||
|
while (end > begin && (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n'))
|
||||||
|
end--;
|
||||||
|
|
||||||
|
// Is there anything to trim?
|
||||||
|
size_t newSize = (size_t)(end - begin + 1);
|
||||||
|
|
||||||
|
if (begin != this->buffer || newSize < strSize(this))
|
||||||
|
{
|
||||||
|
// Calculate new size
|
||||||
|
this->size = newSize;
|
||||||
|
|
||||||
|
// Move the substr to the beginning of the buffer
|
||||||
|
memmove(this->buffer, begin, this->size);
|
||||||
|
this->buffer[this->size] = 0;
|
||||||
|
|
||||||
|
MEM_CONTEXT_BEGIN(this->memContext)
|
||||||
|
{
|
||||||
|
// Resize the buffer
|
||||||
|
this->buffer = memGrowRaw(this->buffer, this->size + 1);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Free the string
|
Free the string
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
void
|
void
|
||||||
strFree(String *this)
|
strFree(String *this)
|
||||||
{
|
{
|
||||||
memFree(this->buffer);
|
if (this != NULL)
|
||||||
memFree(this);
|
{
|
||||||
|
MEM_CONTEXT_BEGIN(this->memContext)
|
||||||
|
{
|
||||||
|
memFree(this->buffer);
|
||||||
|
memFree(this);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,16 @@ Functions
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
String *strNew(const char *string);
|
String *strNew(const char *string);
|
||||||
String *strNewFmt(const char *format, ...);
|
String *strNewFmt(const char *format, ...);
|
||||||
size_t strSize(const String *this);
|
String *strNewSzN(const char *string, size_t size);
|
||||||
|
|
||||||
String *strCat(String *this, const char *cat);
|
String *strCat(String *this, const char *cat);
|
||||||
String *strCatFmt(String *this, const char *format, ...);
|
String *strCatFmt(String *this, const char *format, ...);
|
||||||
|
String *strDup(const String *this);
|
||||||
|
bool strEq(const String *this1, const String *this2);
|
||||||
const char *strPtr(const String *this);
|
const char *strPtr(const String *this);
|
||||||
|
size_t strSize(const String *this);
|
||||||
|
String *strTrim(String *this);
|
||||||
|
|
||||||
void strFree(String *this);
|
void strFree(String *this);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,13 +18,74 @@ strLstNew()
|
|||||||
return (StringList *)lstNew(sizeof(String *));
|
return (StringList *)lstNew(sizeof(String *));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Split a string into a string list based on a delimiter
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
StringList *
|
||||||
|
strLstNewSplit(const String *string, const String *delimiter)
|
||||||
|
{
|
||||||
|
// Create the list
|
||||||
|
StringList *this = strLstNew();
|
||||||
|
|
||||||
|
// Base points to the beginning of the string that is being searched
|
||||||
|
const char *stringBase = strPtr(string);
|
||||||
|
|
||||||
|
// Match points to the next delimiter match that has been found
|
||||||
|
const char *stringMatch = NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Find a delimiter match
|
||||||
|
stringMatch = strstr(stringBase, strPtr(delimiter));
|
||||||
|
|
||||||
|
// If a match was found then add the string
|
||||||
|
if (stringMatch != NULL)
|
||||||
|
{
|
||||||
|
strLstAdd(this, strNewSzN(stringBase, stringMatch - stringBase));
|
||||||
|
stringBase = stringMatch + strSize(delimiter);
|
||||||
|
}
|
||||||
|
// Else make whatever is left the last string
|
||||||
|
else
|
||||||
|
strLstAdd(this, strNew(stringBase));
|
||||||
|
}
|
||||||
|
while(stringMatch != NULL);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Duplicate a string list
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
StringList *
|
||||||
|
strLstDup(const StringList *sourceList)
|
||||||
|
{
|
||||||
|
// Create the list
|
||||||
|
StringList *this = strLstNew();
|
||||||
|
|
||||||
|
// Copy variants
|
||||||
|
for (unsigned int listIdx = 0; listIdx < strLstSize(sourceList); listIdx++)
|
||||||
|
strLstAdd(this, strLstGet(sourceList, listIdx));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Wrapper for lstAdd()
|
Wrapper for lstAdd()
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
StringList *
|
StringList *
|
||||||
strLstAdd(StringList *this, String *string)
|
strLstAdd(StringList *this, String *string)
|
||||||
{
|
{
|
||||||
return (StringList *)lstAdd((List *)this, &string);
|
String *stringCopy = strDup(string);
|
||||||
|
return (StringList *)lstAdd((List *)this, &stringCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Add a zero-terminated string to the list
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
StringList *
|
||||||
|
strLstAddZ(StringList *this, const char *string)
|
||||||
|
{
|
||||||
|
return strLstAdd(this, strNew(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
@ -37,9 +98,10 @@ strLstGet(const StringList *this, unsigned int listIdx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Concatenate a list of strings into a single string using the specified separator
|
Join a list of strings into a single string using the specified separator
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
String *strLstCat(StringList *this, const char *separator)
|
String *
|
||||||
|
strLstJoin(const StringList *this, const char *separator)
|
||||||
{
|
{
|
||||||
String *join = strNew("");
|
String *join = strNew("");
|
||||||
|
|
||||||
|
@ -15,9 +15,13 @@ typedef struct StringList StringList;
|
|||||||
Functions
|
Functions
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
StringList *strLstNew();
|
StringList *strLstNew();
|
||||||
|
StringList *strLstNewSplit(const String *string, const String *delimiter);
|
||||||
|
StringList *strLstDup(const StringList *sourceList);
|
||||||
|
|
||||||
StringList *strLstAdd(StringList *this, String *string);
|
StringList *strLstAdd(StringList *this, String *string);
|
||||||
|
StringList *strLstAddZ(StringList *this, const char *string);
|
||||||
String *strLstGet(const StringList *this, unsigned int listIdx);
|
String *strLstGet(const StringList *this, unsigned int listIdx);
|
||||||
String *strLstCat(StringList *this, const char *separator);
|
String *strLstJoin(const StringList *this, const char *separator);
|
||||||
const char **strLstPtr(const StringList *this);
|
const char **strLstPtr(const StringList *this);
|
||||||
unsigned int strLstSize(const StringList *this);
|
unsigned int strLstSize(const StringList *this);
|
||||||
void strLstFree(StringList *this);
|
void strLstFree(StringList *this);
|
||||||
|
@ -133,25 +133,34 @@ my $oTestDef =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
&TESTDEF_NAME => 'type-list',
|
&TESTDEF_NAME => 'type-list',
|
||||||
&TESTDEF_TOTAL => 3,
|
|
||||||
&TESTDEF_C => true,
|
|
||||||
|
|
||||||
&TESTDEF_COVERAGE =>
|
|
||||||
{
|
|
||||||
'common/type/list' => TESTDEF_COVERAGE_FULL,
|
|
||||||
'common/type/stringList' => TESTDEF_COVERAGE_FULL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
&TESTDEF_NAME => 'type-string',
|
|
||||||
&TESTDEF_TOTAL => 2,
|
&TESTDEF_TOTAL => 2,
|
||||||
&TESTDEF_C => true,
|
&TESTDEF_C => true,
|
||||||
|
|
||||||
|
&TESTDEF_COVERAGE =>
|
||||||
|
{
|
||||||
|
'common/type/list' => TESTDEF_COVERAGE_FULL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&TESTDEF_NAME => 'type-string',
|
||||||
|
&TESTDEF_TOTAL => 5,
|
||||||
|
&TESTDEF_C => true,
|
||||||
|
|
||||||
&TESTDEF_COVERAGE =>
|
&TESTDEF_COVERAGE =>
|
||||||
{
|
{
|
||||||
'common/type/string' => TESTDEF_COVERAGE_FULL,
|
'common/type/string' => TESTDEF_COVERAGE_FULL,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
&TESTDEF_NAME => 'type-string-list',
|
||||||
|
&TESTDEF_TOTAL => 4,
|
||||||
|
&TESTDEF_C => true,
|
||||||
|
|
||||||
|
&TESTDEF_COVERAGE =>
|
||||||
|
{
|
||||||
|
'common/type/stringList' => TESTDEF_COVERAGE_FULL,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
&TESTDEF_NAME => 'encode',
|
&TESTDEF_NAME => 'encode',
|
||||||
&TESTDEF_TOTAL => 1,
|
&TESTDEF_TOTAL => 1,
|
||||||
|
@ -42,67 +42,4 @@ void testRun()
|
|||||||
|
|
||||||
TEST_ERROR(lstGet(list, lstSize(list)), AssertError, "cannot get index 9 from list with 9 value(s)");
|
TEST_ERROR(lstGet(list, lstSize(list)), AssertError, "cannot get index 9 from list with 9 value(s)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
|
||||||
if (testBegin("StringList"))
|
|
||||||
{
|
|
||||||
StringList *list = strLstNew();
|
|
||||||
|
|
||||||
// Add strings to the list
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
for (int listIdx = 0; listIdx <= LIST_INITIAL_SIZE; listIdx++)
|
|
||||||
{
|
|
||||||
if (listIdx == 0)
|
|
||||||
{
|
|
||||||
TEST_RESULT_PTR(strLstAdd(list, NULL), list, "add null item");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
TEST_RESULT_PTR(strLstAdd(list, strNewFmt("STR%02d", listIdx)), list, "add item %d", listIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_RESULT_INT(strLstSize(list), 9, "list size");
|
|
||||||
|
|
||||||
// Read them back and check values
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
for (unsigned int listIdx = 0; listIdx < strLstSize(list); listIdx++)
|
|
||||||
{
|
|
||||||
if (listIdx == 0)
|
|
||||||
{
|
|
||||||
TEST_RESULT_PTR(strLstGet(list, listIdx), NULL, "check null item");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
TEST_RESULT_STR(strPtr(strLstGet(list, listIdx)), strPtr(strNewFmt("STR%02d", listIdx)), "check item %d", listIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check pointer
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
const char **szList = strLstPtr(list);
|
|
||||||
|
|
||||||
for (unsigned int listIdx = 0; listIdx < strLstSize(list); listIdx++)
|
|
||||||
{
|
|
||||||
if (listIdx == 0)
|
|
||||||
{
|
|
||||||
TEST_RESULT_PTR(szList[listIdx], NULL, "check null item");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
TEST_RESULT_STR(szList[listIdx], strPtr(strNewFmt("STR%02d", listIdx)), "check item %d", listIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// strLstCat()
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
list = strLstNew();
|
|
||||||
|
|
||||||
TEST_RESULT_STR(strPtr(strLstCat(list, ", ")), "", "empty list");
|
|
||||||
|
|
||||||
strLstAdd(list, strNew("item1"));
|
|
||||||
strLstAdd(list, strNew("item2"));
|
|
||||||
|
|
||||||
TEST_RESULT_STR(strPtr(strLstCat(list, ", ")), "item1, item2", "empty list");
|
|
||||||
|
|
||||||
strLstAdd(list, NULL);
|
|
||||||
|
|
||||||
TEST_RESULT_STR(strPtr(strLstCat(list, ", ")), "item1, item2, [NULL]", "empty list");
|
|
||||||
|
|
||||||
strLstFree(list);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
104
test/src/module/common/typeStringListTest.c
Normal file
104
test/src/module/common/typeStringListTest.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test String Lists
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Run
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void testRun()
|
||||||
|
{
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("strLstNew(), strLstAdd, strLstGet(), strLstSize(), and strLstFree()"))
|
||||||
|
{
|
||||||
|
StringList *list = strLstNew();
|
||||||
|
|
||||||
|
// Add strings to the list
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
for (int listIdx = 0; listIdx <= LIST_INITIAL_SIZE; listIdx++)
|
||||||
|
{
|
||||||
|
if (listIdx == 0)
|
||||||
|
{
|
||||||
|
TEST_RESULT_PTR(strLstAdd(list, NULL), list, "add null item");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TEST_RESULT_PTR(strLstAdd(list, strNewFmt("STR%02d", listIdx)), list, "add item %d", listIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_RESULT_INT(strLstSize(list), 9, "list size");
|
||||||
|
|
||||||
|
// Read them back and check values
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
for (unsigned int listIdx = 0; listIdx < strLstSize(list); listIdx++)
|
||||||
|
{
|
||||||
|
if (listIdx == 0)
|
||||||
|
{
|
||||||
|
TEST_RESULT_PTR(strLstGet(list, listIdx), NULL, "check null item");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TEST_RESULT_STR(strPtr(strLstGet(list, listIdx)), strPtr(strNewFmt("STR%02d", listIdx)), "check item %d", listIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
strLstFree(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("strLstPtr()"))
|
||||||
|
{
|
||||||
|
StringList *list = strLstNew();
|
||||||
|
|
||||||
|
// Add strings to the list
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
for (int listIdx = 0; listIdx <= 3; listIdx++)
|
||||||
|
{
|
||||||
|
if (listIdx == 0)
|
||||||
|
strLstAdd(list, NULL);
|
||||||
|
else
|
||||||
|
strLstAdd(list, strNewFmt("STR%02d", listIdx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check pointer
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
const char **szList = strLstPtr(list);
|
||||||
|
|
||||||
|
for (unsigned int listIdx = 0; listIdx < strLstSize(list); listIdx++)
|
||||||
|
{
|
||||||
|
if (listIdx == 0)
|
||||||
|
{
|
||||||
|
TEST_RESULT_PTR(szList[listIdx], NULL, "check null item");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TEST_RESULT_STR(szList[listIdx], strPtr(strNewFmt("STR%02d", listIdx)), "check item %d", listIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
strLstFree(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("strLstJoin()"))
|
||||||
|
{
|
||||||
|
StringList *list = strLstNew();
|
||||||
|
|
||||||
|
TEST_RESULT_STR(strPtr(strLstJoin(list, ", ")), "", "empty list");
|
||||||
|
|
||||||
|
strLstAdd(list, strNew("item1"));
|
||||||
|
strLstAddZ(list, "item2");
|
||||||
|
|
||||||
|
TEST_RESULT_STR(strPtr(strLstJoin(list, ", ")), "item1, item2", "list");
|
||||||
|
|
||||||
|
strLstAdd(list, NULL);
|
||||||
|
|
||||||
|
TEST_RESULT_STR(strPtr(strLstJoin(list, ", ")), "item1, item2, [NULL]", "list with NULL at end");
|
||||||
|
|
||||||
|
TEST_RESULT_STR(strPtr(strLstJoin(strLstDup(list), ", ")), "item1, item2, [NULL]", "dup'd list will NULL at end");
|
||||||
|
|
||||||
|
strLstFree(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("strLstSplit()"))
|
||||||
|
{
|
||||||
|
TEST_RESULT_STR(strPtr(strLstJoin(strLstNewSplit(strNew(""), strNew(", ")), ", ")), "", "empty list");
|
||||||
|
TEST_RESULT_STR(strPtr(strLstJoin(strLstNewSplit(strNew("item1"), strNew(", ")), ", ")), "item1", "one item");
|
||||||
|
TEST_RESULT_STR(strPtr(strLstJoin(strLstNewSplit(strNew("item1, item2"), strNew(", ")), ", ")), "item1, item2", "two items");
|
||||||
|
}
|
||||||
|
}
|
@ -8,18 +8,24 @@ Test Run
|
|||||||
void testRun()
|
void testRun()
|
||||||
{
|
{
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("strNew() and strFree()"))
|
if (testBegin("strNew(), strNewSzN(), and strFree()"))
|
||||||
{
|
{
|
||||||
String *string = strNew("static string");
|
String *string = strNew("static string");
|
||||||
TEST_RESULT_STR(strPtr(string), "static string", "new with static string");
|
TEST_RESULT_STR(strPtr(string), "static string", "new with static string");
|
||||||
TEST_RESULT_INT(strSize(string), 13, "check size");
|
TEST_RESULT_INT(strSize(string), 13, "check size");
|
||||||
TEST_RESULT_INT(strlen(strPtr(string)), 13, "check size with strlen()");
|
TEST_RESULT_INT(strlen(strPtr(string)), 13, "check size with strlen()");
|
||||||
TEST_RESULT_CHAR(strPtr(string)[2], 'a', "check character");
|
TEST_RESULT_CHAR(strPtr(string)[2], 'a', "check character");
|
||||||
strFree(string);
|
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(strFree(string), "free string");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_RESULT_STR(strPtr(strNewSzN("testmorestring", 4)), "test", "new string with size limit");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
string = strNewFmt("formatted %s %04d", "string", 1);
|
string = strNewFmt("formatted %s %04d", "string", 1);
|
||||||
TEST_RESULT_STR(strPtr(string), "formatted string 0001", "new with formatted string");
|
TEST_RESULT_STR(strPtr(string), "formatted string 0001", "new with formatted string");
|
||||||
strFree(string);
|
|
||||||
|
TEST_RESULT_VOID(strFree(string), "free string");
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
@ -39,4 +45,32 @@ void testRun()
|
|||||||
strFree(string);
|
strFree(string);
|
||||||
strFree(string2);
|
strFree(string2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("strDup()"))
|
||||||
|
{
|
||||||
|
String *string = strNew("duplicated string");
|
||||||
|
String *stringDup = strDup(string);
|
||||||
|
TEST_RESULT_STR(strPtr(stringDup), strPtr(string), "duplicated strings match");
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("strEq()"))
|
||||||
|
{
|
||||||
|
TEST_RESULT_BOOL(strEq(strNew("equalstring"), strNew("equalstring")), true, "strings equal");
|
||||||
|
TEST_RESULT_BOOL(strEq(strNew("astring"), strNew("anotherstring")), false, "strings not equal");
|
||||||
|
TEST_RESULT_BOOL(strEq(strNew("astring"), strNew("bstring")), false, "equal length strings not equal");
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("strTrim()"))
|
||||||
|
{
|
||||||
|
TEST_RESULT_STR(strPtr(strTrim(strNew(""))), "", "trim empty");
|
||||||
|
TEST_RESULT_STR(strPtr(strTrim(strNew("X"))), "X", "no trim (one char)");
|
||||||
|
TEST_RESULT_STR(strPtr(strTrim(strNew("no-trim"))), "no-trim", "no trim (string)");
|
||||||
|
TEST_RESULT_STR(strPtr(strTrim(strNew(" \tbegin-only"))), "begin-only", "trim begin");
|
||||||
|
TEST_RESULT_STR(strPtr(strTrim(strNew("end-only\t "))), "end-only", "trim end");
|
||||||
|
TEST_RESULT_STR(strPtr(strTrim(strNew("\n\rboth\r\n"))), "both", "trim both");
|
||||||
|
TEST_RESULT_STR(strPtr(strTrim(strNew("begin \r\n\tend"))), "begin \r\n\tend", "ignore whitespace in middle");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ void testRun()
|
|||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
strLstAdd(argList, strNew("--perl-option=value"));
|
strLstAdd(argList, strNew("--perl-option=value"));
|
||||||
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "perl option");
|
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "perl option");
|
||||||
TEST_RESULT_STR(strPtr(strLstCat(parseData->perlOptionList, ",")), "value", "check perl option");
|
TEST_RESULT_STR(strPtr(strLstJoin(parseData->perlOptionList, ",")), "value", "check perl option");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
strLstAdd(argList, strNewFmt("--%s", cfgOptionName(cfgOptDelta)));
|
strLstAdd(argList, strNewFmt("--%s", cfgOptionName(cfgOptDelta)));
|
||||||
@ -108,7 +108,7 @@ void testRun()
|
|||||||
strLstAdd(argList, strNew("/path/to/wal/RECOVERYWAL"));
|
strLstAdd(argList, strNew("/path/to/wal/RECOVERYWAL"));
|
||||||
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "command arguments");
|
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "command arguments");
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(parseData->commandArgList, "|")), "000000010000000200000003|/path/to/wal/RECOVERYWAL",
|
strPtr(strLstJoin(parseData->commandArgList, "|")), "000000010000000200000003|/path/to/wal/RECOVERYWAL",
|
||||||
" check command arguments");
|
" check command arguments");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -118,7 +118,7 @@ void testRun()
|
|||||||
strLstAdd(argList, strNew(TEST_COMMAND_BACKUP));
|
strLstAdd(argList, strNew(TEST_COMMAND_BACKUP));
|
||||||
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "single valid option");
|
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "single valid option");
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(parseData->parseOptionList[cfgOptDbHost].valueList, "|")), "db1.test.org", " check db-host option");
|
strPtr(strLstJoin(parseData->parseOptionList[cfgOptDbHost].valueList, "|")), "db1.test.org", " check db-host option");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
argList = strLstNew();
|
argList = strLstNew();
|
||||||
@ -128,7 +128,7 @@ void testRun()
|
|||||||
strLstAdd(argList, strNew(TEST_COMMAND_RESTORE));
|
strLstAdd(argList, strNew(TEST_COMMAND_RESTORE));
|
||||||
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "multiple valid options");
|
TEST_ASSIGN(parseData, configParseArg(strLstSize(argList), strLstPtr(argList)), "multiple valid options");
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(parseData->parseOptionList[cfgOptLinkMap].valueList, "|")), "ts1=/path/to/ts1|ts2=/path/to/ts2",
|
strPtr(strLstJoin(parseData->parseOptionList[cfgOptLinkMap].valueList, "|")), "ts1=/path/to/ts1|ts2=/path/to/ts2",
|
||||||
" check link-map options");
|
" check link-map options");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,21 +24,21 @@ void testRun()
|
|||||||
cmdLineParam[cmdLineParamSize++] = "backup";
|
cmdLineParam[cmdLineParamSize++] = "backup";
|
||||||
|
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
strPtr(strLstJoin(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', 'backup')|[NULL]", "simple command");
|
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', 'backup')|[NULL]", "simple command");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
cmdLineParam[cmdLineParamSize++] = "--compress";
|
cmdLineParam[cmdLineParamSize++] = "--compress";
|
||||||
|
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
strPtr(strLstJoin(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', '--compress', 'backup')|[NULL]", "simple option");
|
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', '--compress', 'backup')|[NULL]", "simple option");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
cmdLineParam[cmdLineParamSize++] = "--db-host=db1";
|
cmdLineParam[cmdLineParamSize++] = "--db-host=db1";
|
||||||
|
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
strPtr(strLstJoin(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', '--compress', '--db1-host', 'db1', 'backup')|[NULL]",
|
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', '--compress', '--db1-host', 'db1', 'backup')|[NULL]",
|
||||||
"option with = before value");
|
"option with = before value");
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ void testRun()
|
|||||||
cmdLineParam[cmdLineParamSize++] = "postgres";
|
cmdLineParam[cmdLineParamSize++] = "postgres";
|
||||||
|
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
strPtr(strLstJoin(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN
|
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN
|
||||||
"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', 'backup')|[NULL]",
|
"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', 'backup')|[NULL]",
|
||||||
"option with space before value");
|
"option with space before value");
|
||||||
@ -56,7 +56,7 @@ void testRun()
|
|||||||
cmdLineParam[cmdLineParamSize++] = "--perl-option=-I.";
|
cmdLineParam[cmdLineParamSize++] = "--perl-option=-I.";
|
||||||
|
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
strPtr(strLstJoin(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|" TEST_PERL_MAIN
|
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|" TEST_PERL_MAIN
|
||||||
" --perl-option=\"-I.\"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', 'backup')|[NULL]",
|
" --perl-option=\"-I.\"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', 'backup')|[NULL]",
|
||||||
"perl option");
|
"perl option");
|
||||||
@ -65,7 +65,7 @@ void testRun()
|
|||||||
cmdLineParam[cmdLineParamSize++] = "--no-online";
|
cmdLineParam[cmdLineParamSize++] = "--no-online";
|
||||||
|
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
strPtr(strLstJoin(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|" TEST_PERL_MAIN
|
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|" TEST_PERL_MAIN
|
||||||
" --perl-option=\"-I.\"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', '--no-online',"
|
" --perl-option=\"-I.\"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', '--no-online',"
|
||||||
" 'backup')|[NULL]",
|
" 'backup')|[NULL]",
|
||||||
@ -75,7 +75,7 @@ void testRun()
|
|||||||
cmdLineParam[cmdLineParamSize++] = "cmdarg1";
|
cmdLineParam[cmdLineParamSize++] = "cmdarg1";
|
||||||
|
|
||||||
TEST_RESULT_STR(
|
TEST_RESULT_STR(
|
||||||
strPtr(strLstCat(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
strPtr(strLstJoin(perlCommand(cmdLineParamSize, cmdLineParam), "|")),
|
||||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|" TEST_PERL_MAIN
|
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|" TEST_PERL_MAIN
|
||||||
" --perl-option=\"-I.\"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', '--no-online', 'backup',"
|
" --perl-option=\"-I.\"', '--compress', '--db1-host', 'db1', '--db1-user', 'postgres', '--no-online', 'backup',"
|
||||||
" 'cmdarg1')|[NULL]",
|
" 'cmdarg1')|[NULL]",
|
||||||
|
Reference in New Issue
Block a user