diff options
author | Jason Perkins <starkos@industriousone.com> | 2011-06-02 23:26:15 +0400 |
---|---|---|
committer | Jason Perkins <starkos@industriousone.com> | 2011-06-02 23:26:15 +0400 |
commit | 2580bd7798aa41ae14fd1503ed0534aaec7f94ba (patch) | |
tree | 6f10aba5be648e589de5bdda6ce8b529f44ae52c | |
parent | a315c34f15f0b90eb2c611a676cabe07b2a1db5b (diff) |
Added support for key-value fields to the API
-rw-r--r-- | src/base/api.lua | 58 | ||||
-rw-r--r-- | src/base/bake.lua | 52 | ||||
-rw-r--r-- | src/base/table.lua | 21 | ||||
-rw-r--r-- | tests/baking/test_merging.lua | 108 | ||||
-rw-r--r-- | tests/base/test_api.lua | 32 | ||||
-rw-r--r-- | tests/base/test_baking.lua | 12 | ||||
-rw-r--r-- | tests/premake4.lua | 5 |
7 files changed, 249 insertions, 39 deletions
diff --git a/src/base/api.lua b/src/base/api.lua index 18369ba..b78ad19 100644 --- a/src/base/api.lua +++ b/src/base/api.lua @@ -378,6 +378,13 @@ kind = "list", scope = "config", }, + + vpaths = + { + kind = "keyvalue", + scope = "container", + }, + } @@ -530,6 +537,43 @@ end +-- +-- Adds values to a key-value field of a solution/project/configuration. `ctype` +-- specifies the container type (see premake.getobject) for the field. +-- + + function premake.setkeyvalue(ctype, fieldname, value) + local container, err = premake.getobject(ctype) + if not container then + error(err, 4) + end + + if not container[fieldname] then + container[fieldname] = { } + end + + if type(value) ~= "table" then + error("invalid value; table expected", 4) + end + + local result = container[fieldname] + + local function doinsert(tbl, errordepth) + for key,value in pairs(tbl) do + if type(value) == "table" then + doinsert(value, errordepth + 1) + elseif type(key) == "string" and type(value) == "string" then + result[key] = value + else + error("invalid value; both key and value must be a string", errordepth) + end + end + end + + doinsert(value, 4) + return container[fieldname] + end + -- -- Set a new value for a string field of a solution/project/configuration. `ctype` @@ -567,23 +611,25 @@ local scope = premake.fields[name].scope local allowed = premake.fields[name].allowed - if ((kind == "string" or kind == "path") and value) then + if (kind == "string" or kind == "path") and value then if type(value) ~= "string" then error("string value expected", 3) end end - if (kind == "string") then + if kind == "string" then return premake.setstring(scope, name, value, allowed) - elseif (kind == "path") then + elseif kind == "path" then if value then value = path.getabsolute(value) end return premake.setstring(scope, name, value) - elseif (kind == "list") then + elseif kind == "list" then return premake.setarray(scope, name, value, allowed) - elseif (kind == "dirlist") then + elseif kind == "dirlist" then return premake.setdirarray(scope, name, value) - elseif (kind == "filelist") then + elseif kind == "filelist" then return premake.setfilearray(scope, name, value) + elseif kind == "keyvalue" then + return premake.setkeyvalue(scope, name, value) end end diff --git a/src/base/bake.lua b/src/base/bake.lua index aa47985..8c7ca77 100644 --- a/src/base/bake.lua +++ b/src/base/bake.lua @@ -142,29 +142,43 @@ -- The source object, containing the settings to added to the destination. -- + local function mergefield(kind, dest, src) + local tbl = dest or { } + if kind == "keyvalue" then + for key, value in pairs(src) do + tbl[key] = value + end + else + for _, item in ipairs(src) do + if not tbl[item] then + table.insert(tbl, item) + tbl[item] = item + end + end + end + return tbl + end + local function mergeobject(dest, src) - if not src then return end - for field, value in pairs(src) do - if not nocopy[field] then - if type(value) == "table" then - -- merge two lists, removing any duplicates along the way - local tbl = dest[field] or { } - - if field == 'terms' then - for term_key,term_value in pairs(value)do - tbl[term_key]=term_value - end + -- if there's nothing to add, quick out + if not src then + return + end + + for fieldname, value in pairs(src) do + if not nocopy[fieldname] then + -- fields that are included in the API are merged... + local field = premake.fields[fieldname] + if field then + if type(value) == "table" then + dest[fieldname] = mergefield(field.kind, dest[fieldname], value) else - for _, item in ipairs(value) do - if not tbl[item] then - table.insert(tbl, item) - tbl[item] = item - end - end + dest[fieldname] = value end - dest[field] = tbl + + -- ...everything else is just copied as-is else - dest[field] = value + dest[fieldname] = value end end end diff --git a/src/base/table.lua b/src/base/table.lua index 8ca0d08..3aeb962 100644 --- a/src/base/table.lua +++ b/src/base/table.lua @@ -116,6 +116,27 @@ -- +-- Adds the key-value associations from one table into another +-- and returns the resulting merged table. +-- + + function table.merge(...) + local result = { } + for _,t in ipairs(arg) do + if type(t) == "table" then + for k,v in pairs(t) do + result[k] = v + end + else + error("invalid value") + end + end + return result + end + + + +-- -- Translates the values contained in array, using the specified -- translation table, and returns the results in a new array. -- diff --git a/tests/baking/test_merging.lua b/tests/baking/test_merging.lua new file mode 100644 index 0000000..c6b7d1e --- /dev/null +++ b/tests/baking/test_merging.lua @@ -0,0 +1,108 @@ +-- +-- tests/baking/test_merging.lua +-- Verifies different field types are merged properly during baking. +-- Copyright (c) 2011 Jason Perkins and the Premake project +-- + + T.baking_merging = { } + local suite = T.baking_merging + +-- +-- Setup code +-- + + local sln, prj, cfg + function suite.setup() + sln = solution "MySolution" + configurations { "Debug", "Release" } + end + + local function prepare() + premake.bake.buildconfigs() + prj = premake.solution.getproject(sln, 1) + end + + +-- +-- String value tests +-- + + function suite.Strings_AreReplaced() + kind "SharedLib" + project "MyProject" + kind "StaticLib" + prepare() + test.isequal("StaticLib", prj.kind) + end + + function suite.Strings_KeepPreviousValue() + kind "SharedLib" + project "MyProject" + prepare() + test.isequal("SharedLib", prj.kind) + end + + +-- +-- List tests +-- + + function suite.Lists_KeepPreviousValue() + project "MyProject" + prepare() + test.isequal("Debug:Release", table.concat(prj.configurations, ":")) + end + + function suite.Lists_AreJoined() + defines { "SOLUTION" } + project "MyProject" + defines { "PROJECT" } + prepare() + test.isequal("SOLUTION:PROJECT", table.concat(prj.defines, ":")) + end + + function suite.Lists_RemoveDuplicates() + defines { "SOLUTION", "DUPLICATE" } + project "MyProject" + defines { "PROJECT", "DUPLICATE" } + prepare() + test.isequal("SOLUTION:DUPLICATE:PROJECT", table.concat(prj.defines, ":")) + end + + function suite.Lists_FlattensNestedTables() + defines { "ROOT", { "NESTED" } } + project "MyProject" + prepare() + test.isequal("ROOT:NESTED", table.concat(prj.defines, ":")) + end + + +-- +-- Key/value tests +-- + + function suite.KeyValue_AreMerged() + vpaths { ["sln"] = "Solution" } + project "MyProject" + vpaths { ["prj"] = "Project" } + prepare() + test.isequal("Solution", prj.vpaths["sln"]) + test.isequal("Project", prj.vpaths["prj"]) + end + + function suite.KeyValue_OverwritesOldValues() + vpaths { ["sln"] = "Solution", ["prj"] = "Solution2" } + project "MyProject" + vpaths { ["prj"] = "Project" } + prepare() + test.isequal("Project", prj.vpaths["prj"]) + end + + function suite.KeyValue_FlattensNestedTables() + vpaths { ["r"] = "Root", { ["n"] = "Nested" } } + project "MyProject" + prepare() + test.isequal("Root", prj.vpaths["r"]) + test.isequal("Nested", prj.vpaths["n"]) + end + diff --git a/tests/base/test_api.lua b/tests/base/test_api.lua index 854610d..98d116d 100644 --- a/tests/base/test_api.lua +++ b/tests/base/test_api.lua @@ -1,7 +1,7 @@ -- -- tests/base/test_api.lua -- Automated test suite for the project API support functions. --- Copyright (c) 2008-2010 Jason Perkins and the Premake project +-- Copyright (c) 2008-2011 Jason Perkins and the Premake project -- T.api = { } @@ -121,6 +121,36 @@ -- +-- premake.setkeyvalue() tests +-- + + function suite.setkeyvalue_InsertsValues_OnTable() + premake.CurrentConfiguration = { } + premake.setkeyvalue("config", "vpaths", { ["*.h"] = "Headers" }) + test.isequal("Headers", premake.CurrentConfiguration.vpaths["*.h"]) + end + + function suite.setkeyvalue_RaisesError_OnString() + premake.CurrentConfiguration = { } + ok, err = pcall(function () premake.setkeyvalue("config", "vpaths", "Headers") end) + test.isfalse(ok) + end + + function suite.setkeyvalue_RaisesError_OnNonStringKey() + premake.CurrentConfiguration = { } + ok, err = pcall(function () premake.setkeyvalue("config", "vpaths", { [1] = "Headers" }) end) + test.isfalse(ok) + end + + function suite.setkeyvalue_RaisesError_OnNonStringValue() + premake.CurrentConfiguration = { } + ok, err = pcall(function () premake.setkeyvalue("config", "vpaths", { ["*.h"] = 1 }) end) + test.isfalse(ok) + end + + + +-- -- accessor tests -- diff --git a/tests/base/test_baking.lua b/tests/base/test_baking.lua index c446e16..c8168ce 100644 --- a/tests/base/test_baking.lua +++ b/tests/base/test_baking.lua @@ -57,18 +57,6 @@ -- Tests -- - function suite.SolutionFields() - prepare() - test.isequal("Debug:Release", table.concat(cfg.configurations,":")) - end - - - function suite.ProjectFields() - prepare() - test.isequal("C", cfg.language) - end - - function suite.ProjectWideSettings() prepare() test.isequal("SOLUTION:PROJECT:NATIVE", table.concat(prj.defines,":")) diff --git a/tests/premake4.lua b/tests/premake4.lua index a4512be..992dd40 100644 --- a/tests/premake4.lua +++ b/tests/premake4.lua @@ -48,7 +48,6 @@ dofile("test_gmake_cs.lua") dofile("base/test_api.lua") dofile("base/test_action.lua") - dofile("base/test_baking.lua") dofile("base/test_config.lua") dofile("base/test_location.lua") dofile("base/test_os.lua") @@ -58,6 +57,10 @@ dofile("tools/test_gcc.lua") dofile("base/test_config_bug.lua") + -- Baking tests + dofile("base/test_baking.lua") + dofile("baking/test_merging.lua") + -- Clean tests dofile("actions/test_clean.lua") |