all kernel headers have been moved from include/mango to include/kernel and include definitions that are only relevant to kernel-space. any definitions that are relevant to both kernel- and user-space (i.e. type definitions, syscall IDs) have been moved to include/mango within libmango.
126 lines
2.0 KiB
C
126 lines
2.0 KiB
C
#include <kernel/arg.h>
|
|
#include <kernel/libc/string.h>
|
|
#include <kernel/libc/ctype.h>
|
|
|
|
static char g_cmdline[CMDLINE_MAX + 1] = {0};
|
|
|
|
static kern_status_t remove_quotes(char *s, size_t max)
|
|
{
|
|
size_t i = 0;
|
|
while (i < max) {
|
|
if (s[i] != '"') {
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
size_t start = i;
|
|
size_t end = i + 1;
|
|
while (s[end] != '"' && end < max) {
|
|
end++;
|
|
}
|
|
|
|
if (s[end] != '"') {
|
|
return KERN_INVALID_ARGUMENT;
|
|
}
|
|
|
|
/* length of quoted string (excluding quotes) */
|
|
size_t len = end - start - 1;
|
|
|
|
/* remove trailing quote */
|
|
s[end] = 0;
|
|
|
|
/* add 1 to len to include the null terminator */
|
|
memmove(s + start, s + start + 1, len + 1);
|
|
|
|
i = end + 1;
|
|
}
|
|
|
|
return KERN_OK;
|
|
}
|
|
|
|
kern_status_t parse_cmdline(const char *cmdline)
|
|
{
|
|
strncpy(g_cmdline, cmdline, sizeof g_cmdline - 1);
|
|
g_cmdline[sizeof g_cmdline - 1] = 0;
|
|
|
|
bool in_string = false;
|
|
|
|
for (size_t i = 0; g_cmdline[i]; i++) {
|
|
char c = g_cmdline[i];
|
|
|
|
if (c == '"') {
|
|
in_string = !in_string;
|
|
continue;
|
|
}
|
|
|
|
if (isspace(c) && !in_string) {
|
|
g_cmdline[i] = 0;
|
|
}
|
|
}
|
|
|
|
if (in_string) {
|
|
/* unterminated string on command line */
|
|
return KERN_INVALID_ARGUMENT;
|
|
}
|
|
|
|
remove_quotes(g_cmdline, sizeof g_cmdline);
|
|
|
|
return KERN_OK;
|
|
}
|
|
|
|
static char *advance_to_next_arg(char *s, char *max)
|
|
{
|
|
while (*s && s < max) {
|
|
s++;
|
|
}
|
|
|
|
while (!*s && s < max) {
|
|
s++;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
const char *arg_value(const char *arg_name)
|
|
{
|
|
char *s = g_cmdline;
|
|
char *end = s + sizeof g_cmdline;
|
|
|
|
while (s < end) {
|
|
size_t len = strlen(s);
|
|
size_t name_len = strcspn(s, "=");
|
|
|
|
if (!strncmp(s, arg_name, name_len)) {
|
|
if (len == name_len) {
|
|
/* arg has no value */
|
|
return NULL;
|
|
}
|
|
|
|
return s + name_len + 1;
|
|
}
|
|
|
|
s = advance_to_next_arg(s, end);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool arg_is_set(const char *arg_name)
|
|
{
|
|
char *s = g_cmdline;
|
|
char *end = s + sizeof g_cmdline;
|
|
|
|
while (s < end) {
|
|
size_t name_len = strcspn(s, "=");
|
|
|
|
if (!strncmp(s, arg_name, name_len)) {
|
|
return true;
|
|
}
|
|
|
|
s = advance_to_next_arg(s, end);
|
|
}
|
|
|
|
return false;
|
|
}
|