mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Refactor List, StringList, and VariantList for performance.
Introduce a standard pattern for exposing public struct members (as documented in CODING.md) and use it to inline lstSize() which should improve the performance of iterating large lists. Since many functions in these modules are just thin wrappers of other functions, inline where appropriate. Remove strLstExistsZ() and strLstInsertZ() since they were only used in tests, where the String version of the function is sufficient. Move strLstNewSplitSizeZ() to command/help/help.c and remove strLstNewSplitSize(). This function has only ever been used by help and does not seem widely applicable.
This commit is contained in:
parent
904738a5f1
commit
79a2d02c9c
30
CODING.md
30
CODING.md
@ -205,6 +205,36 @@ Don't use a macro when a function could be used instead. Macros make it hard to
|
|||||||
|
|
||||||
Object-oriented programming is used extensively. The object pointer is always referred to as `this`.
|
Object-oriented programming is used extensively. The object pointer is always referred to as `this`.
|
||||||
|
|
||||||
|
An object can expose internal struct members by defining a public struct that contains the members to be exposed and using inline functions to get/set the members.
|
||||||
|
|
||||||
|
The header file:
|
||||||
|
```c
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Getters/setters
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct ListPub
|
||||||
|
{
|
||||||
|
unsigned int listSize; // List size
|
||||||
|
} ListPub;
|
||||||
|
|
||||||
|
// List size
|
||||||
|
__attribute__((always_inline)) static inline unsigned int
|
||||||
|
lstSize(const List *this)
|
||||||
|
{
|
||||||
|
ASSERT_INLINE(this != NULL);
|
||||||
|
return ((const ListPub *)this)->listSize;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
And the C file:
|
||||||
|
```c
|
||||||
|
struct List
|
||||||
|
{
|
||||||
|
ListPub pub; // Publicly accessible variables
|
||||||
|
...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
The public struct must be the first member of the private struct. The naming convention for the public struct is to add `Pub` to the end of the private struct name.
|
||||||
|
|
||||||
### Variadic Functions
|
### Variadic Functions
|
||||||
|
|
||||||
Variadic functions can take a variable number of parameters. While the `printf()` pattern is variadic, it is not very flexible in terms of optional parameters given in any order.
|
Variadic functions can take a variable number of parameters. While the `printf()` pattern is variadic, it is not very flexible in terms of optional parameters given in any order.
|
||||||
|
@ -266,6 +266,40 @@ switch (int)
|
|||||||
<title>Objects</title>
|
<title>Objects</title>
|
||||||
|
|
||||||
<p>Object-oriented programming is used extensively. The object pointer is always referred to as <id>this</id>.</p>
|
<p>Object-oriented programming is used extensively. The object pointer is always referred to as <id>this</id>.</p>
|
||||||
|
|
||||||
|
<p>An object can expose internal struct members by defining a public struct that contains the members to be exposed and using inline functions to get/set the members.</p>
|
||||||
|
|
||||||
|
<p>The header file:</p>
|
||||||
|
|
||||||
|
<code-block type="c">
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Getters/setters
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct ListPub
|
||||||
|
{
|
||||||
|
unsigned int listSize; // List size
|
||||||
|
} ListPub;
|
||||||
|
|
||||||
|
// List size
|
||||||
|
__attribute__((always_inline)) static inline unsigned int
|
||||||
|
lstSize(const List *this)
|
||||||
|
{
|
||||||
|
ASSERT_INLINE(this != NULL);
|
||||||
|
return ((const ListPub *)this)->listSize;
|
||||||
|
}
|
||||||
|
</code-block>
|
||||||
|
|
||||||
|
<p>And the C file:</p>
|
||||||
|
|
||||||
|
<code-block type="c">
|
||||||
|
struct List
|
||||||
|
{
|
||||||
|
ListPub pub; // Publicly accessible variables
|
||||||
|
...
|
||||||
|
};
|
||||||
|
</code-block>
|
||||||
|
|
||||||
|
<p>The public struct must be the first member of the private struct. The naming convention for the public struct is to add <id>Pub</id> to the end of the private struct name.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="variadic-functions">
|
<section id="variadic-functions">
|
||||||
|
@ -26,6 +26,75 @@ Define the console width - use a fixed with of 80 since this should be safe on v
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#define CONSOLE_WIDTH 80
|
#define CONSOLE_WIDTH 80
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Helper function to split a string into a string list based on a delimiter and max size per item. In other words each item in the
|
||||||
|
list will be no longer than size even if multiple delimiters are skipped. This is useful for breaking up text on spaces, for
|
||||||
|
example.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static StringList *
|
||||||
|
helpRenderSplitSize(const String *string, const char *delimiter, size_t size)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM(STRING, string);
|
||||||
|
FUNCTION_TEST_PARAM(STRINGZ, delimiter);
|
||||||
|
FUNCTION_TEST_PARAM(SIZE, size);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
ASSERT(string != NULL);
|
||||||
|
ASSERT(delimiter != NULL);
|
||||||
|
ASSERT(size > 0);
|
||||||
|
|
||||||
|
// Create the list
|
||||||
|
StringList *this = strLstNew();
|
||||||
|
|
||||||
|
// Base points to the beginning of the string that is being searched
|
||||||
|
const char *stringBase = strZ(string);
|
||||||
|
|
||||||
|
// Match points to the next delimiter match that has been found
|
||||||
|
const char *stringMatchLast = NULL;
|
||||||
|
const char *stringMatch = NULL;
|
||||||
|
|
||||||
|
MEM_CONTEXT_BEGIN(lstMemContext((List *)this))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Find a delimiter match
|
||||||
|
stringMatch = strstr(stringMatchLast == NULL ? stringBase : stringMatchLast, delimiter);
|
||||||
|
|
||||||
|
// If a match was found then add the string
|
||||||
|
if (stringMatch != NULL)
|
||||||
|
{
|
||||||
|
if ((size_t)(stringMatch - stringBase) >= size)
|
||||||
|
{
|
||||||
|
if (stringMatchLast != NULL)
|
||||||
|
stringMatch = stringMatchLast - strlen(delimiter);
|
||||||
|
|
||||||
|
strLstAdd(this, strNewN(stringBase, (size_t)(stringMatch - stringBase)));
|
||||||
|
stringBase = stringMatch + strlen(delimiter);
|
||||||
|
stringMatchLast = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stringMatchLast = stringMatch + strlen(delimiter);
|
||||||
|
}
|
||||||
|
// Else make whatever is left the last string
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (stringMatchLast != NULL && strlen(stringBase) - strlen(delimiter) >= size)
|
||||||
|
{
|
||||||
|
strLstAdd(this, strNewN(stringBase, (size_t)((stringMatchLast - strlen(delimiter)) - stringBase)));
|
||||||
|
stringBase = stringMatchLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
strLstAdd(this, strNew(stringBase));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (stringMatch != NULL);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END();
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN(this);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Helper function for helpRender() to make output look good on a console
|
Helper function for helpRender() to make output look good on a console
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
@ -55,7 +124,7 @@ helpRenderText(const String *text, size_t indent, bool indentFirst, size_t lengt
|
|||||||
strCat(result, LF_STR);
|
strCat(result, LF_STR);
|
||||||
|
|
||||||
// Split the paragraph into lines that don't exceed the line length
|
// Split the paragraph into lines that don't exceed the line length
|
||||||
StringList *partList = strLstNewSplitSizeZ(strLstGet(lineList, lineIdx), " ", length - indent);
|
StringList *partList = helpRenderSplitSize(strLstGet(lineList, lineIdx), " ", length - indent);
|
||||||
|
|
||||||
for (unsigned int partIdx = 0; partIdx < strLstSize(partList); partIdx++)
|
for (unsigned int partIdx = 0; partIdx < strLstSize(partList); partIdx++)
|
||||||
{
|
{
|
||||||
|
@ -17,9 +17,9 @@ Object type
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
struct List
|
struct List
|
||||||
{
|
{
|
||||||
|
ListPub pub; // Publicly accessible variables
|
||||||
MemContext *memContext;
|
MemContext *memContext;
|
||||||
size_t itemSize;
|
size_t itemSize;
|
||||||
unsigned int listSize;
|
|
||||||
unsigned int listSizeMax;
|
unsigned int listSizeMax;
|
||||||
SortOrder sortOrder;
|
SortOrder sortOrder;
|
||||||
unsigned char *listAlloc; // Pointer to memory allocated for the list
|
unsigned char *listAlloc; // Pointer to memory allocated for the list
|
||||||
@ -59,21 +59,6 @@ lstNew(size_t itemSize, ListParam param)
|
|||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
void *
|
|
||||||
lstAdd(List *this, const void *item)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM_P(VOID, item);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
ASSERT(item != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstInsert(this, lstSize(this), item));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
List *
|
List *
|
||||||
lstClear(List *this)
|
lstClear(List *this)
|
||||||
@ -92,7 +77,7 @@ lstClear(List *this)
|
|||||||
}
|
}
|
||||||
MEM_CONTEXT_END();
|
MEM_CONTEXT_END();
|
||||||
|
|
||||||
this->listSize = 0;
|
this->pub.listSize = 0;
|
||||||
this->listSizeMax = 0;
|
this->listSizeMax = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,8 +122,8 @@ lstGet(const List *this, unsigned int listIdx)
|
|||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
// Ensure list index is in range
|
// Ensure list index is in range
|
||||||
if (listIdx >= this->listSize)
|
if (listIdx >= lstSize(this))
|
||||||
THROW_FMT(AssertError, "cannot get index %u from list with %u value(s)", listIdx, this->listSize);
|
THROW_FMT(AssertError, "cannot get index %u from list with %u value(s)", listIdx, lstSize(this));
|
||||||
|
|
||||||
// Return pointer to list item
|
// Return pointer to list item
|
||||||
FUNCTION_TEST_RETURN(this->list + (listIdx * this->itemSize));
|
FUNCTION_TEST_RETURN(this->list + (listIdx * this->itemSize));
|
||||||
@ -154,26 +139,11 @@ lstGetLast(const List *this)
|
|||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
// Ensure there are items in the list
|
// Ensure there are items in the list
|
||||||
if (this->listSize == 0)
|
if (lstSize(this) == 0)
|
||||||
THROW(AssertError, "cannot get last from list with no values");
|
THROW(AssertError, "cannot get last from list with no values");
|
||||||
|
|
||||||
// Return pointer to list item
|
// Return pointer to list item
|
||||||
FUNCTION_TEST_RETURN(lstGet(this, this->listSize - 1));
|
FUNCTION_TEST_RETURN(lstGet(this, lstSize(this) - 1));
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
bool
|
|
||||||
lstExists(const List *this, const void *item)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM_P(VOID, item);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
ASSERT(item != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstFind(this, item) != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
@ -190,13 +160,13 @@ lstFind(const List *this, const void *item)
|
|||||||
ASSERT(item != NULL);
|
ASSERT(item != NULL);
|
||||||
|
|
||||||
if (this->sortOrder == sortOrderAsc)
|
if (this->sortOrder == sortOrderAsc)
|
||||||
FUNCTION_TEST_RETURN(bsearch(item, this->list, this->listSize, this->itemSize, this->comparator));
|
FUNCTION_TEST_RETURN(bsearch(item, this->list, lstSize(this), this->itemSize, this->comparator));
|
||||||
else if (this->sortOrder == sortOrderDesc)
|
else if (this->sortOrder == sortOrderDesc)
|
||||||
{
|
{
|
||||||
// Assign the list for the descending comparator to use
|
// Assign the list for the descending comparator to use
|
||||||
comparatorDescList = this;
|
comparatorDescList = this;
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(bsearch(item, this->list, this->listSize, this->itemSize, lstComparatorDesc));
|
FUNCTION_TEST_RETURN(bsearch(item, this->list, lstSize(this), this->itemSize, lstComparatorDesc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back on an iterative search
|
// Fall back on an iterative search
|
||||||
@ -260,7 +230,7 @@ lstIdx(const List *this, const void *item)
|
|||||||
size_t result = (size_t)((unsigned char * const)item - this->list) / this->itemSize;
|
size_t result = (size_t)((unsigned char * const)item - this->list) / this->itemSize;
|
||||||
|
|
||||||
// Item pointers should always be in range
|
// Item pointers should always be in range
|
||||||
ASSERT(result < this->listSize);
|
ASSERT(result < lstSize(this));
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN((unsigned int)result);
|
FUNCTION_TEST_RETURN((unsigned int)result);
|
||||||
}
|
}
|
||||||
@ -279,7 +249,7 @@ lstInsert(List *this, unsigned int listIdx, const void *item)
|
|||||||
ASSERT(item != NULL);
|
ASSERT(item != NULL);
|
||||||
|
|
||||||
// If list size = max then allocate more space
|
// If list size = max then allocate more space
|
||||||
if (this->listSize == this->listSizeMax)
|
if (lstSize(this) == this->listSizeMax)
|
||||||
{
|
{
|
||||||
MEM_CONTEXT_BEGIN(this->memContext)
|
MEM_CONTEXT_BEGIN(this->memContext)
|
||||||
{
|
{
|
||||||
@ -303,9 +273,9 @@ lstInsert(List *this, unsigned int listIdx, const void *item)
|
|||||||
// Else if there is space before the beginning of the list then move the list down
|
// Else if there is space before the beginning of the list then move the list down
|
||||||
else if (
|
else if (
|
||||||
(this->list != this->listAlloc) &&
|
(this->list != this->listAlloc) &&
|
||||||
(this->listSize + ((uintptr_t)(this->list - this->listAlloc) / this->itemSize) == this->listSizeMax))
|
(lstSize(this) + ((uintptr_t)(this->list - this->listAlloc) / this->itemSize) == this->listSizeMax))
|
||||||
{
|
{
|
||||||
memmove(this->listAlloc, this->list, this->listSize * this->itemSize);
|
memmove(this->listAlloc, this->list, lstSize(this) * this->itemSize);
|
||||||
this->list = this->listAlloc;
|
this->list = this->listAlloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +289,7 @@ lstInsert(List *this, unsigned int listIdx, const void *item)
|
|||||||
// Copy item into the list
|
// Copy item into the list
|
||||||
this->sortOrder = sortOrderNone;
|
this->sortOrder = sortOrderNone;
|
||||||
memcpy(itemPtr, item, this->itemSize);
|
memcpy(itemPtr, item, this->itemSize);
|
||||||
this->listSize++;
|
this->pub.listSize++;
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(itemPtr);
|
FUNCTION_TEST_RETURN(itemPtr);
|
||||||
}
|
}
|
||||||
@ -337,7 +307,7 @@ lstRemoveIdx(List *this, unsigned int listIdx)
|
|||||||
ASSERT(listIdx <= lstSize(this));
|
ASSERT(listIdx <= lstSize(this));
|
||||||
|
|
||||||
// Decrement the list size
|
// Decrement the list size
|
||||||
this->listSize--;
|
this->pub.listSize--;
|
||||||
|
|
||||||
// If this is the first item then move the list pointer up to avoid moving all the items
|
// If this is the first item then move the list pointer up to avoid moving all the items
|
||||||
if (listIdx == 0)
|
if (listIdx == 0)
|
||||||
@ -386,10 +356,10 @@ lstRemoveLast(List *this)
|
|||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
if (this->listSize == 0)
|
if (lstSize(this) == 0)
|
||||||
THROW(AssertError, "cannot remove last from list with no values");
|
THROW(AssertError, "cannot remove last from list with no values");
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstRemoveIdx(this, this->listSize - 1));
|
FUNCTION_TEST_RETURN(lstRemoveIdx(this, lstSize(this) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
@ -405,19 +375,6 @@ lstMemContext(const List *this)
|
|||||||
FUNCTION_TEST_RETURN(this->memContext);
|
FUNCTION_TEST_RETURN(this->memContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
unsigned int
|
|
||||||
lstSize(const List *this)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(LIST, this);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this->listSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
List *
|
List *
|
||||||
lstSort(List *this, SortOrder sortOrder)
|
lstSort(List *this, SortOrder sortOrder)
|
||||||
@ -433,7 +390,7 @@ lstSort(List *this, SortOrder sortOrder)
|
|||||||
switch (sortOrder)
|
switch (sortOrder)
|
||||||
{
|
{
|
||||||
case sortOrderAsc:
|
case sortOrderAsc:
|
||||||
qsort(this->list, this->listSize, this->itemSize, this->comparator);
|
qsort(this->list, lstSize(this), this->itemSize, this->comparator);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sortOrderDesc:
|
case sortOrderDesc:
|
||||||
@ -441,7 +398,7 @@ lstSort(List *this, SortOrder sortOrder)
|
|||||||
// Assign the list that will be sorted for the comparator function to use
|
// Assign the list that will be sorted for the comparator function to use
|
||||||
comparatorDescList = this;
|
comparatorDescList = this;
|
||||||
|
|
||||||
qsort(this->list, this->listSize, this->itemSize, lstComparatorDesc);
|
qsort(this->list, lstSize(this), this->itemSize, lstComparatorDesc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,5 +432,5 @@ lstComparatorSet(List *this, ListComparator *comparator)
|
|||||||
String *
|
String *
|
||||||
lstToLog(const List *this)
|
lstToLog(const List *this)
|
||||||
{
|
{
|
||||||
return strNewFmt("{size: %u}", this->listSize);
|
return strNewFmt("{size: %u}", lstSize(this));
|
||||||
}
|
}
|
||||||
|
@ -63,12 +63,35 @@ typedef struct ListParam
|
|||||||
|
|
||||||
List *lstNew(size_t itemSize, ListParam param);
|
List *lstNew(size_t itemSize, ListParam param);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Getters/Setters
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct ListPub
|
||||||
|
{
|
||||||
|
unsigned int listSize; // List size
|
||||||
|
} ListPub;
|
||||||
|
|
||||||
|
// Set a new comparator
|
||||||
|
List *lstComparatorSet(List *this, ListComparator *comparator);
|
||||||
|
|
||||||
|
// List size
|
||||||
|
__attribute__((always_inline)) static inline unsigned int
|
||||||
|
lstSize(const List *this)
|
||||||
|
{
|
||||||
|
ASSERT_INLINE(this != NULL);
|
||||||
|
return ((const ListPub *)this)->listSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the list empty?
|
||||||
|
__attribute__((always_inline)) static inline bool
|
||||||
|
lstEmpty(const List *this)
|
||||||
|
{
|
||||||
|
return lstSize(this) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Functions
|
Functions
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
// Add an item to the end of the list
|
|
||||||
void *lstAdd(List *this, const void *item);
|
|
||||||
|
|
||||||
// Clear items from a list
|
// Clear items from a list
|
||||||
List *lstClear(List *this);
|
List *lstClear(List *this);
|
||||||
|
|
||||||
@ -76,20 +99,31 @@ List *lstClear(List *this);
|
|||||||
void *lstGet(const List *this, unsigned int listIdx);
|
void *lstGet(const List *this, unsigned int listIdx);
|
||||||
void *lstGetLast(const List *this);
|
void *lstGetLast(const List *this);
|
||||||
|
|
||||||
// Does an item exist in the list?
|
|
||||||
bool lstExists(const List *this, const void *item);
|
|
||||||
|
|
||||||
// Find an item in the list
|
// Find an item in the list
|
||||||
void *lstFind(const List *this, const void *item);
|
void *lstFind(const List *this, const void *item);
|
||||||
void *lstFindDefault(const List *this, const void *item, void *itemDefault);
|
void *lstFindDefault(const List *this, const void *item, void *itemDefault);
|
||||||
unsigned int lstFindIdx(const List *this, const void *item);
|
unsigned int lstFindIdx(const List *this, const void *item);
|
||||||
|
|
||||||
|
// Does an item exist in the list?
|
||||||
|
__attribute__((always_inline)) static inline bool
|
||||||
|
lstExists(const List *this, const void *item)
|
||||||
|
{
|
||||||
|
return lstFind(this, item) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the index of a list item
|
// Get the index of a list item
|
||||||
unsigned int lstIdx(const List *this, const void *item);
|
unsigned int lstIdx(const List *this, const void *item);
|
||||||
|
|
||||||
// Insert an item into the list
|
// Insert an item into the list
|
||||||
void *lstInsert(List *this, unsigned int listIdx, const void *item);
|
void *lstInsert(List *this, unsigned int listIdx, const void *item);
|
||||||
|
|
||||||
|
// Add an item to the end of the list
|
||||||
|
__attribute__((always_inline)) static inline void *
|
||||||
|
lstAdd(List *this, const void *item)
|
||||||
|
{
|
||||||
|
return lstInsert(this, lstSize(this), item);
|
||||||
|
}
|
||||||
|
|
||||||
// Memory context for this list
|
// Memory context for this list
|
||||||
MemContext *lstMemContext(const List *this);
|
MemContext *lstMemContext(const List *this);
|
||||||
|
|
||||||
@ -101,25 +135,9 @@ bool lstRemove(List *this, const void *item);
|
|||||||
List *lstRemoveIdx(List *this, unsigned int listIdx);
|
List *lstRemoveIdx(List *this, unsigned int listIdx);
|
||||||
List *lstRemoveLast(List *this);
|
List *lstRemoveLast(List *this);
|
||||||
|
|
||||||
// Return list size
|
|
||||||
unsigned int lstSize(const List *this);
|
|
||||||
|
|
||||||
// Is the list empty?
|
|
||||||
__attribute__((always_inline)) static inline bool
|
|
||||||
lstEmpty(const List *this)
|
|
||||||
{
|
|
||||||
return lstSize(this) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// List sort
|
// List sort
|
||||||
List *lstSort(List *this, SortOrder sortOrder);
|
List *lstSort(List *this, SortOrder sortOrder);
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
|
||||||
Getters/Setters
|
|
||||||
***********************************************************************************************************************************/
|
|
||||||
// Set a new comparator
|
|
||||||
List *lstComparatorSet(List *this, ListComparator *comparator);
|
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Destructor
|
Destructor
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
|
@ -12,64 +12,25 @@ String List Handler
|
|||||||
#include "common/memContext.h"
|
#include "common/memContext.h"
|
||||||
#include "common/type/stringList.h"
|
#include "common/type/stringList.h"
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
|
||||||
Wrapper for lstNew*()
|
|
||||||
***********************************************************************************************************************************/
|
|
||||||
StringList *
|
|
||||||
strLstNew(void)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_VOID();
|
|
||||||
FUNCTION_TEST_RETURN((StringList *)lstNewP(sizeof(String *), .comparator = lstComparatorStr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Internal add -- the string must have been created in the list's mem context before being passed
|
Internal add -- the string must have been created in the list's mem context before being passed
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
static String *
|
__attribute__((always_inline)) static inline String *
|
||||||
strLstAddInternal(StringList *this, String *string)
|
strLstAddInternal(StringList *this, String *string)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
return *(String **)lstAdd((List *)this, &string);
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(STRING, string);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(*(String **)lstAdd((List *)this, &string));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Internal insert -- the string must have been created in the list's mem context before being passed
|
Internal insert -- the string must have been created in the list's mem context before being passed
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
static String *
|
__attribute__((always_inline)) static inline String *
|
||||||
strLstInsertInternal(StringList *this, unsigned int listIdx, String *string)
|
strLstInsertInternal(StringList *this, unsigned int listIdx, String *string)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
return *(String **)lstInsert((List *)this, listIdx, &string);
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(UINT, listIdx);
|
|
||||||
FUNCTION_TEST_PARAM(STRING, string);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(*(String **)lstInsert((List *)this, listIdx, &string));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
StringList *
|
|
||||||
strLstNewSplit(const String *string, const String *delimiter)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING, string);
|
|
||||||
FUNCTION_TEST_PARAM(STRING, delimiter);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(string != NULL);
|
|
||||||
ASSERT(delimiter != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(strLstNewSplitZ(string, strZ(delimiter)));
|
|
||||||
}
|
|
||||||
|
|
||||||
StringList *
|
StringList *
|
||||||
strLstNewSplitZ(const String *string, const char *delimiter)
|
strLstNewSplitZ(const String *string, const char *delimiter)
|
||||||
{
|
{
|
||||||
@ -114,85 +75,6 @@ strLstNewSplitZ(const String *string, const char *delimiter)
|
|||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
StringList *
|
|
||||||
strLstNewSplitSize(const String *string, const String *delimiter, size_t size)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING, string);
|
|
||||||
FUNCTION_TEST_PARAM(STRING, delimiter);
|
|
||||||
FUNCTION_TEST_PARAM(SIZE, size);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(string != NULL);
|
|
||||||
ASSERT(delimiter != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(strLstNewSplitSizeZ(string, strZ(delimiter), size));
|
|
||||||
}
|
|
||||||
|
|
||||||
StringList *
|
|
||||||
strLstNewSplitSizeZ(const String *string, const char *delimiter, size_t size)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING, string);
|
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, delimiter);
|
|
||||||
FUNCTION_TEST_PARAM(SIZE, size);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(string != NULL);
|
|
||||||
ASSERT(delimiter != NULL);
|
|
||||||
|
|
||||||
// Create the list
|
|
||||||
StringList *this = strLstNew();
|
|
||||||
|
|
||||||
// Base points to the beginning of the string that is being searched
|
|
||||||
const char *stringBase = strZ(string);
|
|
||||||
|
|
||||||
// Match points to the next delimiter match that has been found
|
|
||||||
const char *stringMatchLast = NULL;
|
|
||||||
const char *stringMatch = NULL;
|
|
||||||
|
|
||||||
MEM_CONTEXT_BEGIN(lstMemContext((List *)this))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Find a delimiter match
|
|
||||||
stringMatch = strstr(stringMatchLast == NULL ? stringBase : stringMatchLast, delimiter);
|
|
||||||
|
|
||||||
// If a match was found then add the string
|
|
||||||
if (stringMatch != NULL)
|
|
||||||
{
|
|
||||||
if ((size_t)(stringMatch - stringBase) >= size)
|
|
||||||
{
|
|
||||||
if (stringMatchLast != NULL)
|
|
||||||
stringMatch = stringMatchLast - strlen(delimiter);
|
|
||||||
|
|
||||||
strLstAddInternal(this, strNewN(stringBase, (size_t)(stringMatch - stringBase)));
|
|
||||||
stringBase = stringMatch + strlen(delimiter);
|
|
||||||
stringMatchLast = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
stringMatchLast = stringMatch + strlen(delimiter);
|
|
||||||
}
|
|
||||||
// Else make whatever is left the last string
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (stringMatchLast != NULL && strlen(stringBase) - strlen(delimiter) >= size)
|
|
||||||
{
|
|
||||||
strLstAddInternal(this, strNewN(stringBase, (size_t)((stringMatchLast - strlen(delimiter)) - stringBase)));
|
|
||||||
stringBase = stringMatchLast;
|
|
||||||
}
|
|
||||||
|
|
||||||
strLstAddInternal(this, strNew(stringBase));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (stringMatch != NULL);
|
|
||||||
}
|
|
||||||
MEM_CONTEXT_END();
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
StringList *
|
StringList *
|
||||||
strLstNewVarLst(const VariantList *sourceList)
|
strLstNewVarLst(const VariantList *sourceList)
|
||||||
@ -247,35 +129,6 @@ strLstDup(const StringList *sourceList)
|
|||||||
FUNCTION_TEST_RETURN(this);
|
FUNCTION_TEST_RETURN(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
bool
|
|
||||||
strLstExists(const StringList *this, const String *string)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(STRING, string);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstExists((List *)this, &string));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
strLstExistsZ(const StringList *this, const char *cstring)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, cstring);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
const String *string = cstring == NULL ? NULL : STR(cstring);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstExists((List *)this, &string));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
String *
|
String *
|
||||||
strLstAdd(StringList *this, const String *string)
|
strLstAdd(StringList *this, const String *string)
|
||||||
@ -337,20 +190,6 @@ strLstAddZ(StringList *this, const char *string)
|
|||||||
FUNCTION_TEST_RETURN(result);
|
FUNCTION_TEST_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
String *
|
|
||||||
strLstGet(const StringList *this, unsigned int listIdx)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(UINT, listIdx);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(*(String **)lstGet((List *)this, listIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
String *
|
String *
|
||||||
strLstInsert(StringList *this, unsigned int listIdx, const String *string)
|
strLstInsert(StringList *this, unsigned int listIdx, const String *string)
|
||||||
@ -374,43 +213,6 @@ strLstInsert(StringList *this, unsigned int listIdx, const String *string)
|
|||||||
FUNCTION_TEST_RETURN(result);
|
FUNCTION_TEST_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
String *
|
|
||||||
strLstInsertZ(StringList *this, unsigned int listIdx, const char *string)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(UINT, listIdx);
|
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, string);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
String *result = NULL;
|
|
||||||
|
|
||||||
MEM_CONTEXT_BEGIN(lstMemContext((List *)this))
|
|
||||||
{
|
|
||||||
result = strLstInsertInternal(this, listIdx, strNew(string));
|
|
||||||
}
|
|
||||||
MEM_CONTEXT_END();
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
String *
|
|
||||||
strLstJoin(const StringList *this, const char *separator)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, separator);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
ASSERT(separator != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(strLstJoinQuote(this, separator, ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
String *
|
String *
|
||||||
strLstJoinQuote(const StringList *this, const char *separator, const char *quote)
|
strLstJoinQuote(const StringList *this, const char *separator, const char *quote)
|
||||||
@ -502,22 +304,6 @@ strLstMergeAnti(const StringList *this, const StringList *anti)
|
|||||||
FUNCTION_TEST_RETURN(result);
|
FUNCTION_TEST_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
StringList *
|
|
||||||
strLstMove(StringList *this, MemContext *parentNew)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(parentNew != NULL);
|
|
||||||
|
|
||||||
lstMove((List *)this, parentNew);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
const char **
|
const char **
|
||||||
strLstPtr(const StringList *this)
|
strLstPtr(const StringList *this)
|
||||||
@ -543,93 +329,9 @@ strLstPtr(const StringList *this)
|
|||||||
FUNCTION_TEST_RETURN(list);
|
FUNCTION_TEST_RETURN(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
bool
|
|
||||||
strLstRemove(StringList *this, const String *item)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(STRING, item);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
ASSERT(item != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstRemove((List *)this, &item));
|
|
||||||
}
|
|
||||||
|
|
||||||
StringList *
|
|
||||||
strLstRemoveIdx(StringList *this, unsigned int listIdx)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(UINT, listIdx);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN((StringList *)lstRemoveIdx((List *)this, listIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
unsigned int
|
|
||||||
strLstSize(const StringList *this)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstSize((List *)this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
StringList *
|
|
||||||
strLstSort(StringList *this, SortOrder sortOrder)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(ENUM, sortOrder);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
lstSort((List *)this, sortOrder);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
StringList *
|
|
||||||
strLstComparatorSet(StringList *this, ListComparator *comparator)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(FUNCTIONP, comparator);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
lstComparatorSet((List *)this, comparator);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
String *
|
String *
|
||||||
strLstToLog(const StringList *this)
|
strLstToLog(const StringList *this)
|
||||||
{
|
{
|
||||||
return strNewFmt("{[%s]}", strZ(strLstJoinQuote(this, ", ", "\"")));
|
return strNewFmt("{[%s]}", strZ(strLstJoinQuote(this, ", ", "\"")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
void
|
|
||||||
strLstFree(StringList *this)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
lstFree((List *)this);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
|
||||||
}
|
|
||||||
|
@ -17,16 +17,21 @@ typedef struct StringList StringList;
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Constructors
|
Constructors
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
StringList *strLstNew(void);
|
// Create empty StringList
|
||||||
|
__attribute__((always_inline)) static inline StringList *
|
||||||
|
strLstNew(void)
|
||||||
|
{
|
||||||
|
return (StringList *)lstNewP(sizeof(String *), .comparator = lstComparatorStr);
|
||||||
|
}
|
||||||
|
|
||||||
// Split a string into a string list based on a delimiter
|
// Split a string into a string list based on a delimiter
|
||||||
StringList *strLstNewSplit(const String *string, const String *delimiter);
|
|
||||||
StringList *strLstNewSplitZ(const String *string, const char *delimiter);
|
StringList *strLstNewSplitZ(const String *string, const char *delimiter);
|
||||||
|
|
||||||
// Split a string into a string list based on a delimiter and max size per item. In other words each item in the list will be no
|
__attribute__((always_inline)) static inline StringList *
|
||||||
// longer than size even if multiple delimiters are skipped. This is useful for breaking up text on spaces, for example.
|
strLstNewSplit(const String *string, const String *delimiter)
|
||||||
StringList *strLstNewSplitSize(const String *string, const String *delimiter, size_t size);
|
{
|
||||||
StringList *strLstNewSplitSizeZ(const String *string, const char *delimiter, size_t size);
|
return strLstNewSplitZ(string, strZ(delimiter));
|
||||||
|
}
|
||||||
|
|
||||||
// New string list from a variant list -- all variants in the list must be type string
|
// New string list from a variant list -- all variants in the list must be type string
|
||||||
StringList *strLstNewVarLst(const VariantList *sourceList);
|
StringList *strLstNewVarLst(const VariantList *sourceList);
|
||||||
@ -34,6 +39,30 @@ StringList *strLstNewVarLst(const VariantList *sourceList);
|
|||||||
// Duplicate a string list
|
// Duplicate a string list
|
||||||
StringList *strLstDup(const StringList *sourceList);
|
StringList *strLstDup(const StringList *sourceList);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Getters/Setters
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
// Set a new comparator
|
||||||
|
__attribute__((always_inline)) static inline StringList *
|
||||||
|
strLstComparatorSet(StringList *this, ListComparator *comparator)
|
||||||
|
{
|
||||||
|
return (StringList *)lstComparatorSet((List *)this, comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// List size
|
||||||
|
__attribute__((always_inline)) static inline unsigned int
|
||||||
|
strLstSize(const StringList *this)
|
||||||
|
{
|
||||||
|
return lstSize((List *)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the list empty?
|
||||||
|
__attribute__((always_inline)) static inline bool
|
||||||
|
strLstEmpty(const StringList *this)
|
||||||
|
{
|
||||||
|
return strLstSize(this) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Functions
|
Functions
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
@ -43,60 +72,75 @@ String *strLstAddZ(StringList *this, const char *string);
|
|||||||
String *strLstAddIfMissing(StringList *this, const String *string);
|
String *strLstAddIfMissing(StringList *this, const String *string);
|
||||||
|
|
||||||
// Does the specified string exist in the list?
|
// Does the specified string exist in the list?
|
||||||
bool strLstExists(const StringList *this, const String *string);
|
__attribute__((always_inline)) static inline bool
|
||||||
bool strLstExistsZ(const StringList *this, const char *cstring);
|
strLstExists(const StringList *this, const String *string)
|
||||||
|
{
|
||||||
|
return lstExists((List *)this, &string);
|
||||||
|
}
|
||||||
|
|
||||||
// Insert into the list
|
// Insert into the list
|
||||||
String *strLstInsert(StringList *this, unsigned int listIdx, const String *string);
|
String *strLstInsert(StringList *this, unsigned int listIdx, const String *string);
|
||||||
String *strLstInsertZ(StringList *this, unsigned int listIdx, const char *string);
|
|
||||||
|
|
||||||
// Get a string by index
|
// Get a string by index
|
||||||
String *strLstGet(const StringList *this, unsigned int listIdx);
|
__attribute__((always_inline)) static inline String *
|
||||||
|
strLstGet(const StringList *this, unsigned int listIdx)
|
||||||
// Join a list of strings into a single string using the specified separator
|
{
|
||||||
String *strLstJoin(const StringList *this, const char *separator);
|
return *(String **)lstGet((List *)this, listIdx);
|
||||||
|
}
|
||||||
|
|
||||||
// Join a list of strings into a single string using the specified separator and quote with specified quote character
|
// Join a list of strings into a single string using the specified separator and quote with specified quote character
|
||||||
String *strLstJoinQuote(const StringList *this, const char *separator, const char *quote);
|
String *strLstJoinQuote(const StringList *this, const char *separator, const char *quote);
|
||||||
|
|
||||||
|
// Join a list of strings into a single string using the specified separator
|
||||||
|
__attribute__((always_inline)) static inline String *
|
||||||
|
strLstJoin(const StringList *this, const char *separator)
|
||||||
|
{
|
||||||
|
return strLstJoinQuote(this, separator, "");
|
||||||
|
}
|
||||||
|
|
||||||
// Return all items in this list which are not in the anti list. The input lists must *both* be sorted ascending or the results will
|
// Return all items in this list which are not in the anti list. The input lists must *both* be sorted ascending or the results will
|
||||||
// be undefined.
|
// be undefined.
|
||||||
StringList *strLstMergeAnti(const StringList *this, const StringList *anti);
|
StringList *strLstMergeAnti(const StringList *this, const StringList *anti);
|
||||||
|
|
||||||
// Move to a new parent mem context
|
// Move to a new parent mem context
|
||||||
StringList *strLstMove(StringList *this, MemContext *parentNew);
|
__attribute__((always_inline)) static inline StringList *
|
||||||
|
strLstMove(StringList *this, MemContext *parentNew)
|
||||||
|
{
|
||||||
|
return (StringList *)lstMove((List *)this, parentNew);
|
||||||
|
}
|
||||||
|
|
||||||
// Return a null-terminated array of pointers to the zero-terminated strings in this list. DO NOT override const and modify any of
|
// Return a null-terminated array of pointers to the zero-terminated strings in this list. DO NOT override const and modify any of
|
||||||
// the strings in this array, though it is OK to modify the array itself.
|
// the strings in this array, though it is OK to modify the array itself.
|
||||||
const char **strLstPtr(const StringList *this);
|
const char **strLstPtr(const StringList *this);
|
||||||
|
|
||||||
// Remove an item from the list
|
// Remove an item from the list
|
||||||
bool strLstRemove(StringList *this, const String *item);
|
|
||||||
StringList *strLstRemoveIdx(StringList *this, unsigned int listIdx);
|
|
||||||
|
|
||||||
// List size
|
|
||||||
unsigned int strLstSize(const StringList *this);
|
|
||||||
|
|
||||||
// Is the list empty?
|
|
||||||
__attribute__((always_inline)) static inline bool
|
__attribute__((always_inline)) static inline bool
|
||||||
strLstEmpty(const StringList *this)
|
strLstRemove(StringList *this, const String *item)
|
||||||
{
|
{
|
||||||
return strLstSize(this) == 0;
|
return lstRemove((List *)this, &item);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) static inline StringList *
|
||||||
|
strLstRemoveIdx(StringList *this, unsigned int listIdx)
|
||||||
|
{
|
||||||
|
return (StringList *)lstRemoveIdx((List *)this, listIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// List sort
|
// List sort
|
||||||
StringList *strLstSort(StringList *this, SortOrder sortOrder);
|
__attribute__((always_inline)) static inline StringList *
|
||||||
|
strLstSort(StringList *this, SortOrder sortOrder)
|
||||||
/***********************************************************************************************************************************
|
{
|
||||||
Getters/Setters
|
return (StringList *)lstSort((List *)this, sortOrder);
|
||||||
***********************************************************************************************************************************/
|
}
|
||||||
// Set a new comparator
|
|
||||||
StringList *strLstComparatorSet(StringList *this, ListComparator *comparator);
|
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Destructor
|
Destructor
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
void strLstFree(StringList *this);
|
__attribute__((always_inline)) static inline void
|
||||||
|
strLstFree(StringList *this)
|
||||||
|
{
|
||||||
|
lstFree((List *)this);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Macros for function logging
|
Macros for function logging
|
||||||
|
@ -12,16 +12,6 @@ Variant List Handler
|
|||||||
#include "common/type/list.h"
|
#include "common/type/list.h"
|
||||||
#include "common/type/variantList.h"
|
#include "common/type/variantList.h"
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
|
||||||
Wrapper for lstNewP()
|
|
||||||
***********************************************************************************************************************************/
|
|
||||||
VariantList *
|
|
||||||
varLstNew(void)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_VOID();
|
|
||||||
FUNCTION_TEST_RETURN((VariantList *)lstNewP(sizeof(Variant *)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
VariantList *
|
VariantList *
|
||||||
varLstNewStrLst(const StringList *stringList)
|
varLstNewStrLst(const StringList *stringList)
|
||||||
@ -63,75 +53,3 @@ varLstDup(const VariantList *source)
|
|||||||
|
|
||||||
FUNCTION_TEST_RETURN(result);
|
FUNCTION_TEST_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
VariantList *
|
|
||||||
varLstAdd(VariantList *this, Variant *data)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(VARIANT, data);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
lstAdd((List *)this, &data);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
Variant *
|
|
||||||
varLstGet(const VariantList *this, unsigned int listIdx)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(UINT, listIdx);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(*(Variant **)lstGet((List *)this, listIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
unsigned int
|
|
||||||
varLstSize(const VariantList *this)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(lstSize((List *)this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
VariantList *
|
|
||||||
varLstMove(VariantList *this, MemContext *parentNew)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
|
|
||||||
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
ASSERT(parentNew != NULL);
|
|
||||||
|
|
||||||
lstMove((List *)this, parentNew);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
|
||||||
void
|
|
||||||
varLstFree(VariantList *this)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM(VARIANT_LIST, this);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
lstFree((List *)this);
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
|
||||||
}
|
|
||||||
|
@ -15,7 +15,12 @@ typedef struct VariantList VariantList;
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Constructors
|
Constructors
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
VariantList *varLstNew(void);
|
// Create empty VariantList
|
||||||
|
__attribute__((always_inline)) static inline VariantList *
|
||||||
|
varLstNew(void)
|
||||||
|
{
|
||||||
|
return (VariantList *)lstNewP(sizeof(Variant *));
|
||||||
|
}
|
||||||
|
|
||||||
// Create VariantList from StringList
|
// Create VariantList from StringList
|
||||||
VariantList *varLstNewStrLst(const StringList *stringList);
|
VariantList *varLstNewStrLst(const StringList *stringList);
|
||||||
@ -24,19 +29,14 @@ VariantList *varLstNewStrLst(const StringList *stringList);
|
|||||||
VariantList *varLstDup(const VariantList *source);
|
VariantList *varLstDup(const VariantList *source);
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Functions
|
Getters/Setters
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
// Add to list
|
|
||||||
VariantList *varLstAdd(VariantList *this, Variant *data);
|
|
||||||
|
|
||||||
// Get by index
|
|
||||||
Variant *varLstGet(const VariantList *this, unsigned int listIdx);
|
|
||||||
|
|
||||||
// Move to new parent mem context
|
|
||||||
VariantList *varLstMove(VariantList *this, MemContext *parentNew);
|
|
||||||
|
|
||||||
// List size
|
// List size
|
||||||
unsigned int varLstSize(const VariantList *this);
|
__attribute__((always_inline)) static inline unsigned int
|
||||||
|
varLstSize(const VariantList *this)
|
||||||
|
{
|
||||||
|
return lstSize((List *)this);
|
||||||
|
}
|
||||||
|
|
||||||
// Is the list empty?
|
// Is the list empty?
|
||||||
__attribute__((always_inline)) static inline bool
|
__attribute__((always_inline)) static inline bool
|
||||||
@ -45,10 +45,39 @@ varLstEmpty(const VariantList *this)
|
|||||||
return varLstSize(this) == 0;
|
return varLstSize(this) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
// Add to list
|
||||||
|
__attribute__((always_inline)) static inline VariantList *
|
||||||
|
varLstAdd(VariantList *this, Variant *data)
|
||||||
|
{
|
||||||
|
lstAdd((List *)this, &data);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get by index
|
||||||
|
__attribute__((always_inline)) static inline Variant *
|
||||||
|
varLstGet(const VariantList *this, const unsigned int listIdx)
|
||||||
|
{
|
||||||
|
return *(Variant **)lstGet((List *)this, listIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to new parent mem context
|
||||||
|
__attribute__((always_inline)) static inline VariantList *
|
||||||
|
varLstMove(VariantList *this, MemContext *parentNew)
|
||||||
|
{
|
||||||
|
return (VariantList *)lstMove((List *)this, parentNew);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Destructor
|
Destructor
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
void varLstFree(VariantList *this);
|
__attribute__((always_inline)) static inline void
|
||||||
|
varLstFree(VariantList *this)
|
||||||
|
{
|
||||||
|
lstFree((List *)this);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Macros for function logging
|
Macros for function logging
|
||||||
|
@ -122,7 +122,7 @@ unit:
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
- name: type-string
|
- name: type-string
|
||||||
total: 26
|
total: 25
|
||||||
feature: string
|
feature: string
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
@ -730,7 +730,7 @@ unit:
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
- name: help
|
- name: help
|
||||||
total: 4
|
total: 5
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
- command/help/help
|
- command/help/help
|
||||||
|
@ -72,7 +72,7 @@ harnessCfgLoadRole(ConfigCommand commandId, ConfigCommandRole commandRoleId, con
|
|||||||
|
|
||||||
// Set job retry to 0 if it is valid
|
// Set job retry to 0 if it is valid
|
||||||
if (cfgParseOptionValid(commandId, commandRoleId, cfgOptJobRetry))
|
if (cfgParseOptionValid(commandId, commandRoleId, cfgOptJobRetry))
|
||||||
strLstInsertZ(argList, 0, "--" CFGOPT_JOB_RETRY "=0");
|
strLstInsert(argList, 0, STRDEF("--" CFGOPT_JOB_RETRY "=0"));
|
||||||
|
|
||||||
// Set log path if valid
|
// Set log path if valid
|
||||||
if (cfgParseOptionValid(commandId, commandRoleId, cfgOptLogPath))
|
if (cfgParseOptionValid(commandId, commandRoleId, cfgOptLogPath))
|
||||||
|
@ -192,7 +192,8 @@ testRun(void)
|
|||||||
|
|
||||||
TEST_RESULT_VOID(expireBackup(infoBackup, full1, 0), "expire backup with both manifest files");
|
TEST_RESULT_VOID(expireBackup(infoBackup, full1, 0), "expire backup with both manifest files");
|
||||||
TEST_RESULT_BOOL(
|
TEST_RESULT_BOOL(
|
||||||
(strLstSize(storageListP(storageTest, full1Path)) && strLstExistsZ(storageListP(storageTest, full1Path), "bogus")),
|
(strLstSize(storageListP(storageTest, full1Path)) &&
|
||||||
|
strLstExists(storageListP(storageTest, full1Path), STRDEF("bogus"))),
|
||||||
true, "full1 - only manifest files removed");
|
true, "full1 - only manifest files removed");
|
||||||
|
|
||||||
TEST_RESULT_VOID(expireBackup(infoBackup, full2, 0), "expire backup with no manifest - does not error");
|
TEST_RESULT_VOID(expireBackup(infoBackup, full2, 0), "expire backup with no manifest - does not error");
|
||||||
|
@ -47,6 +47,23 @@ testRun(void)
|
|||||||
"Use 'pgbackrest help [command]' for more information.\n",
|
"Use 'pgbackrest help [command]' for more information.\n",
|
||||||
helpVersion));
|
helpVersion));
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("helpRenderSplitSize()"))
|
||||||
|
{
|
||||||
|
TEST_RESULT_STR_Z(strLstJoin(helpRenderSplitSize(STRDEF("abc def"), " ", 3), "-"), "abc-def", "two items");
|
||||||
|
TEST_RESULT_STR_Z(strLstJoin(helpRenderSplitSize(STRDEF("abc def"), " ", 4), "-"), "abc-def", "one items");
|
||||||
|
TEST_RESULT_STR_Z(strLstJoin(helpRenderSplitSize(STRDEF("abc def ghi"), " ", 4), "-"), "abc-def-ghi", "three items");
|
||||||
|
TEST_RESULT_STR_Z(strLstJoin(helpRenderSplitSize(STRDEF("abc def ghi"), " ", 8), "-"), "abc def-ghi", "three items");
|
||||||
|
TEST_RESULT_STR_Z(strLstJoin(helpRenderSplitSize(STRDEF("abc def "), " ", 4), "-"), "abc-def ", "two items");
|
||||||
|
|
||||||
|
TEST_RESULT_STR_Z(
|
||||||
|
strLstJoin(helpRenderSplitSize(STRDEF("this is a short sentence"), " ", 10), "\n"),
|
||||||
|
"this is a\n"
|
||||||
|
"short\n"
|
||||||
|
"sentence",
|
||||||
|
"empty list");
|
||||||
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("helpRenderText()"))
|
if (testBegin("helpRenderText()"))
|
||||||
{
|
{
|
||||||
|
@ -35,7 +35,7 @@ testRun(void)
|
|||||||
List *list = lstNewP(sizeof(void *));
|
List *list = lstNewP(sizeof(void *));
|
||||||
|
|
||||||
TEST_RESULT_UINT(list->itemSize, sizeof(void *), "item size");
|
TEST_RESULT_UINT(list->itemSize, sizeof(void *), "item size");
|
||||||
TEST_RESULT_UINT(list->listSize, 0, "list size");
|
TEST_RESULT_UINT(list->pub.listSize, 0, "list size");
|
||||||
TEST_RESULT_UINT(list->listSizeMax, 0, "list size max");
|
TEST_RESULT_UINT(list->listSizeMax, 0, "list size max");
|
||||||
TEST_RESULT_PTR(lstMemContext(list), list->memContext, "list mem context");
|
TEST_RESULT_PTR(lstMemContext(list), list->memContext, "list mem context");
|
||||||
TEST_RESULT_VOID(lstClear(list), "clear list");
|
TEST_RESULT_VOID(lstClear(list), "clear list");
|
||||||
@ -130,7 +130,7 @@ testRun(void)
|
|||||||
TEST_RESULT_VOID(lstAdd(list, &item), "add item %d", item);
|
TEST_RESULT_VOID(lstAdd(list, &item), "add item %d", item);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_RESULT_INT(list->listSize, list->listSizeMax, "size equals max size");
|
TEST_RESULT_UINT(lstSize(list), list->listSizeMax, "size equals max size");
|
||||||
|
|
||||||
// Remove last item
|
// Remove last item
|
||||||
TEST_RESULT_VOID(lstRemoveLast(list), "remove last item");
|
TEST_RESULT_VOID(lstRemoveLast(list), "remove last item");
|
||||||
|
@ -341,8 +341,8 @@ testRun(void)
|
|||||||
TEST_ASSIGN(list, strLstNew(), "new list");
|
TEST_ASSIGN(list, strLstNew(), "new list");
|
||||||
TEST_RESULT_VOID(strLstAddIfMissing(list, STRDEF("item1")), "add item 1");
|
TEST_RESULT_VOID(strLstAddIfMissing(list, STRDEF("item1")), "add item 1");
|
||||||
TEST_RESULT_UINT(strLstSize(list), 1, "check size");
|
TEST_RESULT_UINT(strLstSize(list), 1, "check size");
|
||||||
TEST_RESULT_BOOL(strLstExistsZ(list, "item1"), true, "check exists");
|
TEST_RESULT_BOOL(strLstExists(list, STRDEF("item1")), true, "check exists");
|
||||||
TEST_RESULT_BOOL(strLstExistsZ(list, NULL), false, "check null exists");
|
TEST_RESULT_BOOL(strLstExists(list, NULL), false, "check null exists");
|
||||||
TEST_RESULT_VOID(strLstAddIfMissing(list, STRDEF("item1")), "add item 1 again");
|
TEST_RESULT_VOID(strLstAddIfMissing(list, STRDEF("item1")), "add item 1 again");
|
||||||
TEST_RESULT_UINT(strLstSize(list), 1, "check size");
|
TEST_RESULT_UINT(strLstSize(list), 1, "check size");
|
||||||
TEST_RESULT_BOOL(strLstEmpty(list), false, " not empty");
|
TEST_RESULT_BOOL(strLstEmpty(list), false, " not empty");
|
||||||
@ -361,24 +361,6 @@ testRun(void)
|
|||||||
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplit(STRDEF("item1, item2"), STRDEF(", ")), ", "), "item1, item2", "two items");
|
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplit(STRDEF("item1, item2"), STRDEF(", ")), ", "), "item1, item2", "two items");
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
|
||||||
if (testBegin("strLstNewSplitSize()"))
|
|
||||||
{
|
|
||||||
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplitSize(STRDEF(""), STRDEF(" "), 0), ", "), "", "empty list");
|
|
||||||
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplitSizeZ(STRDEF("abc def"), " ", 3), "-"), "abc-def", "two items");
|
|
||||||
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplitSizeZ(STRDEF("abc def"), " ", 4), "-"), "abc-def", "one items");
|
|
||||||
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplitSizeZ(STRDEF("abc def ghi"), " ", 4), "-"), "abc-def-ghi", "three items");
|
|
||||||
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplitSizeZ(STRDEF("abc def ghi"), " ", 8), "-"), "abc def-ghi", "three items");
|
|
||||||
TEST_RESULT_STR_Z(strLstJoin(strLstNewSplitSizeZ(STRDEF("abc def "), " ", 4), "-"), "abc-def ", "two items");
|
|
||||||
|
|
||||||
TEST_RESULT_STR_Z(
|
|
||||||
strLstJoin(strLstNewSplitSize(STRDEF("this is a short sentence"), STRDEF(" "), 10), "\n"),
|
|
||||||
"this is a\n"
|
|
||||||
"short\n"
|
|
||||||
"sentence",
|
|
||||||
"empty list");
|
|
||||||
}
|
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("strLstNewVarLst()"))
|
if (testBegin("strLstNewVarLst()"))
|
||||||
{
|
{
|
||||||
@ -430,7 +412,7 @@ testRun(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("strLstExists() and strLstExistsZ()"))
|
if (testBegin("strLstExists()"))
|
||||||
{
|
{
|
||||||
StringList *list = strLstNew();
|
StringList *list = strLstNew();
|
||||||
strLstAddZ(list, "A");
|
strLstAddZ(list, "A");
|
||||||
@ -438,8 +420,6 @@ testRun(void)
|
|||||||
|
|
||||||
TEST_RESULT_BOOL(strLstExists(list, STRDEF("B")), false, "string does not exist");
|
TEST_RESULT_BOOL(strLstExists(list, STRDEF("B")), false, "string does not exist");
|
||||||
TEST_RESULT_BOOL(strLstExists(list, STRDEF("C")), true, "string exists");
|
TEST_RESULT_BOOL(strLstExists(list, STRDEF("C")), true, "string exists");
|
||||||
TEST_RESULT_BOOL(strLstExistsZ(list, "B"), false, "string does not exist");
|
|
||||||
TEST_RESULT_BOOL(strLstExistsZ(list, "C"), true, "string exists");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
@ -531,11 +511,11 @@ testRun(void)
|
|||||||
|
|
||||||
TEST_RESULT_STR_Z(strLstToLog(list), "{[]}", "format empty list");
|
TEST_RESULT_STR_Z(strLstToLog(list), "{[]}", "format empty list");
|
||||||
|
|
||||||
strLstInsertZ(list, 0, "item3");
|
strLstInsert(list, 0, STRDEF("item3"));
|
||||||
TEST_RESULT_STR_Z(strLstToLog(list), "{[\"item3\"]}", "format 1 item list");
|
TEST_RESULT_STR_Z(strLstToLog(list), "{[\"item3\"]}", "format 1 item list");
|
||||||
|
|
||||||
strLstInsert(list, 0, STRDEF("item1"));
|
strLstInsert(list, 0, STRDEF("item1"));
|
||||||
strLstInsertZ(list, 1, "item2");
|
strLstInsert(list, 1, STRDEF("item2"));
|
||||||
TEST_RESULT_STR_Z(strLstToLog(list), "{[\"item1\", \"item2\", \"item3\"]}", "format 3 item list");
|
TEST_RESULT_STR_Z(strLstToLog(list), "{[\"item1\", \"item2\", \"item3\"]}", "format 3 item list");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +174,9 @@ testRun(void)
|
|||||||
TEST_RESULT_UINT(backupDataPtr->backupInfoSizeDelta, 163866, " backup delta");
|
TEST_RESULT_UINT(backupDataPtr->backupInfoSizeDelta, 163866, " backup delta");
|
||||||
TEST_RESULT_STR_Z(backupDataPtr->backupPrior, "20161219-212741F", " backup prior exists");
|
TEST_RESULT_STR_Z(backupDataPtr->backupPrior, "20161219-212741F", " backup prior exists");
|
||||||
TEST_RESULT_BOOL(
|
TEST_RESULT_BOOL(
|
||||||
(strLstSize(backupDataPtr->backupReference) == 1 && strLstExistsZ(backupDataPtr->backupReference, "20161219-212741F")), true,
|
(strLstSize(backupDataPtr->backupReference) == 1 &&
|
||||||
" backup reference exists");
|
strLstExists(backupDataPtr->backupReference, STRDEF("20161219-212741F"))),
|
||||||
|
true, " backup reference exists");
|
||||||
TEST_RESULT_PTR(infoBackupDataByLabel(infoBackup, STRDEF("20161219-12345")), NULL, " backup label does not exist");
|
TEST_RESULT_PTR(infoBackupDataByLabel(infoBackup, STRDEF("20161219-12345")), NULL, " backup label does not exist");
|
||||||
|
|
||||||
backupData = infoBackupData(infoBackup, 2);
|
backupData = infoBackupData(infoBackup, 2);
|
||||||
@ -185,8 +186,9 @@ testRun(void)
|
|||||||
TEST_RESULT_STR_Z(backupData.backupType, "incr", " backup type incr");
|
TEST_RESULT_STR_Z(backupData.backupType, "incr", " backup type incr");
|
||||||
TEST_RESULT_STR_Z(backupData.backupPrior, "20161219-212741F", " backup prior exists");
|
TEST_RESULT_STR_Z(backupData.backupPrior, "20161219-212741F", " backup prior exists");
|
||||||
TEST_RESULT_BOOL(
|
TEST_RESULT_BOOL(
|
||||||
(strLstSize(backupData.backupReference) == 2 && strLstExistsZ(backupData.backupReference, "20161219-212741F") &&
|
(strLstSize(backupData.backupReference) == 2 && strLstExists(backupData.backupReference, STRDEF("20161219-212741F")) &&
|
||||||
strLstExistsZ(backupData.backupReference, "20161219-212741F_20161219-212803D")), true, " backup reference exists");
|
strLstExists(backupData.backupReference, STRDEF("20161219-212741F_20161219-212803D"))),
|
||||||
|
true, " backup reference exists");
|
||||||
TEST_RESULT_BOOL(backupData.optionArchiveCheck, true, " option archive check");
|
TEST_RESULT_BOOL(backupData.optionArchiveCheck, true, " option archive check");
|
||||||
TEST_RESULT_BOOL(backupData.optionArchiveCopy, false, " option archive copy");
|
TEST_RESULT_BOOL(backupData.optionArchiveCopy, false, " option archive copy");
|
||||||
TEST_RESULT_BOOL(backupData.optionBackupStandby, false, " option backup standby");
|
TEST_RESULT_BOOL(backupData.optionBackupStandby, false, " option backup standby");
|
||||||
|
Loading…
Reference in New Issue
Block a user