Move config set value removes to new field framework (mostly)

This commit is contained in:
Jason Perkins 2014-03-09 08:27:21 -04:00
parent aacafa8fe7
commit b228800ba9
4 changed files with 95 additions and 95 deletions

View File

@ -1,7 +1,7 @@
--
-- api.lua
-- Implementation of the solution, project, and configuration APIs.
-- Copyright (c) 2002-2013 Jason Perkins and the Premake project
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
--
premake.api = {}
@ -91,19 +91,6 @@
error("name '" .. name .. "' in use", 2)
end
-- Translate the old "key-" and "-list" field kind modifiers to the
-- new boolean values (13 Jan 2014; should deprecate eventually)
if field.kind:startswith("key-") then
field.kind = field.kind:sub(5)
field.keyed = true
end
if field.kind:endswith("-list") then
field.kind = field.kind:sub(1, -6)
field.list = true
end
-- add this new field to my master list
field = premake.field.new(field)
@ -112,8 +99,7 @@
return api.callback(field, value)
end
-- list values also get a removal function
if api.isListField(field) and not api.isKeyedField(field) then
if premake.field.removes(field) then
_G["remove" .. name] = function(value)
return api.remove(field, value)
end
@ -134,10 +120,8 @@
function api.alias(original, alias)
_G[alias] = _G[original]
if api.isListField(premake.fields[original]) then
_G["remove" .. alias] = _G["remove" .. original]
end
end
@ -309,7 +293,7 @@
if not value then return end
local target = api.gettarget(field.scope)
local kind = field.kind
local hasDeprecatedValues = (type(field.deprecated) == "table")
-- Build a list of values to be removed. If this field has deprecated
-- values, check to see if any of those are going to be removed by this
@ -317,7 +301,6 @@
-- the appropriate logic for removing that value.
local removes = {}
local remover = api["remove" .. kind] or table.insert
function check(value)
if field.deprecated[value] then
@ -326,20 +309,18 @@
if api._deprecations ~= "off" then
local key = field.name .. "_" .. value
premake.warnOnce(key, "the %s value %s has been deprecated.\n %s", field.name, value, handler.message or "")
if api._deprecations == "error" then error("deprecation errors enabled", 8) end
if api._deprecations == "error" then
error { msg="deprecation errors enabled" }
end
end
end
end
local function recurse(value)
if type(value) == "table" then
table.foreachi(value, function(v)
recurse(v)
end)
return
end
table.foreachi(value, recurse)
if value:contains("*") then
elseif hasDeprecatedValues and value:contains("*") then
local current = configset.fetch(target.configset, field)
local mask = path.wildcards(value)
for _, item in ipairs(current) do
@ -347,27 +328,27 @@
recurse(item)
end
end
remover(removes, value)
return
end
table.insert(removes, value)
else
local value, err, additional = api.checkvalue(value, field)
if err then error(err, 4) end
if err then
error { msg=err }
end
if field.deprecated then
check(value)
end
remover(removes, value)
table.insert(removes, value)
if additional then
remover(removes, additional)
table.insert(removes, additional)
end
end
end
recurse(value)
-- Tell the config set to remove these values from future queries
configset.removevalues(target.configset, field.name, removes)
configset.remove(target.configset, field, removes)
end
@ -437,8 +418,8 @@
--
function api.comparevalues(field, value1, value2)
-- both nil?
if not value1 and not value2 then
-- both the same?
if value1 == value2 then
return true
end
@ -447,9 +428,16 @@
return false
end
-- for keyed list, I just make sure all keys are present,
-- no checking of values is done (yet)
if api.isKeyedField(field) then
-- different types?
if type(value1) ~= type(value2) then
return false
end
if type(value1) == "table" then
if #value1 ~= #value2 then
return false
end
for k,v in pairs(value1) do
if not value2[k] then
return false
@ -460,29 +448,11 @@
return false
end
end
elseif value1 ~= value2 then
return false
end
return true
-- for arrays, just see if the lengths match, for now
elseif api.isListField(field) then
return #value1 == #value2
-- everything else can use a simple compare
else
return value1 == value2
end
end
--
-- Check the collection properties of a field.
--
function api.isKeyedField(field)
return field.keyed
end
function api.isListField(field)
return field.list
end
@ -502,19 +472,6 @@
api.reset()
--
-- Set a new file value on an API field. Unlike paths, file value can
-- use wildcards (and so must always be a list).
--
function api.removefile(target, value)
table.insert(target, path.getabsolute(value))
end
api.removedirectory = api.removefile
--
-- Directory data kind; performs wildcard directory searches, converts
-- results to absolute paths.
@ -531,8 +488,10 @@
value = path.getabsolute(value)
end
return value
end,
remove = function(field, current, value, processor)
return path.getabsolute(value)
end
})
@ -553,6 +512,9 @@
value = path.getabsolute(value)
end
return value
end,
remove = function(field, current, value, processor)
return path.getabsolute(value)
end
})
@ -585,14 +547,15 @@
current = current or {}
for k, v in pairs(value) do
if type(k) == "number" then
current = storeKeyed(field, current, v, processor)
else
-- if type(k) == "number" then
-- error ()
-- current = storeKeyed(field, current, v, processor)
-- else
if processor then
v = processor(field, current[k], v)
end
current[k] = v
end
-- end
end
return current
@ -643,6 +606,7 @@
premake.field.kind("list", {
store = storeList,
remove = storeList,
merge = storeList,
})

