From f58e4507f913bf3a6f5afee14650f058ecf6be84 Mon Sep 17 00:00:00 2001 From: Lucas Faria Mendes Date: Fri, 5 Dec 2025 05:18:27 -0300 Subject: codecrafters submit [skip ci] --- src/builtins.zig | 8 +++++++- src/main.zig | 14 ++++++++++++-- src/shell.zig | 6 ++++++ test_history.txt | 4 ++++ 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 test_history.txt diff --git a/src/builtins.zig b/src/builtins.zig index 2a1eed7..011a923 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -1,7 +1,7 @@ const std = @import("std"); const path = @import("path.zig"); -const BUILTINS = [_][]const u8{ "exit", "echo", "type", "pwd", "cd" }; +const BUILTINS = [_][]const u8{ "exit", "echo", "type", "pwd", "cd", "history" }; pub const CommandResult = enum { continue_loop, @@ -115,3 +115,9 @@ pub fn executeType(allocator: std.mem.Allocator, stdout: anytype, args: ?[]const } } } + +pub fn executeHistory(stdout: anytype, history_list: []const []const u8) !void { + for (history_list, 1..) |cmd, idx| { + try stdout.print(" {d} {s}\n", .{ idx, cmd }); + } +} diff --git a/src/main.zig b/src/main.zig index 74140cd..d16699d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -285,6 +285,12 @@ pub fn main() !void { defer _ = gpa.deinit(); const allocator = gpa.allocator(); + var history = std.ArrayList([]const u8){}; + defer { + for (history.items) |cmd| allocator.free(cmd); + history.deinit(allocator); + } + const stdout = std.fs.File.stdout(); while (true) { @@ -297,6 +303,10 @@ pub fn main() !void { var stdout_writer = std.fs.File.stdout().writerStreaming(&.{}); const stdout_iface = &stdout_writer.interface; + // Record command in history (duplicate it for long-term storage) + const cmd_copy = try allocator.dupe(u8, cmd); + try history.append(allocator, cmd_copy); + if (std.mem.indexOfScalar(u8, cmd, '|')) |_| { var segments = std.ArrayList([]const u8){}; defer segments.deinit(allocator); @@ -326,7 +336,7 @@ pub fn main() !void { if (segments.items.len == 1) { const parsed = parser.parseCommand(cmd); - const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error); + const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error, history.items); if (result == .exit_shell) break; } else { const result = try shell.executePipeline(allocator, stdout_iface, segments.items); @@ -335,7 +345,7 @@ pub fn main() !void { } else { const parsed = parser.parseCommand(cmd); - const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error); + const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error, history.items); if (result == .exit_shell) break; } diff --git a/src/shell.zig b/src/shell.zig index 271e3ea..6f8bfef 100644 --- a/src/shell.zig +++ b/src/shell.zig @@ -19,9 +19,15 @@ pub fn executeCommand( error_redirect: ?[]const u8, append_output: ?[]const u8, append_error: ?[]const u8, + history_list: []const []const u8, ) !builtins.CommandResult { if (std.mem.eql(u8, cmd_name, "exit")) return builtins.executeExit(); + if (std.mem.eql(u8, cmd_name, "history")) { + try builtins.executeHistory(stdout, history_list); + return .continue_loop; + } + if (std.mem.eql(u8, cmd_name, "echo")) { if (error_redirect) |file| { const fd = try std.fs.cwd().createFile(file, .{}); diff --git a/test_history.txt b/test_history.txt new file mode 100644 index 0000000..1f4d742 --- /dev/null +++ b/test_history.txt @@ -0,0 +1,4 @@ +echo hello +pwd +type echo +history -- cgit v1.2.3