osc parser temporary state changed to union

This commit is contained in:
Mitchell Hashimoto
2022-05-10 12:10:44 -07:00
parent eee837f69b
commit b585fe463d

View File

@ -57,24 +57,27 @@ pub const Parser = struct {
/// Current command of the parser, this accumulates. /// Current command of the parser, this accumulates.
command: Command = undefined, command: Command = undefined,
/// Current string parameter being populated
param_str: *[]const u8 = undefined,
/// Current numeric parameter being populated
param_num: u16 = 0,
/// Buffer that stores the input we see for a single OSC command. /// Buffer that stores the input we see for a single OSC command.
/// Slices in Command are offsets into this buffer. /// Slices in Command are offsets into this buffer.
buf: [MAX_BUF]u8 = undefined, buf: [MAX_BUF]u8 = undefined,
buf_start: usize = 0, buf_start: usize = 0,
buf_idx: usize = 0, buf_idx: usize = 0,
/// Temporary state for key/value pairs
key: []const u8 = undefined,
/// True when a command is complete/valid to return. /// True when a command is complete/valid to return.
complete: bool = false, complete: bool = false,
/// Temporary state that is dependent on the current state.
temp_state: union {
/// Current string parameter being populated
str: *[]const u8,
/// Current numeric parameter being populated
num: u16,
/// Temporary state for key/value pairs
key: []const u8,
} = undefined,
// Maximum length of a single OSC command. This is the full OSC command // Maximum length of a single OSC command. This is the full OSC command
// sequence length (excluding ESC ]). This is arbitrary, I couldn't find // sequence length (excluding ESC ]). This is arbitrary, I couldn't find
// any definitive resource on how long this should be. // any definitive resource on how long this should be.
@ -138,7 +141,7 @@ pub const Parser = struct {
self.command = .{ .change_window_title = undefined }; self.command = .{ .change_window_title = undefined };
self.state = .string; self.state = .string;
self.param_str = &self.command.change_window_title; self.temp_state = .{ .str = &self.command.change_window_title };
self.buf_start = self.buf_idx; self.buf_start = self.buf_idx;
}, },
else => self.state = .invalid, else => self.state = .invalid,
@ -190,7 +193,7 @@ pub const Parser = struct {
.semantic_option_key => switch (c) { .semantic_option_key => switch (c) {
'=' => { '=' => {
self.key = self.buf[self.buf_start .. self.buf_idx - 1]; self.temp_state = .{ .key = self.buf[self.buf_start .. self.buf_idx - 1] };
self.state = .semantic_option_value; self.state = .semantic_option_value;
self.buf_start = self.buf_idx; self.buf_start = self.buf_idx;
}, },
@ -211,6 +214,7 @@ pub const Parser = struct {
// No longer complete, if ';' shows up we expect some code. // No longer complete, if ';' shows up we expect some code.
self.complete = false; self.complete = false;
self.state = .semantic_exit_code; self.state = .semantic_exit_code;
self.temp_state = .{ .num = 0 };
self.buf_start = self.buf_idx; self.buf_start = self.buf_idx;
}, },
else => self.state = .invalid, else => self.state = .invalid,
@ -221,8 +225,8 @@ pub const Parser = struct {
self.complete = true; self.complete = true;
const idx = self.buf_idx - self.buf_start; const idx = self.buf_idx - self.buf_start;
if (idx > 0) self.param_num *|= 10; if (idx > 0) self.temp_state.num *|= 10;
self.param_num +|= c - '0'; self.temp_state.num +|= c - '0';
}, },
';' => { ';' => {
self.endSemanticExitCode(); self.endSemanticExitCode();
@ -243,17 +247,17 @@ pub const Parser = struct {
fn endSemanticOptionValue(self: *Parser) void { fn endSemanticOptionValue(self: *Parser) void {
const value = self.buf[self.buf_start..self.buf_idx]; const value = self.buf[self.buf_start..self.buf_idx];
if (mem.eql(u8, self.key, "aid")) { if (mem.eql(u8, self.temp_state.key, "aid")) {
switch (self.command) { switch (self.command) {
.prompt_start => |*v| v.aid = value, .prompt_start => |*v| v.aid = value,
else => {}, else => {},
} }
} else log.info("unknown semantic prompts option: {s}", .{self.key}); } else log.info("unknown semantic prompts option: {s}", .{self.temp_state.key});
} }
fn endSemanticExitCode(self: *Parser) void { fn endSemanticExitCode(self: *Parser) void {
switch (self.command) { switch (self.command) {
.end_of_command => |*v| v.exit_code = @truncate(u8, self.param_num), .end_of_command => |*v| v.exit_code = @truncate(u8, self.temp_state.num),
else => {}, else => {},
} }
} }
@ -270,7 +274,7 @@ pub const Parser = struct {
switch (self.state) { switch (self.state) {
.semantic_exit_code => self.endSemanticExitCode(), .semantic_exit_code => self.endSemanticExitCode(),
.semantic_option_value => self.endSemanticOptionValue(), .semantic_option_value => self.endSemanticOptionValue(),
.string => self.param_str.* = self.buf[self.buf_start..self.buf_idx], .string => self.temp_state.str.* = self.buf[self.buf_start..self.buf_idx],
else => {}, else => {},
} }