summaryrefslogtreecommitdiff
path: root/src/parser.zig
diff options
context:
space:
mode:
authorLucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br>2025-12-05 07:07:36 +0000
committerLucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br>2025-12-05 07:07:36 +0000
commit9a135e52fccafabb494a05c19d9874dbf23c6f03 (patch)
tree95df20713bfa1af7a071052a0f3ff4c010ef343f /src/parser.zig
parentbd95ed67a18aa6938c76e29dff136309ba22a02a (diff)
downloadshell-zig-9a135e52fccafabb494a05c19d9874dbf23c6f03.tar.gz
shell-zig-9a135e52fccafabb494a05c19d9874dbf23c6f03.zip
codecrafters submit [skip ci]
Diffstat (limited to 'src/parser.zig')
-rw-r--r--src/parser.zig30
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 {