blob: 0aaf4f74414fa587bae1ae0c9978460eda0fd49d [file] [log] [blame]
/* SPDX-License-Identifier: Apache-2.0
* Copyright The Zephyr Project contributors
*/
#include <zephyr/sys/util.h>
#include <ctype.h>
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
extern const char *get_bootargs(void);
char **prepare_main_args(int *argc)
{
#ifdef CONFIG_DYNAMIC_BOOTARGS
const char *bootargs = get_bootargs();
#else
const char bootargs[] = CONFIG_BOOTARGS_STRING;
#endif
/* beginning of the buffer contains argument's strings, end of it contains argvs */
static char args_buf[CONFIG_BOOTARGS_ARGS_BUFFER_SIZE];
char *strings_end = (char *)args_buf;
char **argv_begin = (char **)WB_DN(
args_buf + CONFIG_BOOTARGS_ARGS_BUFFER_SIZE - sizeof(char *));
int i = 0;
*argc = 0;
*argv_begin = NULL;
#ifdef CONFIG_DYNAMIC_BOOTARGS
if (!bootargs) {
return argv_begin;
}
#endif
while (1) {
while (isspace(bootargs[i])) {
i++;
}
if (bootargs[i] == '\0') {
return argv_begin;
}
if (strings_end + sizeof(char *) >= (char *)argv_begin) {
LOG_WRN("not enough space in args buffer to accommodate all bootargs"
" - bootargs truncated");
return argv_begin;
}
argv_begin--;
memmove(argv_begin, argv_begin + 1, *argc * sizeof(char *));
argv_begin[*argc] = strings_end;
bool quoted = false;
if (bootargs[i] == '\"' || bootargs[i] == '\'') {
char delimiter = bootargs[i];
for (int j = i + 1; bootargs[j] != '\0'; j++) {
if (bootargs[j] == delimiter) {
quoted = true;
break;
}
}
}
if (quoted) {
char delimiter = bootargs[i];
i++; /* strip quotes */
while (bootargs[i] != delimiter
&& strings_end < (char *)argv_begin) {
*strings_end++ = bootargs[i++];
}
i++; /* strip quotes */
} else {
while (!isspace(bootargs[i])
&& bootargs[i] != '\0'
&& strings_end < (char *)argv_begin) {
*strings_end++ = bootargs[i++];
}
}
if (strings_end < (char *)argv_begin) {
*strings_end++ = '\0';
} else {
LOG_WRN("not enough space in args buffer to accommodate all bootargs"
" - bootargs truncated");
argv_begin[*argc] = NULL;
return argv_begin;
}
(*argc)++;
}
}