local path = {} path.sep = package.config:sub(1, 1) path.is_windows = path.sep == "\\" local function normalize(p) local out = p:gsub("\\", "/") out = out:gsub("/+", "/") if path.is_windows then out = out:gsub("/", "\\") end return out end function path.join(...) local parts = {...} local out = "" for _, part in ipairs(parts) do part = tostring(part) if part ~= "" then if out == "" then out = part else out = out .. "/" .. part end end end return normalize(out) end function path.dirname(p) p = tostring(p):gsub("\\", "/") local d = p:match("^(.*)/[^/]*$") if d == nil or d == "" then return "." end return normalize(d) end function path.basename(p) p = tostring(p):gsub("\\", "/") return p:match("([^/]+)$") or p end function path.exists(p) local f = io.open(p, "rb") if f then f:close(); return true end return false end function path.read_file(p) local f = assert(io.open(p, "rb")) local data = f:read("*a") f:close() return data end function path.write_file(p, data) local f = assert(io.open(p, "wb")) f:write(data) f:close() end function path.remove_file(p) if not p or p == "" then return end os.remove(p) end function path.shell_quote(s) s = tostring(s) if path.is_windows then return '"' .. s:gsub('"', '\\"') .. '"' end return "'" .. s:gsub("'", "'\\''") .. "'" end function path.repo_root(script_path) local tools_dir = path.dirname(script_path or arg[0] or "tools/test.lua") local root = path.dirname(tools_dir) if path.exists(path.join(root, "gpu.odin")) then return root end return "." end function path.mkdir_p(dir) local cmd if path.is_windows then cmd = "if not exist " .. path.shell_quote(dir) .. " mkdir " .. path.shell_quote(dir) else cmd = "mkdir -p " .. path.shell_quote(dir) end return os.execute(cmd) end return path