1 /* SPDX-License-Identifier: Apache-2.0 2 * Copyright The Zephyr Project contributors 3 */ 4 5 #include <zephyr/sys/util.h> 6 #include <ctype.h> 7 #include <zephyr/logging/log.h> 8 LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); 9 10 extern const char *get_bootargs(void); prepare_main_args(int * argc)11char **prepare_main_args(int *argc) 12 { 13 #ifdef CONFIG_DYNAMIC_BOOTARGS 14 const char *bootargs = get_bootargs(); 15 #else 16 const char bootargs[] = CONFIG_BOOTARGS_STRING; 17 #endif 18 19 /* beginning of the buffer contains argument's strings, end of it contains argvs */ 20 static char args_buf[CONFIG_BOOTARGS_ARGS_BUFFER_SIZE]; 21 char *strings_end = (char *)args_buf; 22 char **argv_begin = (char **)WB_DN( 23 args_buf + CONFIG_BOOTARGS_ARGS_BUFFER_SIZE - sizeof(char *)); 24 int i = 0; 25 26 *argc = 0; 27 *argv_begin = NULL; 28 29 #ifdef CONFIG_DYNAMIC_BOOTARGS 30 if (!bootargs) { 31 return argv_begin; 32 } 33 #endif 34 35 while (1) { 36 while (isspace(bootargs[i])) { 37 i++; 38 } 39 40 if (bootargs[i] == '\0') { 41 return argv_begin; 42 } 43 44 if (strings_end + sizeof(char *) >= (char *)argv_begin) { 45 LOG_WRN("not enough space in args buffer to accommodate all bootargs" 46 " - bootargs truncated"); 47 return argv_begin; 48 } 49 50 argv_begin--; 51 memmove(argv_begin, argv_begin + 1, *argc * sizeof(char *)); 52 argv_begin[*argc] = strings_end; 53 54 bool quoted = false; 55 56 if (bootargs[i] == '\"' || bootargs[i] == '\'') { 57 char delimiter = bootargs[i]; 58 59 for (int j = i + 1; bootargs[j] != '\0'; j++) { 60 if (bootargs[j] == delimiter) { 61 quoted = true; 62 break; 63 } 64 } 65 } 66 67 if (quoted) { 68 char delimiter = bootargs[i]; 69 70 i++; /* strip quotes */ 71 while (bootargs[i] != delimiter 72 && strings_end < (char *)argv_begin) { 73 *strings_end++ = bootargs[i++]; 74 } 75 i++; /* strip quotes */ 76 } else { 77 while (!isspace(bootargs[i]) 78 && bootargs[i] != '\0' 79 && strings_end < (char *)argv_begin) { 80 *strings_end++ = bootargs[i++]; 81 } 82 } 83 84 if (strings_end < (char *)argv_begin) { 85 *strings_end++ = '\0'; 86 } else { 87 LOG_WRN("not enough space in args buffer to accommodate all bootargs" 88 " - bootargs truncated"); 89 argv_begin[*argc] = NULL; 90 return argv_begin; 91 } 92 (*argc)++; 93 } 94 } 95