summaryrefslogtreecommitdiff
path: root/src/eval.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.zig')
-rw-r--r--src/eval.zig118
1 files changed, 1 insertions, 117 deletions
diff --git a/src/eval.zig b/src/eval.zig
index 8676516..1568411 100644
--- a/src/eval.zig
+++ b/src/eval.zig
@@ -121,123 +121,7 @@ fn executeCommandWithOutput(command: Command, allocator: Allocator, output_captu
},
.External => |external| {
- // Try to execute external command
- var child_args = ArrayList([]const u8).init(allocator);
- defer child_args.deinit();
-
- try child_args.append(external.program);
- for (external.args.items) |arg| {
- try child_args.append(arg);
- }
-
- var child = std.process.Child.init(child_args.items, allocator);
-
- // Set up pipes for capturing output
- child.stdin_behavior = if (input_source != null) .Pipe else .Inherit;
- child.stdout_behavior = if (output_capture != null) .Pipe else .Inherit;
- child.stderr_behavior = if (output_capture != null) .Pipe else .Inherit;
-
- const spawn_result = child.spawn();
- if (spawn_result) |_| {
- // Spawn succeeded, continue with execution
- } else |err| switch (err) {
- error.FileNotFound => {
- const error_msg = try std.fmt.allocPrint(allocator, "'{s}' is not recognized as an internal or external command,\noperable program or batch file.\n", .{external.program});
- defer allocator.free(error_msg);
-
- if (output_capture) |capture| {
- try capture.write(error_msg);
- } else {
- print("{s}", .{error_msg});
- }
- return CommandStatus{ .Code = 1 };
- },
- error.AccessDenied => {
- const error_msg = "Access is denied.\n";
- if (output_capture) |capture| {
- try capture.write(error_msg);
- } else {
- print("{s}", .{error_msg});
- }
- return CommandStatus{ .Code = 1 };
- },
- else => {
- const error_msg = try std.fmt.allocPrint(allocator, "Cannot execute '{s}': {}\n", .{ external.program, err });
- defer allocator.free(error_msg);
-
- if (output_capture) |capture| {
- try capture.write(error_msg);
- } else {
- print("{s}", .{error_msg});
- }
- return CommandStatus{ .Code = 1 };
- },
- }
-
- // Handle input redirection
- if (input_source) |source| {
- if (child.stdin) |stdin| {
- const writer = stdin.writer();
-
- // Reset source position for reading
- var temp_source = source.*;
- temp_source.position = 0;
-
- while (try temp_source.readLine(allocator)) |line| {
- defer allocator.free(line);
- try writer.print("{s}\n", .{line});
- }
- child.stdin.?.close();
- child.stdin = null;
- }
- }
-
- // Handle output capture
- if (output_capture) |capture| {
- // Read stdout
- if (child.stdout) |stdout| {
- var buffer: [4096]u8 = undefined;
- while (true) {
- const bytes_read = stdout.read(&buffer) catch break;
- if (bytes_read == 0) break;
- try capture.write(buffer[0..bytes_read]);
- }
- }
-
- // Read stderr
- if (child.stderr) |stderr| {
- var buffer: [4096]u8 = undefined;
- while (true) {
- const bytes_read = stderr.read(&buffer) catch break;
- if (bytes_read == 0) break;
- try capture.write(buffer[0..bytes_read]);
- }
- }
- }
-
- // Wait for process to complete
- const term = child.wait() catch |err| {
- const error_msg = switch (err) {
- error.FileNotFound => try std.fmt.allocPrint(allocator, "'{s}' is not recognized as an internal or external command,\noperable program or batch file.\n", .{external.program}),
- else => try std.fmt.allocPrint(allocator, "Error waiting for command: {}\n", .{err}),
- };
- defer allocator.free(error_msg);
-
- if (output_capture) |capture| {
- try capture.write(error_msg);
- } else {
- print("{s}", .{error_msg});
- }
- return CommandStatus{ .Code = 1 };
- };
-
- // Return exit code
- switch (term) {
- .Exited => |code| return CommandStatus{ .Code = @intCast(code) },
- .Signal => |_| return CommandStatus{ .Code = 1 },
- .Stopped => |_| return CommandStatus{ .Code = 1 },
- .Unknown => |_| return CommandStatus{ .Code = 1 },
- }
+ return external.eval(allocator, output_capture, input_source);
},
.Redirect => |redirect| {