lib/util: add strarray utility functions
Add some basic utilities for handling arrays of strings. Signed-off-by: John Levon <john.levon@nutanix.com> Change-Id: I2333f3e4605175b1717a7f289847ff2d48745e8d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15274 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
c3e62d7729
commit
1139cb1415
@ -236,6 +236,35 @@ long int spdk_strtol(const char *nptr, int base);
|
||||
*/
|
||||
long long int spdk_strtoll(const char *nptr, int base);
|
||||
|
||||
/**
|
||||
* Build a NULL-terminated array of strings from the given string separated by
|
||||
* the given chars in delim, as if split by strpbrk(). Empty items are pointers
|
||||
* to an empty string.
|
||||
*
|
||||
* \param str Input string
|
||||
* \param delim Separating delimiter set.
|
||||
*
|
||||
* \return the string array, or NULL on failure.
|
||||
*/
|
||||
char **spdk_strarray_from_string(const char *str, const char *delim);
|
||||
|
||||
/**
|
||||
* Duplicate a NULL-terminated array of strings. Returns NULL on failure.
|
||||
* The array, and the strings, are allocated with the standard allocator (e.g.
|
||||
* calloc()).
|
||||
*
|
||||
* \param strarray input array of strings.
|
||||
*/
|
||||
char **spdk_strarray_dup(const char **strarray);
|
||||
|
||||
/**
|
||||
* Free a NULL-terminated array of strings. The array and its strings must have
|
||||
* been allocated with the standard allocator (calloc() etc.).
|
||||
*
|
||||
* \param strarray array of strings.
|
||||
*/
|
||||
void spdk_strarray_free(char **strarray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
|
||||
SO_VER := 5
|
||||
SO_MINOR := 1
|
||||
SO_MINOR := 2
|
||||
|
||||
C_SRCS = base64.c bit_array.c cpuset.c crc16.c crc32.c crc32c.c crc32_ieee.c \
|
||||
dif.c fd.c file.c hexlify.c iov.c math.c pipe.c strerror_tls.c string.c uuid.c \
|
||||
|
@ -123,6 +123,9 @@
|
||||
spdk_mem_all_zero;
|
||||
spdk_strtol;
|
||||
spdk_strtoll;
|
||||
spdk_strarray_from_string;
|
||||
spdk_strarray_dup;
|
||||
spdk_strarray_free;
|
||||
|
||||
# public functions in util.h
|
||||
spdk_u32log2;
|
||||
|
@ -446,3 +446,99 @@ spdk_strtoll(const char *nptr, int base)
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_strarray_free(char **strarray)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (strarray == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; strarray[i] != NULL; i++) {
|
||||
free(strarray[i]);
|
||||
}
|
||||
free(strarray);
|
||||
}
|
||||
|
||||
char **
|
||||
spdk_strarray_from_string(const char *str, const char *delim)
|
||||
{
|
||||
const char *c = str;
|
||||
size_t count = 0;
|
||||
char **result;
|
||||
size_t i;
|
||||
|
||||
assert(str != NULL);
|
||||
assert(delim != NULL);
|
||||
|
||||
/* Count number of entries. */
|
||||
for (;;) {
|
||||
const char *next = strpbrk(c, delim);
|
||||
|
||||
count++;
|
||||
|
||||
if (next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
c = next + 1;
|
||||
}
|
||||
|
||||
/* Account for the terminating NULL entry. */
|
||||
result = calloc(count + 1, sizeof(char *));
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c = str;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const char *next = strpbrk(c, delim);
|
||||
|
||||
if (next == NULL) {
|
||||
result[i] = strdup(c);
|
||||
} else {
|
||||
result[i] = strndup(c, next - c);
|
||||
}
|
||||
|
||||
if (result[i] == NULL) {
|
||||
spdk_strarray_free(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (next != NULL) {
|
||||
c = next + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char **
|
||||
spdk_strarray_dup(const char **strarray)
|
||||
{
|
||||
size_t count, i;
|
||||
char **result;
|
||||
|
||||
assert(strarray != NULL);
|
||||
|
||||
for (count = 0; strarray[count] != NULL; count++)
|
||||
;
|
||||
|
||||
result = calloc(count + 1, sizeof(char *));
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
result[i] = strdup(strarray[i]);
|
||||
if (result[i] == NULL) {
|
||||
spdk_strarray_free(result);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -375,6 +375,67 @@ test_strtoll(void)
|
||||
CU_ASSERT(val == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_strarray(void)
|
||||
{
|
||||
char **r;
|
||||
char **r2;
|
||||
|
||||
r = spdk_strarray_from_string("", ":");
|
||||
CU_ASSERT(strcmp(r[0], "") == 0);
|
||||
CU_ASSERT(r[1] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
|
||||
r = spdk_strarray_from_string(":", ":");
|
||||
CU_ASSERT(strcmp(r[0], "") == 0);
|
||||
CU_ASSERT(strcmp(r[1], "") == 0);
|
||||
CU_ASSERT(r[2] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
|
||||
r = spdk_strarray_from_string("a", ":");
|
||||
CU_ASSERT(strcmp(r[0], "a") == 0);
|
||||
CU_ASSERT(r[1] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
|
||||
r = spdk_strarray_from_string("ab:", ":");
|
||||
CU_ASSERT(strcmp(r[0], "ab") == 0);
|
||||
CU_ASSERT(strcmp(r[1], "") == 0);
|
||||
CU_ASSERT(r[2] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
|
||||
r = spdk_strarray_from_string(":ab", ":");
|
||||
CU_ASSERT(strcmp(r[0], "") == 0);
|
||||
CU_ASSERT(strcmp(r[1], "ab") == 0);
|
||||
CU_ASSERT(r[2] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
|
||||
r = spdk_strarray_from_string("ab:c", ":");
|
||||
CU_ASSERT(strcmp(r[0], "ab") == 0);
|
||||
CU_ASSERT(strcmp(r[1], "c") == 0);
|
||||
CU_ASSERT(r[2] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
|
||||
r = spdk_strarray_from_string(":ab.:c:", ":.");
|
||||
CU_ASSERT(strcmp(r[0], "") == 0);
|
||||
CU_ASSERT(strcmp(r[1], "ab") == 0);
|
||||
CU_ASSERT(strcmp(r[2], "") == 0);
|
||||
CU_ASSERT(strcmp(r[3], "c") == 0);
|
||||
CU_ASSERT(strcmp(r[4], "") == 0);
|
||||
CU_ASSERT(r[5] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
|
||||
r = spdk_strarray_from_string(":ab.:c:", ":.");
|
||||
r2 = spdk_strarray_dup((const char **)r);
|
||||
CU_ASSERT(strcmp(r2[0], "") == 0);
|
||||
CU_ASSERT(strcmp(r2[1], "ab") == 0);
|
||||
CU_ASSERT(strcmp(r2[2], "") == 0);
|
||||
CU_ASSERT(strcmp(r2[3], "c") == 0);
|
||||
CU_ASSERT(strcmp(r2[4], "") == 0);
|
||||
CU_ASSERT(r2[5] == NULL);
|
||||
spdk_strarray_free(r);
|
||||
spdk_strarray_free(r2);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -392,6 +453,7 @@ main(int argc, char **argv)
|
||||
CU_ADD_TEST(suite, test_sprintf_append_realloc);
|
||||
CU_ADD_TEST(suite, test_strtol);
|
||||
CU_ADD_TEST(suite, test_strtoll);
|
||||
CU_ADD_TEST(suite, test_strarray);
|
||||
|
||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user