diff options
| author | Lucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br> | 2025-12-05 08:46:32 +0000 |
|---|---|---|
| committer | Lucas Faria Mendes <lucas.oliveira1676@etec.sp.gov.br> | 2025-12-05 08:46:32 +0000 |
| commit | 8a2b0d1ccca3a5d0f50b4db1b84687000dc74882 (patch) | |
| tree | 91ff883308422aa65900374bd23e3347406a804b | |
| parent | b92ef57d9cfb3b8b51848d3a2940b0b2251c0529 (diff) | |
| download | shell-zig-8a2b0d1ccca3a5d0f50b4db1b84687000dc74882.tar.gz shell-zig-8a2b0d1ccca3a5d0f50b4db1b84687000dc74882.zip | |
codecrafters submit [skip ci]
| -rw-r--r-- | src/builtins.zig | 38 | ||||
| -rw-r--r-- | src/main.zig | 6 | ||||
| -rw-r--r-- | src/shell.zig | 9 |
3 files changed, 50 insertions, 3 deletions
diff --git a/src/builtins.zig b/src/builtins.zig index 8ce4a6f..4f8dfb8 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -181,3 +181,41 @@ pub fn executeHistoryWrite(stdout: anytype, file_path: []const u8, history_list: try file.writeAll("\n"); } } + +pub fn executeHistoryAppend(stdout: anytype, file_path: []const u8, history_list: []const []const u8, last_written_index: *usize) !void { + // Open file in append mode, or create if doesn't exist + const file = std.fs.cwd().openFile(file_path, .{ .mode = .write_only }) catch |err| { + if (err == error.FileNotFound) { + // Create the file if it doesn't exist + const new_file = std.fs.cwd().createFile(file_path, .{}) catch { + try stdout.print("history: cannot write to {s}: error\n", .{file_path}); + return; + }; + defer new_file.close(); + + // Write all commands to new file + for (history_list) |cmd| { + try new_file.writeAll(cmd); + try new_file.writeAll("\n"); + } + last_written_index.* = history_list.len; + return; + } else { + try stdout.print("history: cannot open {s}: error\n", .{file_path}); + return; + } + }; + defer file.close(); + + // Seek to end to append + try file.seekFromEnd(0); + + // Append only new commands (commands after last_written_index) + const start_idx = last_written_index.*; + for (history_list[start_idx..]) |cmd| { + try file.writeAll(cmd); + try file.writeAll("\n"); + } + + last_written_index.* = history_list.len; +} diff --git a/src/main.zig b/src/main.zig index 69b40e0..d373826 100644 --- a/src/main.zig +++ b/src/main.zig @@ -361,6 +361,8 @@ pub fn main() !void { history.deinit(allocator); } + var last_written_index: usize = 0; + const stdout = std.fs.File.stdout(); while (true) { @@ -406,7 +408,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, &history); + 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, &last_written_index); if (result == .exit_shell) break; } else { const result = try shell.executePipeline(allocator, stdout_iface, segments.items); @@ -415,7 +417,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, &history); + 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, &last_written_index); if (result == .exit_shell) break; } diff --git a/src/shell.zig b/src/shell.zig index 5a848af..d3f75ec 100644 --- a/src/shell.zig +++ b/src/shell.zig @@ -20,11 +20,12 @@ pub fn executeCommand( append_output: ?[]const u8, append_error: ?[]const u8, history: *std.ArrayList([]const u8), + last_written_index: *usize, ) !builtins.CommandResult { if (std.mem.eql(u8, cmd_name, "exit")) return builtins.executeExit(); if (std.mem.eql(u8, cmd_name, "history")) { - // Check if args contain -r or -w flag for reading/writing file + // Check if args contain -r, -w, or -a flag for reading/writing/appending file if (args) |a| { const trimmed = std.mem.trim(u8, a, " "); if (std.mem.startsWith(u8, trimmed, "-r ")) { @@ -39,6 +40,12 @@ pub fn executeCommand( try builtins.executeHistoryWrite(stdout, file_path, history.items); } return .continue_loop; + } else if (std.mem.startsWith(u8, trimmed, "-a ")) { + const file_path = std.mem.trim(u8, trimmed[3..], " "); + if (file_path.len > 0) { + try builtins.executeHistoryAppend(stdout, file_path, history.items, last_written_index); + } + return .continue_loop; } } |