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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
|||||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
SO_VER := 5
|
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 \
|
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 \
|
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_mem_all_zero;
|
||||||
spdk_strtol;
|
spdk_strtol;
|
||||||
spdk_strtoll;
|
spdk_strtoll;
|
||||||
|
spdk_strarray_from_string;
|
||||||
|
spdk_strarray_dup;
|
||||||
|
spdk_strarray_free;
|
||||||
|
|
||||||
# public functions in util.h
|
# public functions in util.h
|
||||||
spdk_u32log2;
|
spdk_u32log2;
|
||||||
|
@ -446,3 +446,99 @@ spdk_strtoll(const char *nptr, int base)
|
|||||||
|
|
||||||
return val;
|
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);
|
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
|
int
|
||||||
main(int argc, char **argv)
|
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_sprintf_append_realloc);
|
||||||
CU_ADD_TEST(suite, test_strtol);
|
CU_ADD_TEST(suite, test_strtol);
|
||||||
CU_ADD_TEST(suite, test_strtoll);
|
CU_ADD_TEST(suite, test_strtoll);
|
||||||
|
CU_ADD_TEST(suite, test_strarray);
|
||||||
|
|
||||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user