forked from premake/premake-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontext.lua
More file actions
256 lines (209 loc) · 6.2 KB
/
context.lua
File metadata and controls
256 lines (209 loc) · 6.2 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
243
244
245
246
247
248
249
250
251
252
253
254
255
--
-- base/context.lua
--
-- Provide a context for pulling out values from a configuration set. Each
-- context has an associated list of terms which constrain the values that
-- it will retrieve, i.e. "Windows, "Debug", "x64", and so on.
--
-- The context also provides caching for the values returned from the set.
--
-- TODO: I may roll this functionality up into the container API at some
-- point. If you find yourself using or extending this code for your own
-- work give me a shout before you go too far with it so we can coordinate.
--
-- Copyright (c) 2012-2014 Jess Perkins and the Premake project
--
local p = premake
p.context = {}
local context = p.context
local configset = p.configset
--
-- Create a new context object.
--
-- @param cfgset
-- The configuration set to provide the data from this context.
-- @param environ
-- An optional key-value environment table for token expansion; keys and
-- values provided in this table will be available for tokens to use.
-- @param filename
-- An optional filename, which will limit the fetched results to blocks
-- which specifically match the provided name.
-- @return
-- A new context object.
--
function context.new(cfgset, environ)
local ctx = {}
ctx._cfgset = cfgset
ctx.environ = environ or {}
ctx.terms = {}
-- This base directory is used when expanding path tokens encountered
-- in non-path value; such values will be made relative to this value
-- so the resulting projects will only contain relative paths. It is
-- expected that the creator of the context will set this value using
-- the setbasedir() function.
ctx._basedir = os.getcwd()
-- when a missing field is requested, fetch it from my config
-- set, and then cache the value for future lookups
setmetatable(ctx, context.__mt)
return ctx
end
--
-- Create an extended and uncached context based on another context object.
--
-- @param baseContext
-- The base context to extent
-- @param newEnvVars
-- An optional key-value environment table for token expansion; keys and
-- values provided in this table will be available for tokens to use.
-- @return
-- A new context object.
--
function context.extent(baseContext, newEnvVars)
local ctx = {}
ctx._ctx = baseContext
ctx.environ = newEnvVars or baseContext.environ
ctx.terms = {}
ctx._basedir = baseContext._basedir
setmetatable(ctx, context.__mt_uncached)
return ctx
end
---
-- Add a new key-value pair to refine the context filtering.
--
-- @param ctx
-- The context to be filtered.
-- @param key
-- The new (or an existing) key value.
-- @param value
-- The filtering value for the key.
---
function context.addFilter(ctx, key, value)
if type(value) == "table" then
for i = 1, #value do
value[i] = p.field.resolvealias(key, tostring(value[i]))
end
elseif value ~= nil then
value = p.field.resolvealias(key, value)
end
ctx.terms[key:lower()] = value
end
--
-- Copies the list of terms from an existing context.
--
-- @param ctx
-- The context to receive the copied terms.
-- @param src
-- The context containing the terms to copy.
--
function context.copyFilters(ctx, src)
ctx.terms = {}
for k,v in pairs(src.terms) do
ctx.terms[k] = v
end
end
--
-- Merges the list of terms from an existing context.
--
-- @param ctx
-- The context to receive the copied terms.
-- @param src
-- The context containing the terms to copy.
--
function context.mergeFilters(ctx, src)
for k, v in pairs(src.terms) do
if k == "tags" then
ctx.terms[k] = table.join(ctx.terms[k], v)
else
ctx.terms[k] = v
end
end
end
--
-- Sets the base directory for path token expansion in non-path fields; such
-- values will be made relative to this path.
--
-- @param ctx
-- The context in which to set the value.
-- @param basedir
-- The new base directory for path token expansion. This should be
-- provided as an absolute path. This may be left nil to simply fetch
-- the current base directory.
-- @return
-- The context's base directory.
--
function context.basedir(ctx, basedir)
ctx._basedir = basedir or ctx._basedir
return ctx._basedir
end
--
-- Compiles the context for better performance. The list of context terms
-- becomes locked down; any subsequent changes are ignored.
--
-- @param ctx
-- The context to compile.
--
function context.compile(ctx)
ctx._cfgset = configset.compile(ctx._cfgset, ctx.terms)
end
--
-- Check to see if a context's underlying configuration set is empty; that
-- is, it does not contain any configuration blocks.
--
-- @param ctx
-- The context to query.
-- @return
-- True if the set does not contain any blocks.
--
function context.empty(ctx)
return configset.empty(ctx._cfgset)
end
--
-- Fetch a value from underlying configuration set.
--
-- @param ctx
-- The context to query.
-- @param key
-- The property key to query.
-- @param onlylocal
-- If true, don't combine values from parent contexts.
-- @return
-- The value of the key, as determined by the configuration set. If
-- there is a corresponding Premake field, and it the field is enabled
-- for tokens, any contained tokens will be expanded.
--
function context.fetchvalue(ctx, key, onlylocal)
if not onlylocal then
local value = rawget(ctx, key)
if value ~= nil then
return value
end
end
-- The underlying configuration set will only hold registered fields.
-- If the requested key doesn't have a corresponding field, it is just
-- a regular value to be stored and fetched from the table.
local field = p.field.get(key)
if not field then
return nil
end
-- If there is a matching field, then go fetch the aggregated value
-- from my configuration set, and then cache it future lookups.
local value = configset.fetch(ctx._cfgset, field, ctx.terms, ctx, onlylocal and ctx._cfgset)
if value then
-- store the result for later lookups
rawset(ctx, key, value)
end
return value
end
context.__mt = {
__index = context.fetchvalue
}
context.__mt_uncached = {
__index = function(ctx, key)
local field = p.field.get(key)
if not field then
return nil
end
local parent = rawget(ctx, '_ctx')
return configset.fetch(parent._cfgset, field, ctx.terms, ctx, nil)
end
}