Files
mango/kernel/arg.c

126 lines
2.0 KiB
C
Raw Normal View History

2024-11-02 11:31:51 +00:00
#include <mango/arg.h>
#include <mango/libc/string.h>
#include <mango/libc/ctype.h>
2023-12-27 17:34:59 +00:00
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;
}