mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 07:04:28 +00:00
lib: Add a function to split a string into substrings
Some environment variables provide a space-separated list of strings. It is easier to process these when they are broken out into an array of strings. Add a utility function to handle this. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
a0fb9de60d
commit
3e96ed44e8
3 changed files with 147 additions and 0 deletions
|
@ -328,6 +328,30 @@ char *strmhz(char *buf, unsigned long hz);
|
|||
*/
|
||||
void str_to_upper(const char *in, char *out, size_t len);
|
||||
|
||||
/**
|
||||
* str_to_list() - Convert a string to a list of string pointers
|
||||
*
|
||||
* Splits a string containing space-delimited substrings into a number of
|
||||
* separate strings, e.g. "this is" becomes {"this", "is", NULL}. If @instr is
|
||||
* empty then this returns just {NULL}. The string should have only a single
|
||||
* space between items, with no leading or trailing spaces.
|
||||
*
|
||||
* @instr: String to process (this is alloced by this function)
|
||||
* Returns: List of string pointers, terminated by NULL. Each entry points to
|
||||
* a string. If @instr is empty, the list consists just of a single NULL entry.
|
||||
* Note that the first entry points to the alloced string.
|
||||
* Returns NULL if out of memory
|
||||
*/
|
||||
const char **str_to_list(const char *instr);
|
||||
|
||||
/**
|
||||
* str_free_list() - Free a string list
|
||||
*
|
||||
* @ptr: String list to free, as created by str_to_list(). This can also be
|
||||
* NULL, in which case the function does nothing
|
||||
*/
|
||||
void str_free_list(const char **ptr);
|
||||
|
||||
/**
|
||||
* vsscanf - Unformat a buffer into a list of arguments
|
||||
* @inp: input buffer
|
||||
|
|
41
lib/strto.c
41
lib/strto.c
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
/* from lib/kstrtox.c */
|
||||
|
@ -222,3 +223,43 @@ void str_to_upper(const char *in, char *out, size_t len)
|
|||
if (len)
|
||||
*out = '\0';
|
||||
}
|
||||
|
||||
const char **str_to_list(const char *instr)
|
||||
{
|
||||
const char **ptr;
|
||||
char *str, *p;
|
||||
int count, i;
|
||||
|
||||
/* don't allocate if the string is empty */
|
||||
str = *instr ? strdup(instr) : (char *)instr;
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
/* count the number of space-separated strings */
|
||||
for (count = *str != '\0', p = str; *p; p++) {
|
||||
if (*p == ' ') {
|
||||
count++;
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate the pointer array, allowing for a NULL terminator */
|
||||
ptr = calloc(count + 1, sizeof(char *));
|
||||
if (!ptr) {
|
||||
if (*str)
|
||||
free(str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0, p = str; i < count; p += strlen(p) + 1, i++)
|
||||
ptr[i] = p;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void str_free_list(const char **ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free((char *)ptr[0]);
|
||||
free(ptr);
|
||||
}
|
||||
|
|
|
@ -274,6 +274,88 @@ static int str_trailing(struct unit_test_state *uts)
|
|||
}
|
||||
STR_TEST(str_trailing, 0);
|
||||
|
||||
static int test_str_to_list(struct unit_test_state *uts)
|
||||
{
|
||||
const char **ptr;
|
||||
ulong start;
|
||||
|
||||
/* check out of memory */
|
||||
start = ut_check_delta(0);
|
||||
malloc_enable_testing(0);
|
||||
ut_assertnull(str_to_list(""));
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
ut_assertnull(str_to_list("this is a test"));
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
malloc_enable_testing(1);
|
||||
ut_assertnull(str_to_list("this is a test"));
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
/* for an empty string, only one nalloc is needed */
|
||||
malloc_enable_testing(1);
|
||||
ptr = str_to_list("");
|
||||
ut_assertnonnull(ptr);
|
||||
ut_assertnull(ptr[0]);
|
||||
str_free_list(ptr);
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
malloc_disable_testing();
|
||||
|
||||
/* test the same again, without any nalloc restrictions */
|
||||
ptr = str_to_list("");
|
||||
ut_assertnonnull(ptr);
|
||||
ut_assertnull(ptr[0]);
|
||||
str_free_list(ptr);
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
/* test a single string */
|
||||
start = ut_check_delta(0);
|
||||
ptr = str_to_list("hi");
|
||||
ut_assertnonnull(ptr);
|
||||
ut_assertnonnull(ptr[0]);
|
||||
ut_asserteq_str("hi", ptr[0]);
|
||||
ut_assertnull(ptr[1]);
|
||||
str_free_list(ptr);
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
/* test two strings */
|
||||
ptr = str_to_list("hi there");
|
||||
ut_assertnonnull(ptr);
|
||||
ut_assertnonnull(ptr[0]);
|
||||
ut_asserteq_str("hi", ptr[0]);
|
||||
ut_assertnonnull(ptr[1]);
|
||||
ut_asserteq_str("there", ptr[1]);
|
||||
ut_assertnull(ptr[2]);
|
||||
str_free_list(ptr);
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
/* test leading, trailing and multiple spaces */
|
||||
ptr = str_to_list(" more space ");
|
||||
ut_assertnonnull(ptr);
|
||||
ut_assertnonnull(ptr[0]);
|
||||
ut_asserteq_str("", ptr[0]);
|
||||
ut_assertnonnull(ptr[1]);
|
||||
ut_asserteq_str("more", ptr[1]);
|
||||
ut_assertnonnull(ptr[2]);
|
||||
ut_asserteq_str("", ptr[2]);
|
||||
ut_assertnonnull(ptr[3]);
|
||||
ut_asserteq_str("space", ptr[3]);
|
||||
ut_assertnonnull(ptr[4]);
|
||||
ut_asserteq_str("", ptr[4]);
|
||||
ut_assertnonnull(ptr[5]);
|
||||
ut_asserteq_str("", ptr[5]);
|
||||
ut_assertnull(ptr[6]);
|
||||
str_free_list(ptr);
|
||||
ut_assertok(ut_check_delta(start));
|
||||
|
||||
/* test freeing a NULL pointer */
|
||||
str_free_list(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
STR_TEST(test_str_to_list, 0);
|
||||
|
||||
int do_ut_str(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
struct unit_test *tests = UNIT_TEST_SUITE_START(str_test);
|
||||
|
|
Loading…
Reference in a new issue