util: Add spdk_strcpy_replace() to replace substrings
spdk_nvme_cpl_get_status_string() returns a string which contains upper cases, spaces, and hyphens. To use the returned string for JSON RPC, we have to convert it to a string which contains only lowercases and underscores. For our convenience, add a new API spdk_strcpy_replace() to replace all occurrences of the search string with the replacement string. Signed-off-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Change-Id: I3ca9774d0bfb2d0bb7bd7412bc671e6f69104b7d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16054 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
60fd5c554d
commit
d6e57b5389
@ -85,6 +85,9 @@ available trace point groups and mask of the available trace points for each gro
|
||||
New API `spdk_fd_group_get_epoll_event` that returns the epoll(7) event that
|
||||
caused a function callback in file descriptor group to execute.
|
||||
|
||||
A new API `spdk_strcpy_replace` was added to replace all occurrences of the search string
|
||||
with the replacement string.
|
||||
|
||||
### json
|
||||
|
||||
Added API `spdk_json_write_double` and `spdk_json_write_named_double` to allow
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright (C) 2015 Intel Corporation.
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
@ -265,6 +266,22 @@ char **spdk_strarray_dup(const char **strarray);
|
||||
*/
|
||||
void spdk_strarray_free(char **strarray);
|
||||
|
||||
/**
|
||||
* Copy a string into a fixed-size buffer with all occurrences of the search string
|
||||
* replaced with the given replace substring. The fixed-size buffer must not be less
|
||||
* than the string with the replaced values including the terminating null byte.
|
||||
*
|
||||
* \param dst Pointer to destination fixed-size buffer to fill.
|
||||
* \param size Size of the destination fixed-size buffer in bytes.
|
||||
* \param src Pointer to source null-terminated string to copy into dst.
|
||||
* \param search The string being searched for.
|
||||
* \param replace the replacement substring the replaces the found search substring.
|
||||
*
|
||||
* \return 0 on success, or negated errno on failure.
|
||||
*/
|
||||
int spdk_strcpy_replace(char *dst, size_t size, const char *src, const char *search,
|
||||
const char *replace);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -126,6 +126,7 @@
|
||||
spdk_strarray_from_string;
|
||||
spdk_strarray_dup;
|
||||
spdk_strarray_free;
|
||||
spdk_strcpy_replace;
|
||||
|
||||
# public functions in util.h
|
||||
spdk_u32log2;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright (C) 2015 Intel Corporation.
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
@ -542,3 +543,49 @@ spdk_strarray_dup(const char **strarray)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_strcpy_replace(char *dst, size_t size, const char *src, const char *search,
|
||||
const char *replace)
|
||||
{
|
||||
const char *p, *q;
|
||||
char *r;
|
||||
size_t c, search_size, replace_size, dst_size;
|
||||
|
||||
if (dst == NULL || src == NULL || search == NULL || replace == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
search_size = strlen(search);
|
||||
replace_size = strlen(replace);
|
||||
|
||||
c = 0;
|
||||
for (p = strstr(src, search); p != NULL; p = strstr(p + search_size, search)) {
|
||||
c++;
|
||||
}
|
||||
|
||||
dst_size = strlen(src) + (replace_size - search_size) * c;
|
||||
if (dst_size >= size) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
q = src;
|
||||
r = dst;
|
||||
|
||||
for (p = strstr(src, search); p != NULL; p = strstr(p + search_size, search)) {
|
||||
memcpy(r, q, p - q);
|
||||
r += p - q;
|
||||
|
||||
memcpy(r, replace, replace_size);
|
||||
r += replace_size;
|
||||
|
||||
q = p + search_size;
|
||||
}
|
||||
|
||||
memcpy(r, q, strlen(q));
|
||||
r += strlen(q);
|
||||
|
||||
*r = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright (C) 2017 Intel Corporation.
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
@ -436,6 +437,72 @@ test_strarray(void)
|
||||
spdk_strarray_free(r2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_strcpy_replace(void)
|
||||
{
|
||||
const char *original = "good morning, hello, thank you";
|
||||
const char *search1 = "evening";
|
||||
const char *replace1 = "unexpected";
|
||||
const char *search2 = "morning";
|
||||
const char *replace2 = "afternoon";
|
||||
const char *expected2 = "good afternoon, hello, thank you";
|
||||
const char *search3 = "morning";
|
||||
const char *replace3 = "night";
|
||||
const char *expected3 = "good night, hello, thank you";
|
||||
const char *search4 = "hello";
|
||||
const char *replace4 = "good bye";
|
||||
const char *expected4 = "good morning, good bye, thank you";
|
||||
const char *search5 = "thank you";
|
||||
const char *replace5 = "you are welcome";
|
||||
const char *expected5 = "good morning, hello, you are welcome";
|
||||
const char *search6 = " ";
|
||||
const char *replace6 = "-";
|
||||
const char *expected6 = "good-morning,-hello,-thank-you";
|
||||
const char *search7 = ",";
|
||||
const char *replace7 = ".";
|
||||
const char *expected7 = "good morning. hello. thank you";
|
||||
char result[256];
|
||||
int rc;
|
||||
|
||||
rc = spdk_strcpy_replace(NULL, 0, NULL, NULL, NULL);
|
||||
CU_ASSERT(rc == -EINVAL);
|
||||
|
||||
rc = spdk_strcpy_replace(result, sizeof(result), original, search1, replace1);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(strcmp(result, original) == 0);
|
||||
|
||||
rc = spdk_strcpy_replace(result, sizeof(result), original, search2, replace2);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(strcmp(result, expected2) == 0);
|
||||
|
||||
/* A case that sizeof(replace) is less than sizeof(search), and the result array is
|
||||
* smaller than the original string. */
|
||||
rc = spdk_strcpy_replace(result, strlen(expected3) + 1, original, search3, replace3);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(strcmp(result, expected3) == 0);
|
||||
|
||||
/* An error case that the result array is smaller than the string with replaced values
|
||||
* and a terminated null byte. */
|
||||
rc = spdk_strcpy_replace(result, strlen(expected3), original, search3, replace3);
|
||||
CU_ASSERT(rc == -EINVAL);
|
||||
|
||||
rc = spdk_strcpy_replace(result, sizeof(result), original, search4, replace4);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(strcmp(result, expected4) == 0);
|
||||
|
||||
rc = spdk_strcpy_replace(result, sizeof(result), original, search5, replace5);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(strcmp(result, expected5) == 0);
|
||||
|
||||
rc = spdk_strcpy_replace(result, sizeof(result), original, search6, replace6);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(strcmp(result, expected6) == 0);
|
||||
|
||||
rc = spdk_strcpy_replace(result, sizeof(result), original, search7, replace7);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(strcmp(result, expected7) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -454,6 +521,7 @@ main(int argc, char **argv)
|
||||
CU_ADD_TEST(suite, test_strtol);
|
||||
CU_ADD_TEST(suite, test_strtoll);
|
||||
CU_ADD_TEST(suite, test_strarray);
|
||||
CU_ADD_TEST(suite, test_strcpy_replace);
|
||||
|
||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user