45 lines
1.1 KiB
Zig
45 lines
1.1 KiB
Zig
const std = @import("std");
|
|
const ser = @import("../ser.zig");
|
|
const ffi = @import("../ffi.zig");
|
|
const c = ffi.c;
|
|
|
|
pub fn luaPush(l: *c.lua_State) void {
|
|
ser.luaPushAny(l, .{
|
|
.findInPath = ffi.luaFunc(lFindInPath),
|
|
|
|
.map_opt = .{ .noremap = true, .silent = true },
|
|
});
|
|
}
|
|
|
|
/// This is basically a reimplementation of `which`.
|
|
fn lFindInPath(l: *c.lua_State) !c_int {
|
|
const bin = ffi.luaCheckstring(l, 1);
|
|
const path = std.os.getenv("PATH") orelse return error.PathNotSet;
|
|
|
|
var splits = std.mem.split(u8, path, ":");
|
|
while (splits.next()) |p| {
|
|
const trimmed = std.mem.trim(u8, p, " \n\r");
|
|
if (trimmed.len == 0)
|
|
continue;
|
|
|
|
const joined = try std.fs.path.joinZ(
|
|
std.heap.c_allocator,
|
|
&.{ trimmed, bin },
|
|
);
|
|
defer std.heap.c_allocator.free(joined);
|
|
|
|
_ = std.fs.cwd().statFile(joined) catch |e| {
|
|
if (e == error.FileNotFound)
|
|
continue;
|
|
|
|
return e;
|
|
};
|
|
|
|
c.lua_pushstring(l, joined.ptr);
|
|
return 1;
|
|
}
|
|
|
|
c.lua_pushnil(l);
|
|
return 1;
|
|
}
|