Move rule property expansion into modules

Reuse code in gmake2 module
Adjust vs2010 test for fixed behaviour
Add vs2010 test for custom separator
This commit is contained in:
WorldofBay 2018-11-16 09:55:31 +01:00 committed by WorldofBay
parent 85d0b3e34c
commit de1398af25
7 changed files with 122 additions and 155 deletions

View File

@ -259,6 +259,73 @@
end
-- convert a rule property into a string
function gmake2.expandRuleString(rule, prop, value)
-- list?
if type(value) == "table" then
if #value > 0 then
if prop.switch then
return prop.switch .. table.concat(value, " " .. prop.switch)
else
prop.separator = prop.separator or " "
return table.concat(value, prop.separator)
end
else
return nil
end
end
-- bool just emits the switch
if prop.switch and type(value) == "boolean" then
if value then
return prop.switch
else
return nil
end
end
local switch = prop.switch or ""
-- enum?
if prop.values then
value = table.findKeyByValue(prop.values, value)
if value == nil then
value = ""
end
end
-- primitive
value = tostring(value)
if #value > 0 then
return switch .. value
else
return nil
end
end
function gmake2.prepareEnvironment(rule, environ, cfg)
for _, prop in ipairs(rule.propertydefinition) do
local fld = p.rule.getPropertyField(rule, prop)
local value = cfg[fld.name]
if value ~= nil then
if fld.kind == "path" then
value = gmake2.path(cfg, value)
elseif fld.kind == "list:path" then
value = gmake2.path(cfg, value)
end
value = gmake2.expandRuleString(rule, prop, value)
if value ~= nil and #value > 0 then
environ[prop.name] = p.esc(value)
end
end
end
end
---------------------------------------------------------------------------
--
-- Handlers for the individual makefile elements that can be shared

View File

@ -254,26 +254,6 @@
cpp.addRuleFile(cfg, node)
end
function cpp.prepareEnvironment(rule, environ, cfg)
for _, prop in ipairs(rule.propertydefinition) do
local fld = p.rule.getPropertyField(rule, prop)
local value = cfg[fld.name]
if value ~= nil then
if fld.kind == "path" then
value = gmake2.path(cfg, value)
elseif fld.kind == "list:path" then
value = gmake2.path(cfg, value)
end
value = p.rule.expandString(rule, prop, value)
if value ~= nil and #value > 0 then
environ[prop.name] = p.esc(value)
end
end
end
end
function cpp.addRuleFile(cfg, node)
local rules = cfg.project._gmake.rules
local fileext = cpp.determineFiletype(cfg, node)
@ -284,8 +264,8 @@
local environ = table.shallowcopy(filecfg.environ)
if rule.propertydefinition then
cpp.prepareEnvironment(rule, environ, cfg)
cpp.prepareEnvironment(rule, environ, filecfg)
gmake2.prepareEnvironment(rule, environ, cfg)
gmake2.prepareEnvironment(rule, environ, filecfg)
end
local shadowContext = p.context.extent(rule, environ)

View File

@ -166,26 +166,6 @@
end
function utility.prepareEnvironment(rule, environ, cfg)
for _, prop in ipairs(rule.propertydefinition) do
local fld = p.rule.getPropertyField(rule, prop)
local value = cfg[fld.name]
if value ~= nil then
if fld.kind == "path" then
value = gmake2.path(cfg, value)
elseif fld.kind == "list:path" then
value = gmake2.path(cfg, value)
end
value = p.rule.expandString(rule, prop, value)
if value ~= nil and #value > 0 then
environ[prop.name] = p.esc(value)
end
end
end
end
function utility.addRuleFile(cfg, node)
local rules = cfg.project._gmake.rules
local rule = rules[path.getextension(node.abspath):lower()]
@ -195,8 +175,8 @@
local environ = table.shallowcopy(filecfg.environ)
if rule.propertydefinition then
utility.prepareEnvironment(rule, environ, cfg)
utility.prepareEnvironment(rule, environ, filecfg)
gmake2.prepareEnvironment(rule, environ, cfg)
gmake2.prepareEnvironment(rule, environ, filecfg)
end
local shadowContext = p.context.extent(rule, environ)

