Port "not" and "or" modifiers to new criteria objects

This commit is contained in:
Jason Perkins 2012-10-31 19:34:53 -04:00
parent 837b3afbeb
commit 6c19509737
5 changed files with 121 additions and 78 deletions

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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