Deep copy all object values, to allow unique per-target token expansions

This commit is contained in:
Jason Perkins 2012-04-26 07:44:25 -04:00
parent 391ec4eee6
commit 7675e057d2
3 changed files with 68 additions and 4 deletions

View File

@ -18,7 +18,35 @@
return false
end
--
-- Make a complete copy of a table, including any child tables it contains.
--
function table.deepcopy(object)
-- keep track of already seen objects to avoid loops
local seen = {}
local function copy(object)
if type(object) ~= "table" then
return object
elseif seen[object] then
return seen[object]
end
local clone = {}
seen[object] = clone
for key, value in pairs(object) do
clone[key] = copy(value)
end
return clone
end
return copy(object)
end
--
-- Enumerates an array of objects and returns a new table containing
-- only the value of one particular field.

View File

@ -122,7 +122,6 @@
function oven.expandtokens(cfg, scope, filecfg)
-- build a context for the tokens to use
local context = {
_G = _G,
sln = cfg.solution,
prj = cfg.project,
cfg = cfg,
@ -163,7 +162,8 @@
-- give the function access to the project objects
setfenv(func, context)
setmetatable(context, {__index = _G})
-- run it and return the result
local result = func()
if not result then
@ -395,11 +395,13 @@
--
function oven.mergevalue(target, fieldname, fieldkind, value)
-- list values get merged, others overwrite
-- list values get merged, others overwrite; note that if the
-- values contain tokens they will be modified in the token
-- expansion phase, so important to make copies of objects
if fieldkind:endswith("list") then
target[fieldname] = oven.mergetables(target[fieldname] or {}, value)
else
target[fieldname] = value
target[fieldname] = table.deepcopy(value)
end
end

View File

@ -85,3 +85,37 @@
local fcfg = config.getfileconfig(cfg, os.getcwd().."/shaders/hello.cg")
test.isequal("cgc --profile gp5vp shaders/hello.cg -o obj/Debug/hello.gxp", fcfg.buildrule.commands[1])
end
--
-- Make sure that the same token source can be applied to multiple targets.
--
function suite.canReuseTokenSources()
files { "shaders/hello.cg", "shaders/goodbye.cg" }
configuration { "**.cg" }
buildrule {
commands = {
"cgc --profile gp5vp %{file.path} -o %{cfg.objdir}/%{file.basename}.gxp",
},
outputs = {
"%{cfg.objdir}/%{file.basename}.o"
}
}
prepare()
local fcfg = config.getfileconfig(cfg, os.getcwd().."/shaders/hello.cg")
test.isequal("cgc --profile gp5vp shaders/hello.cg -o obj/Debug/hello.gxp", fcfg.buildrule.commands[1])
fcfg = config.getfileconfig(cfg, os.getcwd().."/shaders/goodbye.cg")
test.isequal("cgc --profile gp5vp shaders/goodbye.cg -o obj/Debug/goodbye.gxp", fcfg.buildrule.commands[1])
end
--
-- Verify the global namespace is still accessible.
--
function suite.canUseGlobalFunctions()
testapi "%{iif(true, 'a', 'b')}"
prepare()
test.isequal("a", cfg.testapi)
end