forked from premake/premake-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrule.lua
More file actions
242 lines (196 loc) · 5.03 KB
/
rule.lua
File metadata and controls
242 lines (196 loc) · 5.03 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
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
---
-- base/rule.lua
-- Defines rule sets for generated custom rule files.
-- Copyright (c) 2014 Jason Perkins and the Premake project
---
local p = premake
p.rule = p.api.container("rule", p.global)
local rule = p.rule
---
-- Create a new rule container instance.
---
function rule.new(name)
local self = p.container.new(rule, name)
-- create a variable setting function. Do a version with lowercased
-- first letter(s) to match Premake's naming style for other calls
_G[name .. "Vars"] = function(vars)
rule.setVars(self, vars)
end
local lowerName = name:gsub("^%u+", string.lower)
_G[lowerName .. "Vars"] = _G[name .. "Vars"]
return self
end
---
-- Enumerate the property definitions for a rule.
---
function rule.eachProperty(self)
local props = self.propertydefinition
local i = 0
return function ()
i = i + 1
if i <= #props then
return props[i]
end
end
end
---
-- Find a property definition by its name.
--
-- @param name
-- The property name.
-- @returns
-- The property definition if found, nil otherwise.
---
function rule.getProperty(self, name)
local props = self.propertydefinition
for i = 1, #props do
local prop = props[i]
if prop.name == name then
return prop
end
end
end
---
-- Find the field definition for one this rule's properties. This field
-- can then be used with the api.* functions to manipulate the property's
-- values in the current configuration scope.
--
-- @param prop
-- The property definition.
-- @return
-- The field definition for the property; this will be created if it
-- does not already exist.
---
function rule.getPropertyField(self, prop)
if prop._field then
return prop._field
end
local kind = prop.kind or "string"
if kind == "list" then
kind = "list:string"
end
local fld = p.field.new {
name = "_rule_" .. self.name .. "_" .. prop.name,
scope = "config",
kind = kind,
tokens = true,
}
prop._field = fld
return fld
end
---
-- Set one or more rule variables in the current configuration scope.
--
-- @param vars
-- A key-value list of variables to set and their corresponding values.
---
function rule.setVars(self, vars)
for key, value in pairs(vars) do
local prop = rule.getProperty(self, key)
if not prop then
error (string.format("rule '%s' does not have property '%s'", self.name, key))
end
local fld = rule.getPropertyField(self, prop)
p.api.storeField(fld, value)
end
end
---
-- prepare an environment with the rule properties as global tokens,
-- according to the format specified.
--
-- @param environ
-- The environment table to fill up
-- @param format
-- The formatting to be used, ie "[%s]".
---
function rule.createEnvironment(self, format)
local environ = {}
for _, def in ipairs(self.propertydefinition) do
environ[def.name] = string.format(format, def.name)
end
return environ
end
---
-- prepare an table of pathVars with the rule properties as global tokens,
-- according to the format specified.
--
-- @param pathVars
-- The pathVars table to fill up
-- @param format
-- The formatting to be used, ie "%%(%s)".
---
function rule.preparePathVars(self, pathVars, format)
for _, def in ipairs(self.propertydefinition) do
pathVars[def.name] = { absolute = true, token = string.format(format, def.name) }
end
end
function rule.createPathVars(self, format)
local pathVars = {}
rule.preparePathVars(self, pathVars, format)
return pathVars
end
function rule.prepareEnvironment(self, environ, cfg)
local function path(cfg, value)
cfg = cfg.project or cfg
local dirs = path.translate(project.getrelative(cfg, value))
if type(dirs) == 'table' then
dirs = table.filterempty(dirs)
end
return dirs
end
local function expandRuleString(prop, value)
-- list
if type(value) == "table" then
if #value > 0 then
local switch = prop.switch or ""
if prop.separator then
return switch .. table.concat(value, prop.separator)
else
return switch .. table.concat(value, " " .. switch)
end
else
return nil
end
end
-- bool just emits the switch
if prop.switch and type(value) == "boolean" then
if value then
return prop.switch
else
return nil
end
end
-- enum
if prop.values then
local switch = prop.switch or {}
value = table.findKeyByValue(prop.values, value)
if value == nil then
return nil
end
return switch[value]
end
-- primitive
local switch = prop.switch or ""
value = tostring(value)
if #value > 0 then
return switch .. value
else
return nil
end
end
for _, prop in ipairs(self.propertydefinition) do
local fld = p.rule.getPropertyField(self, prop)
local value = cfg[fld.name]
if value ~= nil then
if fld.kind == "path" then
value = path(cfg, value)
elseif fld.kind == "list:path" then
value = path(cfg, value)
end
value = expandRuleString(prop, value)
if value ~= nil and #value > 0 then
environ[prop.name] = p.esc(value)
end
end
end
end