-
Notifications
You must be signed in to change notification settings - Fork 0
/
Tuprules.lua
149 lines (139 loc) · 3.26 KB
/
Tuprules.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
CONFIG = {
base = {
cflags = "",
lflags = "",
objdir = "obj/",
bindir = "bin/",
coutputs = {},
loutputs = {},
},
buildtypes = {
debug = {
suffix = "d",
},
release = {
suffix = "",
},
},
}
function flag_remove(flag)
return function(s)
s = s:gsub((" " .. flag .. " "), " ")
s = s:gsub(("^" .. flag .. " "), " ")
s = s:gsub((" " .. flag .. "$"), " ")
s = s:gsub(("^" .. flag .. "$"), "")
return s
end
end
function merge(v, tbl, index)
merge_type = type((tbl or {})[index])
if merge_type == "string" then
local merged = tbl[index]
if merged:sub(0, 1) == " " then
error("Merged variables should not start with spaces:" .. merged, 3)
elseif merged:sub(-1) == " " then
error("Merged variables should not end with spaces: " .. merged, 3)
end
-- By only space-separating flags, we allow custom directories.
if index:sub(-5) == "flags" and v != "" and merged != "" then
return (v .. " " .. merged)
else
return (v .. merged)
end
elseif merge_type == "table" then
for key, value in pairs(tbl[index]) do
table.insert(v, key, value)
end
elseif merge_type == "function" then
return tbl[index](v)
end
return v
end
function CONFIG:branch(buildtype_filter, ...)
local arg = { ... }
local ret = {
base = {},
buildtypes = {},
branch = CONFIG.branch,
}
for k, v in pairs(self.base) do
for _, other in pairs(arg) do
if other.branch then
error(
"Configurations should not be combined with each other", 2
)
end
v = merge(v, other.base, k)
end
ret.base[k] = v
end
for buildtype, vars in pairs(self.buildtypes) do
if (buildtype_filter == "") or (buildtype == buildtype_filter) then
ret.buildtypes[buildtype] = {}
for k, v in pairs(vars) do
for _, other in pairs(arg) do
v = merge(v, (other.buildtypes or {})[buildtype], k)
end
ret.buildtypes[buildtype][k] = v
end
end
end
return ret
end
-- Inspired by https://stackoverflow.com/a/1283608.
function table_merge(t1, t2)
-- The caller expects [t1] to remain unmodified, so we create a shallow copy
local ret = {}
for k, v in pairs(t1) do
ret[k] = v
end
setmetatable(ret, getmetatable(t1))
for k, v in pairs(t2) do
if type(v) == "table" then
if type(ret[k] or false) == "table" then
ret[k] = table_merge(ret[k] or {}, t2[k] or {})
elseif type(v) != 'function' then
ret[k] = v
end
elseif type(v) != 'function' then
ret += v
end
end
return ret
end
-- https://stackoverflow.com/a/49709999
function table_filter(tbl, patterns)
for _, pattern in pairs(patterns) do
local new_index = 1
local size_orig = #tbl
for old_index, v in ipairs(tbl) do
if not string.match(v, pattern) then
tbl[new_index] = v
new_index = new_index + 1
end
end
for i = new_index, size_orig do tbl[i] = nil end
end
return tbl
end
functional_metatable = {
__add = table_merge,
__sub = table_filter,
}
function sourcepath(path)
if path:sub(-1) != "/" then
error("Paths should end with a slash: " .. path, 2)
end
return {
root = path,
join = function(component)
return (path .. component)
end,
glob = function(pattern)
local ret = tup.glob(path .. pattern)
setmetatable(ret, functional_metatable)
return ret
end
}
end
tup.include(string.format("Tuprules.%s.lua", tup.getconfig("TUP_PLATFORM")))