diff --git a/src/_premake_init.lua b/src/_premake_init.lua index 6f1d3e54..20a25214 100644 --- a/src/_premake_init.lua +++ b/src/_premake_init.lua @@ -6,31 +6,11 @@ -- Copyright (c) 2012 Jason Perkins and the Premake project -- - local configset = premake.configset - - --- --- Create a "root" configuration set, to hold the global configuration. Values --- that are added to this set become available for all add-ons, solution, projects, --- and on down the line. --- - - configset.root = configset.new() - local root = configset.root - -- -- Set up the global environment for the systems I know about. I would like to see -- at least some if not all of this moved into add-ons in the future. -- --- TODO: use the same configuration API as the user project scripts, once they --- have been ported, like: --- --- configuration { "Windows or Xbox360", "SharedLib" } --- targetprefix "" --- targetextension ".dll" --- implibextension ".lib" --- -- -- Use Posix-style target naming by default, since it is the most common. @@ -60,47 +40,14 @@ -- Windows and friends. -- - configuration { "Windows", "ConsoleApp" } + configuration { "Windows or Xbox360 or C#", "ConsoleApp or WindowedApp" } targetextension ".exe" - configuration { "Windows", "WindowedApp" } - targetextension ".exe" - - configuration { "Windows", "SharedLib" } + configuration { "Windows or Xbox360 or C#", "SharedLib" } targetprefix "" targetextension ".dll" implibextension ".lib" - configuration { "Windows", "StaticLib" } + configuration { "Windows or Xbox360 or C#", "StaticLib" } targetprefix "" targetextension ".lib" - - configuration { "Xbox360", "ConsoleApp" } - targetextension ".exe" - - configuration { "Xbox360", "WindowedApp" } - targetextension ".exe" - - configuration { "Xbox360", "SharedLib" } - targetprefix "" - targetextension ".dll" - implibextension ".lib" - - configuration { "Xbox360", "StaticLib" } - targetprefix "" - targetextension ".lib" - - --- --- .NET languages always use Windows-style naming. --- - - configuration { "C#", "ConsoleApp" } - targetextension ".exe" - - configuration { "C#", "WindowedApp" } - targetextension ".exe" - - configuration { "C#", "SharedLib" } - targetprefix "" - targetextension ".dll" diff --git a/src/base/api.lua b/src/base/api.lua index d0eb3be5..74c49efa 100644 --- a/src/base/api.lua +++ b/src/base/api.lua @@ -27,7 +27,6 @@ } - -- -- A place to store the current active objects in each project scope. -- @@ -35,6 +34,16 @@ api.scope = {} +-- +-- Create a "root" configuration set, to hold the global configuration. Values +-- that are added to this set become available for all add-ons, solution, projects, +-- and on down the line. +-- + + configset.root = configset.new() + local root = configset.root + + -- -- Register a new API function. See the built-in API definitions below -- for usage examples. @@ -1211,7 +1220,7 @@ -- TODO: Fetch the current config set from api.scope instead local container = api.scope.project or api.scope.solution or {} local cset = container.configset or configset.root - configset.addblock(cset, terms) + configset.addblock(cset, {terms}) -- OLD APPROACH: -- TODO: Phase this out ASAP diff --git a/src/base/configset.lua b/src/base/configset.lua index a0773ca6..e5f678f4 100644 --- a/src/base/configset.lua +++ b/src/base/configset.lua @@ -56,12 +56,8 @@ function configset.addblock(cfgset, terms) local block = {} - -- convert terms to a simple, all-lower-case array - terms = table.flatten({ terms }) - for i, term in ipairs(terms) do - terms[i] = term:lower() - end - block.terms = terms + -- attach a criteria object to the block to control its application + block.criteria = criteria.new(terms) table.insert(cfgset.blocks, block) cfgset.current = block @@ -108,7 +104,7 @@ local value = nil for _, block in ipairs(cfgset.blocks) do - if criteria.matches(block.terms, context) then + if criteria.matches(block.criteria, context) then value = block[fieldname] or value end end diff --git a/src/base/criteria.lua b/src/base/criteria.lua index 9ab3878f..0d10e50f 100644 --- a/src/base/criteria.lua +++ b/src/base/criteria.lua @@ -24,15 +24,21 @@ -- A new criteria object. -- - function criteria.new(terms) + function criteria.new(terms) terms = table.flatten(terms) - - -- make future tests case-insensitive - for i, term in ipairs(terms) do - terms[i] = term:lower() + + -- convert Premake wildcard symbols into the appropriate Lua patterns; this + -- list of patterns is what will actually be tested against + local patterns = {} + for _, term in ipairs(terms) do + local pattern = path.wildcards(term):lower() + table.insert(patterns, pattern) end - return terms + local crit = {} + crit.terms = terms + crit.patterns = patterns + return crit end @@ -49,16 +55,25 @@ -- function criteria.matches(crit, context) - local checkterm = function(term) - for _, value in ipairs(context) do - if value:match(term) == value then - return true + + function testpattern(pattern) + for _, part in ipairs(pattern:explode(" or ")) do + if part:startswith("not ") then + return not testpattern(part:sub(5)) + end + + for _, value in ipairs(context) do + if value:match(part) == value then + return true + end end end + + return false end - - for _, term in ipairs(crit) do - if not checkterm(term) then + + for _, pattern in ipairs(crit.patterns) do + if not testpattern(pattern) then return false end end diff --git a/tests/base/test_criteria.lua b/tests/base/test_criteria.lua index 6669646e..b6460eae 100644 --- a/tests/base/test_criteria.lua +++ b/tests/base/test_criteria.lua @@ -55,3 +55,79 @@ crit = criteria.new { "ps3" } test.isfalse(criteria.matches(crit, { "ps3 ppu sn" })) end + + +-- +-- Wildcard matches should work. +-- + + function suite.passes_onPatternMatch() + crit = criteria.new { "vs*" } + test.istrue(criteria.matches(crit, { "vs2005" })) + end + + +-- +-- The "not" modifier should fail the test if the term is matched. +-- + + function suite.fails_onNotMatch() + crit = criteria.new { "not windows" } + test.isfalse(criteria.matches(crit, { "windows" })) + end + + function suite.passes_onNotUnmatched() + crit = criteria.new { "not windows" } + test.istrue(criteria.matches(crit, { "linux" })) + end + + +-- +-- The "or" modifier should pass if either term is present. +-- + + function suite.passes_onFirstOrTermMatched() + crit = criteria.new { "windows or linux" } + test.istrue(criteria.matches(crit, { "windows" })) + end + + function suite.passes_onSecondOrTermMatched() + crit = criteria.new { "windows or linux" } + test.istrue(criteria.matches(crit, { "linux" })) + end + + function suite.passes_onThirdOrTermMatched() + crit = criteria.new { "windows or linux or vs2005" } + test.istrue(criteria.matches(crit, { "vs2005" })) + end + + function suite.fails_onNoOrTermMatched() + crit = criteria.new { "windows or linux" } + test.isfalse(criteria.matches(crit, { "vs2005" })) + end + + +-- +-- The "not" modifier should fail on any match with an "or" modifier. +-- + + function suite.passes_onNotOrMatchesFirst() + crit = criteria.new { "not windows or linux" } + test.isfalse(criteria.matches(crit, { "windows" })) + end + + function suite.passes_onNotOrMatchesSecond() + crit = criteria.new { "windows or not linux" } + test.isfalse(criteria.matches(crit, { "linux" })) + end + + +-- +-- The "not" modifier should succeed with "or" if there are no matches. +-- + + function suite.passes_onNoNotMatch() + crit = criteria.new { "not windows or linux" } + test.istrue(criteria.matches(crit, { "macosx" })) + end +