diff options
Diffstat (limited to 'src/parser.zig')
| -rw-r--r-- | src/parser.zig | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/parser.zig b/src/parser.zig index 84c8095..e0f28de 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -6,6 +6,7 @@ pub const ParsedCommand = struct { output_redirect: ?[]const u8, error_redirect: ?[]const u8, append_output: ?[]const u8, + append_error: ?[]const u8, }; pub fn parseCommand(input: []const u8) ParsedCommand { @@ -16,7 +17,7 @@ pub fn parseCommand(input: []const u8) ParsedCommand { while (i < input.len and input[i] == ' ') : (i += 1) {} if (i >= input.len) { - return .{ .name = "", .args = null, .output_redirect = null, .error_redirect = null, .append_output = null }; + return .{ .name = "", .args = null, .output_redirect = null, .error_redirect = null, .append_output = null, .append_error = null }; } if (input[i] == '\'' or input[i] == '"') { @@ -42,9 +43,13 @@ pub fn parseCommand(input: []const u8) ParsedCommand { var redirect_pos: ?usize = null; var error_redirect_pos: ?usize = null; var append_pos: ?usize = null; + var append_error_pos: ?usize = null; var j = i; while (j < input.len) : (j += 1) { - if (j + 1 < input.len and input[j] == '2' and input[j + 1] == '>') { + if (j + 2 < input.len and input[j] == '2' and input[j + 1] == '>' and input[j + 2] == '>') { + append_error_pos = j; + j += 2; + } else if (j + 1 < input.len and input[j] == '2' and input[j + 1] == '>') { error_redirect_pos = j; j += 1; } else if (j + 1 < input.len and input[j] == '1' and j + 1 < input.len and input[j + 1] == '>' and j + 2 < input.len and input[j + 2] == '>') { @@ -66,6 +71,7 @@ pub fn parseCommand(input: []const u8) ParsedCommand { var output_redirect: ?[]const u8 = null; var error_redirect: ?[]const u8 = null; var append_output: ?[]const u8 = null; + var append_error: ?[]const u8 = null; var args_end = input.len; if (redirect_pos) |pos| { @@ -77,6 +83,9 @@ pub fn parseCommand(input: []const u8) ParsedCommand { if (append_pos) |pos| { if (pos < args_end) args_end = pos; } + if (append_error_pos) |pos| { + if (pos < args_end) args_end = pos; + } while (args_end > i and input[args_end - 1] == ' ') : (args_end -= 1) {} @@ -136,7 +145,22 @@ pub fn parseCommand(input: []const u8) ParsedCommand { } } - return .{ .name = cmd_name, .args = args, .output_redirect = output_redirect, .error_redirect = error_redirect, .append_output = append_output }; + if (append_error_pos) |pos| { + var k = pos + 3; + while (k < input.len and input[k] == ' ') : (k += 1) {} + + if (k < input.len) { + var redir_buf = std.ArrayList(u8){}; + defer redir_buf.deinit(std.heap.page_allocator); + + while (k < input.len and input[k] != ' ') : (k += 1) { + _ = redir_buf.append(std.heap.page_allocator, input[k]) catch {}; + } + append_error = redir_buf.toOwnedSlice(std.heap.page_allocator) catch null; + } + } + + return .{ .name = cmd_name, .args = args, .output_redirect = output_redirect, .error_redirect = error_redirect, .append_output = append_output, .append_error = append_error }; } pub fn parseArgs(allocator: std.mem.Allocator, cmd_name: []const u8, args_str: ?[]const u8) ![]const []const u8 { |