View File

@ -227,19 +227,28 @@
--
-- @param cset
-- The configuration set from which to remove.
-- @param fieldname
-- The name of the field holding the values to be removed.
-- @param field
-- The field holding the values to be removed.
-- @param values
-- A list of values to be removed.
--
function configset.removevalues(cset, fieldname, values)
function configset.remove(cset, field, values)
-- removes are always processed first; starting a new block here
-- ensures that they will be processed in the proper order
local current = cset._current
configset.addblock(cset, current._criteria.terms, current._basedir)
values = table.flatten(values)
-- This needs work; right now it is hardcoded to only work for lists.
-- To support removing from keyed collections, I first need to figure
-- out how to move the wildcard():lower() bit into the value
-- processing call chain (i.e. that should happen somewhere inside of
-- the field.remove() call). And then I will probably need to add
-- another accessor to actually do the removing, which right now is
-- hardcoded inside of _fetchMerged(). Oh, and some of the logic in
-- api.remove() needs to get pushed down to here (or field).
values = premake.field.remove(field, {}, values)
for i, value in ipairs(values) do
values[i] = path.wildcards(value):lower()
end
@ -247,7 +256,7 @@
-- add a list of removed values to the block
current = cset._current
current._removes = {}
current._removes[fieldname] = values
current._removes[field.name] = values
end

View File

@ -52,6 +52,16 @@
-- Translate the old approaches to data kind definitions to the new
-- one used here. These should probably be deprecated eventually.
if f.kind:startswith("key-") then
f.kind = f.kind:sub(5)
f.keyed = true
end
if f.kind:endswith("-list") then
f.kind = f.kind:sub(1, -6)
f.list = true
end
local kind = f.kind
if f.list then
@ -217,6 +227,23 @@
function field.remove(f, current, value)
local processor = field.accessor(f, "remove")
if processor then
return processor(f, current, value)
else
return value
end
end
function field.removes(f)
return (field.accessor(f, "merge") ~= nil and field.accessor(f, "remove") ~= nil)
end
function field.store(f, current, value)
local processor = field.accessor(f, "store")
if processor then

View File

@ -169,14 +169,14 @@
function suite.remove_onExactValueMatch()
local f = field.get("flags")
configset.store(cset, f, { "Symbols", "Unsafe", "NoRTTI" })
configset.removevalues(cset, "flags", { "Unsafe" })
configset.remove(cset, f, { "Unsafe" })
test.isequal({ "Symbols", "NoRTTI" }, configset.fetch(cset, f, {}))
end
function suite.remove_onMultipleValues()
local f = field.get("flags")
configset.store(cset, f, { "Symbols", "NoExceptions", "Unsafe", "NoRTTI" })
configset.removevalues(cset, "flags", { "NoExceptions", "NoRTTI" })
configset.remove(cset, f, { "NoExceptions", "NoRTTI" })
test.isequal({ "Symbols", "Unsafe" }, configset.fetch(cset, f, {}))
end
@ -188,7 +188,7 @@
function suite.remove_onWildcard()
local f = field.get("defines")
configset.store(cset, f, { "WIN32", "WIN64", "LINUX", "MACOSX" })
configset.removevalues(cset, "defines", { "WIN*" })
configset.remove(cset, f, { "WIN*" })
test.isequal({ "LINUX", "MACOSX" }, configset.fetch(cset, f, {}))
end