summaryrefslogtreecommitdiff
path: root/src/eval.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.zig')
-rw-r--r--src/eval.zig154
1 files changed, 2 insertions, 152 deletions
diff --git a/src/eval.zig b/src/eval.zig
index 1568411..9399c75 100644
--- a/src/eval.zig
+++ b/src/eval.zig
@@ -38,7 +38,7 @@ pub fn executeCommand(command: Command, allocator: Allocator) !CommandStatus {
return executeCommandWithOutput(command, allocator, null, null);
}
-fn executeCommandWithOutput(command: Command, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+pub fn executeCommandWithOutput(command: Command, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
switch (command) {
.Empty => return CommandStatus{ .Code = 0 },
@@ -125,157 +125,7 @@ fn executeCommandWithOutput(command: Command, allocator: Allocator, output_captu
},
.Redirect => |redirect| {
- // Check if we have any output redirections
- var has_output_redirect = false;
- for (redirect.redirects.items) |redir| {
- if (redir.redirect_type == .OutputOverwrite or redir.redirect_type == .OutputAppend) {
- has_output_redirect = true;
- break;
- }
- }
-
- var captured_output = OutputCapture.init(allocator);
- defer captured_output.deinit();
-
- // Prepare input redirection if needed
- var input_data: ?[]const u8 = null;
- var redirect_input_source: ?InputSource = null;
- defer if (input_data) |data| allocator.free(data);
-
- // Process input redirections first
- for (redirect.redirects.items) |redir| {
- if (redir.redirect_type == .InputFrom) {
- const file_path = switch (redir.target) {
- .Con => {
- print("Input redirection from CON not supported\n", .{});
- return CommandStatus{ .Code = 1 };
- },
- .Lpt1, .Lpt2, .Lpt3, .Prn => {
- print("Cannot redirect input from device\n", .{});
- return CommandStatus{ .Code = 1 };
- },
- .Path => |path| path,
- };
-
- // Read input file
- const file = std.fs.cwd().openFile(file_path, .{}) catch |err| {
- switch (err) {
- error.FileNotFound => print("The system cannot find the file specified.\n", .{}),
- error.AccessDenied => print("Access is denied.\n", .{}),
- else => print("Cannot open input file.\n", .{}),
- }
- return CommandStatus{ .Code = 1 };
- };
- defer file.close();
-
- input_data = file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch |err| {
- switch (err) {
- error.AccessDenied => print("Access is denied.\n", .{}),
- else => print("Cannot read input file.\n", .{}),
- }
- return CommandStatus{ .Code = 1 };
- };
-
- redirect_input_source = InputSource.init(input_data.?);
- break; // Only handle first input redirection
- }
- }
-
- // Execute the command with input and output capture (only capture output if needed)
- const status = try executeCommandWithOutput(redirect.command.*, allocator, if (has_output_redirect) &captured_output else null, if (redirect_input_source) |*source| source else null);
-
- // Handle output redirections
- for (redirect.redirects.items) |redir| {
- if (redir.redirect_type == .InputFrom) continue; // Already handled
- const file_path = switch (redir.target) {
- .Con => {
- // Redirect to console - just print normally
- print("{s}", .{captured_output.getContents()});
- continue;
- },
- .Lpt1, .Lpt2, .Lpt3, .Prn => {
- print("Cannot redirect to device\n", .{});
- return CommandStatus{ .Code = 1 };
- },
- .Path => |path| path,
- };
-
- // Handle different redirect types
- switch (redir.redirect_type) {
- .OutputOverwrite => {
- // Write to file, overwriting existing content
- const file = std.fs.cwd().createFile(file_path, .{}) catch |err| {
- switch (err) {
- error.AccessDenied => print("Access is denied.\n", .{}),
- else => print("Cannot create file.\n", .{}),
- }
- return CommandStatus{ .Code = 1 };
- };
- defer file.close();
-
- file.writeAll(captured_output.getContents()) catch |err| {
- switch (err) {
- error.AccessDenied => print("Access is denied.\n", .{}),
- else => print("Cannot write to file.\n", .{}),
- }
- return CommandStatus{ .Code = 1 };
- };
- },
- .OutputAppend => {
- // Append to file
- const file = std.fs.cwd().openFile(file_path, .{ .mode = .write_only }) catch |err| {
- switch (err) {
- error.FileNotFound => {
- // Create new file if it doesn't exist
- const new_file = std.fs.cwd().createFile(file_path, .{}) catch |create_err| {
- switch (create_err) {
- error.AccessDenied => print("Access is denied.\n", .{}),
- else => print("Cannot create file.\n", .{}),
- }
- return CommandStatus{ .Code = 1 };
- };
- defer new_file.close();
-
- new_file.writeAll(captured_output.getContents()) catch {
- print("Cannot write to file.\n", .{});
- return CommandStatus{ .Code = 1 };
- };
- continue;
- },
- error.AccessDenied => {
- print("Access is denied.\n", .{});
- return CommandStatus{ .Code = 1 };
- },
- else => {
- print("Cannot open file.\n", .{});
- return CommandStatus{ .Code = 1 };
- },
- }
- };
- defer file.close();
-
- // Seek to end for append
- file.seekFromEnd(0) catch {
- print("Cannot seek to end of file.\n", .{});
- return CommandStatus{ .Code = 1 };
- };
-
- file.writeAll(captured_output.getContents()) catch |err| {
- switch (err) {
- error.AccessDenied => print("Access is denied.\n", .{}),
- else => print("Cannot write to file.\n", .{}),
- }
- return CommandStatus{ .Code = 1 };
- };
- },
- .InputFrom => {
- // Input redirection already handled above
- continue;
- },
- }
- }
-
- return status;
+ return redirect.eval(allocator, output_capture, input_source, executeCommandWithOutput);
},
else => {