View File

@ -104,7 +104,7 @@
prepare()
test.capture [[
<MyRule>
<MyVar>a,b,c</MyVar>
<MyVar>a;b;c</MyVar>
</MyRule>
]]
end

View File

@ -194,7 +194,7 @@
]]
end
function suite.categories_onStringWithCategory()
function suite.categories_onStringWithCategory()
createVar { name="MyVar", kind="string", category="Custom Category" }
local r = test.getRule("MyRule")
m.categories(r)
@ -220,5 +220,19 @@
</Category.DisplayName>
</Category>
</Rule.Categories>
]]
end
]]
end
function suite.properties_onListWithSeparator()
createVar { name="MyVar", kind="list", separator="," }
local r = test.getRule("MyRule")
m.properties(r)
test.capture [[
<StringListProperty
Name="MyVar"
HelpContext="0"
DisplayName="MyVar"
Separator=","
/>
]]
end

View File

@ -604,6 +604,37 @@
---
-- Transform property to string
---
function m.getRulePropertyString(rule, prop, value, kind)
-- list of paths
if kind == "list:path" then
return table.concat(vstudio.path(cfg, value), ';')
end
-- path
if kind == "path" then
return vstudio.path(cfg, value)
end
-- list
if type(value) == "table" then
return table.concat(value, ";")
end
-- enum
if prop.values then
value = table.findKeyByValue(prop.values, value)
end
-- primitive
return tostring(value)
end
---
-- Write out project-level custom rule variables.
---
@ -618,13 +649,7 @@
local fld = p.rule.getPropertyField(rule, prop)
local value = cfg[fld.name]
if value ~= nil then
if fld.kind == "list:path" then
value = table.concat(vstudio.path(cfg, value), ';')
elseif fld.kind == "path" then
value = vstudio.path(cfg, value)
else
value = p.rule.getPropertyString(rule, prop, value)
end
value = m.getRulePropertyString(rule, prop, value, fld.kind)
if value ~= nil and #value > 0 then
m.element(prop.name, nil, '%s', value)
@ -1207,7 +1232,7 @@
for cfg in project.eachconfig(prj) do
local fcfg = fileconfig.getconfig(file, cfg)
if fcfg and fcfg[fld.name] then
local value = p.rule.getPropertyString(rule, prop, fcfg[fld.name])
local value = m.getRulePropertyString(rule, prop, fcfg[fld.name])
if value and #value > 0 then
m.element(prop.name, m.configPair(cfg), '%s', value)
end

View File

@ -106,105 +106,6 @@
---
-- Given the value for a particular property, returns a formatted string.
--
-- @param prop
-- The property definition.
-- @param value
-- The value of the property to be formatted.
-- @returns
-- A string value.
---
function rule.getPropertyString(self, prop, value)
-- list?
if type(value) == "table" then
if #value > 0 then
local sep = prop.separator or ";"
return table.concat(value, sep)
else
return nil
end
end
-- enum?
if prop.values then
local i = table.findKeyByValue(prop.values, value)
if i ~= nil then
return tostring(i)
else
return nil
end
end
-- primitive
value = tostring(value)
if #value > 0 then
return value
else
return nil
end
end
---
-- Given the value for a particular property, returns a expanded string with switches embedded.
--
-- @param prop
-- The property definition.
-- @param value
-- The value of the property to be formatted.
-- @returns
-- A string value.
---
function rule.expandString(self, prop, value)
if not prop.switch then
prop.separator = prop.separator or " "
return rule.getPropertyString(self, prop, value)
end
-- list?
if type(value) == "table" then
if #value > 0 then
return prop.switch .. table.concat(value, " " .. prop.switch)
else
return nil
end
end
-- bool just emits the switch
if type(value) == "boolean" then
if value then
return prop.switch
else
return nil
end
end
-- enum?
if prop.values then
local i = table.findKeyByValue(prop.values, value)
if i ~= nil then
return prop.switch .. tostring(i)
else
return nil
end
end
-- primitive
value = tostring(value)
if #value > 0 then
return prop.switch .. value
else
return nil
end
end
---
-- Set one or more rule variables in the current configuration scope.
--