summaryrefslogtreecommitdiff
path: root/src/builtins.zig
blob: ea34f1950bd2df3343eddb16702a0773155273a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const std = @import("std");
const path = @import("path.zig");

const BUILTINS = [_][]const u8{ "exit", "echo", "type", "pwd" };

pub const CommandResult = enum {
    continue_loop,
    exit_shell,
};

pub fn isBuiltin(cmd_name: []const u8) bool {
    for (BUILTINS) |builtin| {
        if (std.mem.eql(u8, cmd_name, builtin)) return true;
    }
    return false;
}

pub fn executeExit() CommandResult {
    return .exit_shell;
}

pub fn executeEcho(stdout: anytype, args: ?[]const u8) !void {
    if (args) |a| {
        try stdout.print("{s}\n", .{a});
    } else {
        try stdout.print("\n", .{});
    }
}

pub fn executePwd(allocator: std.mem.Allocator, stdout: anytype) !void {
    const cwd = try std.fs.cwd().realpathAlloc(allocator, ".");
    defer allocator.free(cwd);
    try stdout.print("{s}\n", .{cwd});
}

pub fn executeType(allocator: std.mem.Allocator, stdout: anytype, args: ?[]const u8) !void {
    if (args) |a| {
        if (isBuiltin(a)) {
            try stdout.print("{s} is a shell builtin\n", .{a});
        } else if (try path.findInPath(allocator, a)) |cmd_path| {
            defer allocator.free(cmd_path);
            try stdout.print("{s} is {s}\n", .{ a, cmd_path });
        } else {
            try stdout.print("{s}: not found\n", .{a});
        }
    }
}