forked from thetaepsilon-gamedev/minetest-devsupport-modpack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch_dirs.lua
131 lines (109 loc) · 3.9 KB
/
search_dirs.lua
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
--[[
This file contains the code to determine relative filesystem paths inside a mod,
for a given requested component path.
The end result is a list of paths that point to candidate lua scripts to load.
These scripts are tested in order to see if they exist,
and the first one found is run to load the component
(see find_component_file() in loader.lua).
]]
local sf = dofile(_modpath.."safe_filenames.lua")
local encode_safe_filename = sf.encode_safe_filename
local encode_safe_path_component = sf.encode_safe_path_component
local filter = function(table, f)
local ret = {}
for key, value in pairs(table) do
ret[key] = f(value)
end
return ret
end
local initfile = "init"
local ext = ".lua"
local interface = {}
-- handle the shorter paths inside mod writer-supplied alias directories.
-- say the mod writer only wanted to create e.g.
-- short_mod_dir/foomodule/... (leading part of namespace chopped)
local paths_relative_to_alias_d = function(dirsep, pathtail)
-- note that the suffix tail has the potential to be zero elements here,
-- so in that case we skip the "all-in-one" and "just filename" paths,
-- otherwise we'd end up with subdir/.lua which would
-- a) look strange and b) cause problems on unix and windows alike if it existed.
local ret = {}
local safepath = filter(pathtail, encode_safe_path_component)
-- myaliasdir/sub/foo
-- may become either sub/foo.lua or sub/foo/init.lua
local basepath = table.concat(safepath, dirsep)
local alias_aio = nil
local zero = (#pathtail == 0)
if not zero then
-- myaliasdir/sub.foo.lua
alias_aio = encode_safe_filename(pathtail) .. ext
table.insert(ret, alias_aio)
-- myaliasdir/sub/foo.lua
-- note that if #pathtail = 1, would just be /sub.lua,
-- which would end up the same as the all-in-one path.
-- hence, skip this if turns out to be the same.
local alias_justname = basepath .. ext
if alias_justname ~= alias_aio then
table.insert(ret, alias_justname)
end
end
-- myaliasdir/sub/foo/init.lua
-- or, if tail is zero size, just myaliasdir/init.lua
basepath = (basepath ~= "") and (basepath .. "/") or ""
table.insert(ret, basepath .. initfile .. ext)
return ret
end
interface.relative_to_alias_d = paths_relative_to_alias_d
-- constructs the list of modpath-relative files to attempt loading.
local paths_relative_to_mod_d =
function(
targetlist,
dirsep,
path,
extraprops,
pathtail
)
assert(type(extraprops) == "table")
assert(type(pathtail) == "table")
local result = {}
local ipos = 0
local add = function(v)
ipos = ipos + 1
result[ipos] = v
end
-- possible paths for a component,
-- given the path "com.github.user.myawesomemod.foomodule"
-- com.github.user.myawesomemod.foomodule.lua
local path_allinone = encode_safe_filename(path) .. ext
local relatives = {}
local safepath = filter(path, encode_safe_path_component)
-- com/github/user/myawesomemod/foomodule
local basepath = table.concat(safepath, dirsep)
-- com/github/user/myawesomemod/foomodule.lua
local path_justname = basepath .. ext
-- com/github/user/myawesomemod/foomodule/init.lua
local path_initfile = basepath .. dirsep .. initfile .. ext
local search_dirs = extraprops.search_dirs
local alias_relatives
if search_dirs then
alias_relatives = paths_relative_to_alias_d(dirsep, pathtail)
end
-- there can exist both portable and native lookup directories for each candidate.
for _, target in ipairs(targetlist) do
target = target..dirsep
-- alias directories take higher precedence than default paths.
if search_dirs then for i, aliasdir in ipairs(search_dirs) do
-- yes, I'm shadowing the outer variable on purpose
local target = target .. aliasdir .. dirsep
for j, candidate in ipairs(alias_relatives) do
add(target .. candidate)
end
end end
add(target .. path_allinone)
add(target .. path_justname)
add(target .. path_initfile)
end
return result
end
interface.relative_to_mod_d = paths_relative_to_mod_d
return interface