summaryrefslogtreecommitdiff
path: root/src/shell.zig
diff options
context:
space:
mode:
authorLucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br>2025-12-05 06:31:01 +0000
committerLucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br>2025-12-05 06:31:01 +0000
commit6f1c762e789cd746e20cd7597aab0316d2c2fcd9 (patch)
tree36ee2dd94e54eea37230f61f574a99054aefdf88 /src/shell.zig
parent5a676cada89ccdd33de496e2a1a1a130a26894f6 (diff)
downloadshell-zig-6f1c762e789cd746e20cd7597aab0316d2c2fcd9.tar.gz
shell-zig-6f1c762e789cd746e20cd7597aab0316d2c2fcd9.zip
codecrafters submit [skip ci]
Diffstat (limited to 'src/shell.zig')
-rw-r--r--src/shell.zig60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/shell.zig b/src/shell.zig
index e42c131..c95d9d0 100644
--- a/src/shell.zig
+++ b/src/shell.zig
@@ -9,11 +9,63 @@ pub fn executeCommand(
stdout: anytype,
cmd_name: []const u8,
args: ?[]const u8,
+ output_redirect: ?[]const u8,
) !builtins.CommandResult {
if (std.mem.eql(u8, cmd_name, "exit")) return builtins.executeExit();
if (std.mem.eql(u8, cmd_name, "echo")) {
- try builtins.executeEcho(stdout, args);
+ if (output_redirect) |file| {
+ const fd = try std.fs.cwd().createFile(file, .{});
+ defer fd.close();
+
+ if (args) |a| {
+ var i: usize = 0;
+ var in_quote = false;
+ var quote_char: u8 = 0;
+ var unquoted = std.ArrayList(u8){};
+ defer unquoted.deinit(allocator);
+ var last_was_space = false;
+
+ while (i < a.len) : (i += 1) {
+ if (!in_quote and a[i] == '\\' and i + 1 < a.len) {
+ i += 1;
+ _ = unquoted.append(allocator, a[i]) catch {};
+ last_was_space = false;
+ } else if (!in_quote and (a[i] == '\'' or a[i] == '"')) {
+ in_quote = true;
+ quote_char = a[i];
+ last_was_space = false;
+ } else if (in_quote and a[i] == quote_char) {
+ in_quote = false;
+ last_was_space = false;
+ } else if (in_quote and quote_char == '"' and a[i] == '\\' and i + 1 < a.len) {
+ const next = a[i + 1];
+ if (next == '"' or next == '\\') {
+ i += 1;
+ _ = unquoted.append(allocator, a[i]) catch {};
+ } else {
+ _ = unquoted.append(allocator, a[i]) catch {};
+ }
+ last_was_space = false;
+ } else if (!in_quote and a[i] == ' ') {
+ if (!last_was_space) {
+ _ = unquoted.append(allocator, ' ') catch {};
+ last_was_space = true;
+ }
+ } else {
+ _ = unquoted.append(allocator, a[i]) catch {};
+ last_was_space = false;
+ }
+ }
+
+ try fd.writeAll(unquoted.items);
+ try fd.writeAll("\n");
+ } else {
+ try fd.writeAll("\n");
+ }
+ } else {
+ try builtins.executeEcho(stdout, args);
+ }
return .continue_loop;
}
@@ -38,7 +90,11 @@ pub fn executeCommand(
const argv = try parser.parseArgs(allocator, cmd_name, args);
defer allocator.free(argv);
- try executor.runExternalProgram(allocator, program_path, argv);
+ if (output_redirect) |file| {
+ try executor.runExternalProgramWithRedirect(allocator, program_path, argv, file);
+ } else {
+ try executor.runExternalProgram(allocator, program_path, argv);
+ }
return .continue_loop;
}