mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-04 22:58:47 +00:00
lifting tokenize_body, using lfs package
This commit is contained in:
@@ -29,13 +29,17 @@ local duffle = dofile(_bootstrap_dir .. "../duffle_paths.lua")
|
||||
-- Constants
|
||||
-- ════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
-- Windows separator chars — used to convert `dir /b /s` output (which uses `\`) into POSIX paths (which our scripts expect).
|
||||
-- Windows separator chars — used to convert `dir` output (which uses `\`) into POSIX paths (which our scripts expect).
|
||||
local PATH_SEP_BACKSLASH = "\\"
|
||||
local PATH_SEP_FORWARD = "/"
|
||||
|
||||
-- Glob command for Windows directory walk. `dir /b /s` lists all matching files recursively with bare paths (no headers);
|
||||
-- `2>nul` discards the "file not found" stderr when nothing matches.
|
||||
local DIR_GLOB_CMD = 'dir /b /s "%s\\%s" 2>nul'
|
||||
-- Fallback glob command (subprocess). Used when `lfs` (LuaFileSystem) is not available.
|
||||
-- Scoped to `code\` to avoid walking `.git/`, `toolchain/`, `build/`, etc.
|
||||
local DIR_GLOB_CMD = 'dir /b /s "%s\\code\\%s" 2>nul'
|
||||
|
||||
-- Try to load lfs (LuaFileSystem). If available, scan_dir uses native directory enumeration (~2ms)
|
||||
-- instead of spawning `dir /b /s` as a subprocess (~56ms). Built by update_deps.ps1 into toolchain/lfs/lfs.dll.
|
||||
local lfs = pcall(require, "lfs") and require("lfs") or nil
|
||||
|
||||
-- ════════════════════════════════════════════════════════════════════════════
|
||||
-- Type declarations
|
||||
@@ -120,36 +124,50 @@ end
|
||||
-- If a build removes/creates .macs.h files mid-process, the caller can invalidate by calling `M._invalidate_scan_cache()`.
|
||||
local SCAN_CACHE_KEY = "__word_count_eval_scan_cache__"
|
||||
|
||||
--- Recursively scan a directory for files matching a glob suffix.
|
||||
--- No regex per the no_regex constraint — uses plain byte matching via `dir /b /s` on Windows.
|
||||
--- Scan `code/` for files matching `suffix` (e.g. `*.macs.h`).
|
||||
--- Uses `lfs` (LuaFileSystem) when available — native directory enumeration at ~2ms.
|
||||
--- Falls back to `dir /b /s` subprocess (~56ms) when `lfs` is not compiled.
|
||||
---
|
||||
--- @param dir string -- directory to scan (absolute or relative)
|
||||
--- @param dir string -- project root directory
|
||||
--- @param suffix string -- file pattern, e.g. "*.macs.h"
|
||||
--- @return string[]
|
||||
function M.scan_dir(dir, suffix)
|
||||
local key = dir .. "\0" .. suffix
|
||||
|
||||
-- Check the in-process cache first. (Mostly helps when a build triggers multiple `M.run` calls -- e.g.
|
||||
-- the audit_lua_nesting script's stress tests but the cost is ~free either way.)
|
||||
local cache = package.loaded[SCAN_CACHE_KEY]
|
||||
if cache and cache[key] then return cache[key] end
|
||||
|
||||
local results = {}
|
||||
local pipe = io.popen(DIR_GLOB_CMD:format(dir, suffix))
|
||||
if not pipe then
|
||||
-- Cache the empty result too (avoids re-scan if the dir is genuinely empty -- e.g. a clean build before components has run yet).
|
||||
cache = cache or {}
|
||||
cache[key] = results
|
||||
package.loaded[SCAN_CACHE_KEY] = cache
|
||||
return results
|
||||
end
|
||||
for raw_line in pipe:lines() do
|
||||
local path = raw_line:gsub(PATH_SEP_BACKSLASH, PATH_SEP_FORWARD)
|
||||
results[#results + 1] = path
|
||||
end
|
||||
pipe:close()
|
||||
|
||||
-- Cache the result.
|
||||
if lfs then
|
||||
-- Native walk: list code/<module>/gen/ for matching files. Zero subprocess spawns.
|
||||
local code_dir = dir .. "/code"
|
||||
if lfs.attributes(code_dir, "mode") == "directory" then
|
||||
for mod_name in lfs.dir(code_dir) do
|
||||
if mod_name ~= "." and mod_name ~= ".." then
|
||||
local gen_path = code_dir .. "/" .. mod_name .. "/gen"
|
||||
if lfs.attributes(gen_path, "mode") == "directory" then
|
||||
for fname in lfs.dir(gen_path) do
|
||||
if fname:match("%.macs%.h$") then
|
||||
results[#results + 1] = gen_path .. "/" .. fname
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Fallback: single `dir /b /s` subprocess scoped to code\.
|
||||
local pipe = io.popen(DIR_GLOB_CMD:format(dir, suffix))
|
||||
if pipe then
|
||||
for raw_line in pipe:lines() do
|
||||
results[#results + 1] = raw_line:gsub(PATH_SEP_BACKSLASH, PATH_SEP_FORWARD)
|
||||
end
|
||||
pipe:close()
|
||||
end
|
||||
end
|
||||
|
||||
-- Cache the result (including empty results).
|
||||
cache = cache or {}
|
||||
cache[key] = results
|
||||
package.loaded[SCAN_CACHE_KEY] = cache
|
||||
|
||||
Reference in New Issue
Block a user