diff --git a/src/base/api.lua b/src/base/api.lua index 16ee1930..51c7dc32 100755 --- a/src/base/api.lua +++ b/src/base/api.lua @@ -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 @@ -133,10 +119,8 @@ --- function api.alias(original, alias) - _G[alias] = _G[original] - if api.isListField(premake.fields[original]) then - _G["remove" .. alias] = _G["remove" .. original] - end + _G[alias] = _G[original] + _G["remove" .. alias] = _G["remove" .. original] 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) - local value, err, additional = api.checkvalue(value, field) - if err then error(err, 4) end + else + local value, err, additional = api.checkvalue(value, field) + if err then + error { msg=err } + end - if field.deprecated then - check(value) - end + if field.deprecated then + check(value) + end - remover(removes, value) - if additional then - remover(removes, additional) + table.insert(removes, value) + if additional then + 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 - 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 + elseif value1 ~= value2 then + return false end - end - --- --- Check the collection properties of a field. --- - - function api.isKeyedField(field) - return field.keyed - end - - function api.isListField(field) - return field.list + return true 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, }) diff --git a/src/base/configset.lua b/src/base/configset.lua index 11c86a5f..8955dd74 100644 --- a/src/base/configset.lua +++ b/src/base/configset.lua @@ -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 diff --git a/src/base/field.lua b/src/base/field.lua index 5093fdb2..af24e6e1 100644 --- a/src/base/field.lua +++ b/src/base/field.lua @@ -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 diff --git a/tests/base/test_configset.lua b/tests/base/test_configset.lua index 3fcbcaa7..d14cd202 100644 --- a/tests/base/test_configset.lua +++ b/tests/base/test_configset.lua @@ -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