forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
1.7 KiB
100 lines
1.7 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
/* |
|
* Helper function for splitting a string into an argv-like array. |
|
*/ |
|
|
|
#include <stdlib.h> |
|
#include <linux/kernel.h> |
|
#include <linux/ctype.h> |
|
#include <linux/string.h> |
|
|
|
static const char *skip_arg(const char *cp) |
|
{ |
|
while (*cp && !isspace(*cp)) |
|
cp++; |
|
|
|
return cp; |
|
} |
|
|
|
static int count_argc(const char *str) |
|
{ |
|
int count = 0; |
|
|
|
while (*str) { |
|
str = skip_spaces(str); |
|
if (*str) { |
|
count++; |
|
str = skip_arg(str); |
|
} |
|
} |
|
|
|
return count; |
|
} |
|
|
|
/** |
|
* argv_free - free an argv |
|
* @argv - the argument vector to be freed |
|
* |
|
* Frees an argv and the strings it points to. |
|
*/ |
|
void argv_free(char **argv) |
|
{ |
|
char **p; |
|
for (p = argv; *p; p++) { |
|
free(*p); |
|
*p = NULL; |
|
} |
|
|
|
free(argv); |
|
} |
|
|
|
/** |
|
* argv_split - split a string at whitespace, returning an argv |
|
* @str: the string to be split |
|
* @argcp: returned argument count |
|
* |
|
* Returns an array of pointers to strings which are split out from |
|
* @str. This is performed by strictly splitting on white-space; no |
|
* quote processing is performed. Multiple whitespace characters are |
|
* considered to be a single argument separator. The returned array |
|
* is always NULL-terminated. Returns NULL on memory allocation |
|
* failure. |
|
*/ |
|
char **argv_split(const char *str, int *argcp) |
|
{ |
|
int argc = count_argc(str); |
|
char **argv = calloc(argc + 1, sizeof(*argv)); |
|
char **argvp; |
|
|
|
if (argv == NULL) |
|
goto out; |
|
|
|
if (argcp) |
|
*argcp = argc; |
|
|
|
argvp = argv; |
|
|
|
while (*str) { |
|
str = skip_spaces(str); |
|
|
|
if (*str) { |
|
const char *p = str; |
|
char *t; |
|
|
|
str = skip_arg(str); |
|
|
|
t = strndup(p, str-p); |
|
if (t == NULL) |
|
goto fail; |
|
*argvp++ = t; |
|
} |
|
} |
|
*argvp = NULL; |
|
|
|
out: |
|
return argv; |
|
|
|
fail: |
|
argv_free(argv); |
|
return NULL; |
|
}
|
|
|