Files
YukiOS/arch/x86_64/boot/cmdline.zig

83 lines
2.5 KiB
Zig

fn isWhitespace(c: u8) bool {
return c == ' ' or c == '\t' or c == '\n' or c == '\r';
}
pub const Cmdline = struct {
ptr: []const u8,
pub fn init(ptr: []const u8) Cmdline {
return Cmdline{
.ptr = ptr,
};
}
fn _parseArg(self: *const Cmdline, key: []const u8, buf: []u8) ?usize {
var state: union(enum) {
search_key,
compare_key: usize,
copy_value: usize,
skip_arg
} = .search_key;
var i: usize = 0;
while (i < self.ptr.len) {
const c = self.ptr[i];
switch (state) {
.search_key => {
if (isWhitespace(c)) {
i = i + 1;
continue;
}
state = .{ .compare_key = 0};
},
.compare_key => |key_index| {
if (key_index < key.len) {
if (c == key[key_index]) {
state = .{ .compare_key = key_index + 1 };
} else {
state = .skip_arg;
}
} else {
if (c == '=') {
state = .{ .copy_value = 0 };
} else if (isWhitespace(c)) {
return 0;
} else {
state = .skip_arg;
}
}
i = i + 1;
},
.skip_arg => {
if (isWhitespace(c)) {
state = .search_key;
}
i = i + 1;
},
.copy_value => |buf_index| {
if (isWhitespace(c) or buf_index >= buf.len) {
return buf_index;
}
buf[buf_index] = c;
state = .{ .copy_value = buf_index + 1 };
i = i + 1;
},
}
}
switch (state) {
.copy_value => |buf_index| return buf_index,
else => return null
}
}
pub fn parseArg(self: *const Cmdline, key: []const u8, buf: []u8) ?usize {
return self._parseArg(key, buf);
}
pub fn parseArgBool(self: *const Cmdline, key: []const u8) bool {
const result = self._parseArg(key, &[_]u8{});
if (result) {
return true;
} else {
return false;
}
}
};