diff --git a/modules/gmake2/gmake2.lua b/modules/gmake2/gmake2.lua index d6c6ad1f..e63669ab 100644 --- a/modules/gmake2/gmake2.lua +++ b/modules/gmake2/gmake2.lua @@ -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 diff --git a/modules/gmake2/gmake2_cpp.lua b/modules/gmake2/gmake2_cpp.lua index 2b04b199..e8970616 100644 --- a/modules/gmake2/gmake2_cpp.lua +++ b/modules/gmake2/gmake2_cpp.lua @@ -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) diff --git a/modules/gmake2/gmake2_utility.lua b/modules/gmake2/gmake2_utility.lua index ab2a894a..d8d965e9 100644 --- a/modules/gmake2/gmake2_utility.lua +++ b/modules/gmake2/gmake2_utility.lua @@ -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) diff --git a/modules/vstudio/tests/vc2010/test_rule_vars.lua b/modules/vstudio/tests/vc2010/test_rule_vars.lua index fa0eda90..bb85847d 100644 --- a/modules/vstudio/tests/vc2010/test_rule_vars.lua +++ b/modules/vstudio/tests/vc2010/test_rule_vars.lua @@ -104,7 +104,7 @@ prepare() test.capture [[ - a,b,c + a;b;c ]] end diff --git a/modules/vstudio/tests/vc2010/test_rule_xml.lua b/modules/vstudio/tests/vc2010/test_rule_xml.lua index 54190d47..c999ed5d 100644 --- a/modules/vstudio/tests/vc2010/test_rule_xml.lua +++ b/modules/vstudio/tests/vc2010/test_rule_xml.lua @@ -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 @@ - ]] - end + ]] + end + + function suite.properties_onListWithSeparator() + createVar { name="MyVar", kind="list", separator="," } + local r = test.getRule("MyRule") + m.properties(r) + test.capture [[ + + ]] + end diff --git a/modules/vstudio/vs2010_vcxproj.lua b/modules/vstudio/vs2010_vcxproj.lua index 4ba96c6d..c9917a81 100644 --- a/modules/vstudio/vs2010_vcxproj.lua +++ b/modules/vstudio/vs2010_vcxproj.lua @@ -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 diff --git a/src/base/rule.lua b/src/base/rule.lua index 2c1e2bf8..78e4984b 100644 --- a/src/base/rule.lua +++ b/src/base/rule.lua @@ -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. --