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; } } };