explorer.lua
2.31 KB
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
local lfs = require "lfs"
local files_list = {}
for file in lfs.dir(".") do
if lfs.attributes(file, "mode") == "file" then files_list[#files_list+1] = file end
end
local args = {...}
function table.print(src, offset, line_feed)
if not line_feed then line_feed = '\n' end
if type(src) ~= "table" then io.write("table.print has no table:", src) io.write(line_feed) return end
offset = offset or ""
for k, e in pairs(src) do
-- Deep copy subtables, but not objects!
if type(e) == "table" and not e.__ATOMIC and not e.__CLASSNAME then
io.write(("%s[%s] = {"):format(offset, tostring(k))) io.write(line_feed)
table.print(e, offset.." ", line_feed)
io.write(("%s}"):format(offset)) io.write(line_feed)
else
io.write(("%s[%s] = %s"):format(offset, tostring(k), tostring(e))) io.write(line_feed)
end
end
end
function loadObj(file)
local deps = {}
local env = {
loadstring = function() end,
setLoaded = function() end,
loadObject = function(f) return {__dep_finder__=f} end,
}
local f, err = loadfile(file)
if not f then error(err) end
setfenv(f, env)
local ok, o = pcall(f)
if not ok then error(o) end
local function explore(o, path)
for k, e in pairs(o) do
if type(k) == "table" then
if k.__dep_finder__ then
deps[k.__dep_finder__] = path..","..tostring(k)
else
explore(k, path..","..tostring(k))
end
end
if type(e) == "table" then
if e.__dep_finder__ then
deps[e.__dep_finder__] = path..","..tostring(k)
else
explore(e, path..","..tostring(k))
end
end
end
end
explore(o, "")
return {name=file, deps=deps, parents={}}
end
local obj = {}
for i, file in ipairs(files_list) do
local o = loadObj(file)
obj[file] = o
end
for file, o in pairs(obj) do
for f, _ in pairs(o.deps) do
if not obj[f] then error("wtf") end
obj[f].parents[file] = true
end
end
function find_file(f)
local seens = {}
local toexplore = {main="main"}
while next(toexplore) do
local k, path = next(toexplore)
toexplore[k] = nil
local e = obj[k]
seens[e.name] = true
for sf, spath in pairs(e.deps) do
if sf == f then
print("found")
print(path.."\n- "..sf.." ["..spath.."]")
return
else
if not seens[sf] then toexplore[sf] = path.."\n- "..sf.." ["..spath.."]" end
end
end
end
end
if args[1] then find_file(args[1]) end
-- table.print(obj)