ea984e9c1c
Don't allow adding to "Command Line" though.
429 lines
8.9 KiB
Lua
429 lines
8.9 KiB
Lua
---
|
|
-- vs2010_rules_xml.lua
|
|
-- Generate a Visual Studio 201x custom rules XML file.
|
|
-- Copyright (c) Jason Perkins and the Premake project
|
|
--
|
|
|
|
local p = premake
|
|
p.vstudio.vs2010.rules.xml = {}
|
|
|
|
local m = p.vstudio.vs2010.rules.xml
|
|
m.elements = {}
|
|
|
|
|
|
---
|
|
-- Entry point; generate the root <ProjectSchemaDefinitions> element.
|
|
---
|
|
|
|
m.elements.project = function(r)
|
|
return {
|
|
m.projectSchemaDefinitions,
|
|
m.rule,
|
|
m.ruleItem,
|
|
m.fileExtension,
|
|
m.contentType,
|
|
}
|
|
end
|
|
|
|
function m.generate(r)
|
|
p.xmlUtf8()
|
|
p.callArray(m.elements.project, r)
|
|
p.out('</ProjectSchemaDefinitions>')
|
|
end
|
|
|
|
|
|
|
|
---
|
|
-- Generate the main <Rule> element.
|
|
---
|
|
|
|
m.elements.rule = function(r)
|
|
return {
|
|
m.dataSource,
|
|
m.categories,
|
|
m.inputs,
|
|
m.properties,
|
|
m.commandLineTemplate,
|
|
m.beforeTargets,
|
|
m.afterTargets,
|
|
m.outputs,
|
|
m.executionDescription,
|
|
m.additionalDependencies,
|
|
m.additionalOptions,
|
|
}
|
|
end
|
|
|
|
function m.rule(r)
|
|
p.push('<Rule')
|
|
p.w('Name="%s"', r.name)
|
|
p.w('PageTemplate="tool"')
|
|
p.w('DisplayName="%s"', r.display or r.name)
|
|
p.w('Order="200">')
|
|
p.callArray(m.elements.rule, r)
|
|
p.pop('</Rule>')
|
|
end
|
|
|
|
|
|
|
|
---
|
|
-- Generate the list of categories.
|
|
---
|
|
|
|
function m.categories(r)
|
|
local categories = {
|
|
[1] = { name="General" },
|
|
}
|
|
local propCategory = {}
|
|
local defs = r.propertydefinition
|
|
for i = 1, #defs do
|
|
local def = defs[i]
|
|
local cat = def.category
|
|
if cat then
|
|
if type(cat) == "string" and cat ~= "Command Line" and cat ~= "General" then
|
|
if not propCategory[cat] then
|
|
table.insert(categories, { name=cat })
|
|
propCategory[cat] = true
|
|
end
|
|
else
|
|
def.category = nil
|
|
end
|
|
end
|
|
end
|
|
table.insert(categories, { name="Command Line", subtype="CommandLine" })
|
|
p.push('<Rule.Categories>')
|
|
for i = 1, #categories do
|
|
m.category(categories[i])
|
|
end
|
|
p.pop('</Rule.Categories>')
|
|
end
|
|
|
|
|
|
function m.category(cat)
|
|
local attribs = p.capture(function()
|
|
p.push()
|
|
p.w('Name="%s"', cat.name)
|
|
if cat.subtype then
|
|
p.w('Subtype="%s"', cat.subtype)
|
|
end
|
|
p.pop()
|
|
end)
|
|
|
|
p.push('<Category')
|
|
p.outln(attribs .. '>')
|
|
|
|
p.push('<Category.DisplayName>')
|
|
p.w('<sys:String>%s</sys:String>', cat.name)
|
|
p.pop('</Category.DisplayName>')
|
|
|
|
p.pop('</Category>')
|
|
end
|
|
|
|
|
|
|
|
---
|
|
-- Generate the list of property definitions.
|
|
---
|
|
|
|
function m.properties(r)
|
|
local defs = r.propertydefinition
|
|
for i = 1, #defs do
|
|
local def = defs[i]
|
|
if def.kind == "boolean" then
|
|
m.boolProperty(def)
|
|
elseif def.kind == "list" then
|
|
m.stringListProperty(def)
|
|
elseif type(def.values) == "table" then
|
|
m.enumProperty(def)
|
|
elseif def.kind and def.kind:startswith("list:") then
|
|
m.stringListProperty(def)
|
|
else
|
|
m.stringProperty(def)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function m.baseProperty(def, suffix)
|
|
local c = p.capture(function ()
|
|
p.w('Name="%s"', def.name)
|
|
p.w('HelpContext="0"')
|
|
p.w('DisplayName="%s"', def.display or def.name)
|
|
if def.description then
|
|
p.w('Description="%s"', def.description)
|
|
end
|
|
if def.category then
|
|
p.w('Category="%s"', def.category)
|
|
end
|
|
end)
|
|
if suffix then
|
|
c = c .. suffix
|
|
end
|
|
p.outln(c)
|
|
end
|
|
|
|
|
|
function m.boolProperty(def)
|
|
p.push('<BoolProperty')
|
|
m.baseProperty(def)
|
|
if def.switch then
|
|
p.w('Switch="%s"', def.switch)
|
|
end
|
|
p.w('/>')
|
|
p.pop()
|
|
end
|
|
|
|
|
|
function m.enumProperty(def)
|
|
p.push('<EnumProperty')
|
|
m.baseProperty(def, '>')
|
|
|
|
local values = def.values
|
|
local switches = def.switch or {}
|
|
|
|
local keys = table.keys(def.values)
|
|
table.sort(keys)
|
|
|
|
for _, key in pairs(keys) do
|
|
p.push('<EnumValue')
|
|
p.w('Name="%d"', key)
|
|
if switches[key] then
|
|
p.w('DisplayName="%s"', values[key])
|
|
if switches[key] then
|
|
p.w('Switch="%s"', switches[key])
|
|
end
|
|
else
|
|
p.w('DisplayName="%s"', values[key])
|
|
end
|
|
p.w('/>')
|
|
p.pop()
|
|
end
|
|
|
|
p.pop('</EnumProperty>')
|
|
end
|
|
|
|
|
|
function m.stringProperty(def)
|
|
p.push('<StringProperty')
|
|
m.baseProperty(def)
|
|
if def.switch then
|
|
p.w('Switch="%s"', def.switch)
|
|
end
|
|
p.w('/>')
|
|
p.pop()
|
|
end
|
|
|
|
|
|
function m.stringListProperty(def)
|
|
p.push('<StringListProperty')
|
|
m.baseProperty(def)
|
|
if def.separator then
|
|
p.w('Separator="%s"', def.separator)
|
|
end
|
|
if def.switch then
|
|
p.w('Switch="%s"', def.switch)
|
|
end
|
|
p.w('/>')
|
|
p.pop()
|
|
end
|
|
|
|
|
|
|
|
---
|
|
-- Implementations of individual elements.
|
|
---
|
|
|
|
function m.additionalDependencies(r)
|
|
p.push('<StringListProperty')
|
|
p.w('Name="AdditionalDependencies"')
|
|
p.w('DisplayName="Additional Dependencies"')
|
|
p.w('IncludeInCommandLine="False"')
|
|
p.w('Visible="false" />')
|
|
p.pop()
|
|
end
|
|
|
|
|
|
|
|
function m.additionalOptions(r)
|
|
p.push('<StringProperty')
|
|
p.w('Subtype="AdditionalOptions"')
|
|
p.w('Name="AdditionalOptions"')
|
|
p.w('Category="Command Line">')
|
|
p.push('<StringProperty.DisplayName>')
|
|
p.w('<sys:String>Additional Options</sys:String>')
|
|
p.pop('</StringProperty.DisplayName>')
|
|
p.push('<StringProperty.Description>')
|
|
p.w('<sys:String>Additional Options</sys:String>')
|
|
p.pop('</StringProperty.Description>')
|
|
p.pop('</StringProperty>')
|
|
end
|
|
|
|
|
|
|
|
function m.afterTargets(r)
|
|
p.push('<DynamicEnumProperty')
|
|
p.w('Name="%sAfterTargets"', r.name)
|
|
p.w('Category="General"')
|
|
p.w('EnumProvider="Targets"')
|
|
p.w('IncludeInCommandLine="False">')
|
|
|
|
p.push('<DynamicEnumProperty.DisplayName>')
|
|
p.w('<sys:String>Execute After</sys:String>')
|
|
p.pop('</DynamicEnumProperty.DisplayName>')
|
|
|
|
p.push('<DynamicEnumProperty.Description>')
|
|
p.w('<sys:String>Specifies the targets for the build customization to run after.</sys:String>')
|
|
p.pop('</DynamicEnumProperty.Description>')
|
|
|
|
p.push('<DynamicEnumProperty.ProviderSettings>')
|
|
p.push('<NameValuePair')
|
|
p.w('Name="Exclude"')
|
|
p.w('Value="^%sAfterTargets|^Compute" />', r.name)
|
|
p.pop()
|
|
p.pop('</DynamicEnumProperty.ProviderSettings>')
|
|
|
|
p.push('<DynamicEnumProperty.DataSource>')
|
|
p.push('<DataSource')
|
|
p.w('Persistence="ProjectFile"')
|
|
p.w('ItemType=""')
|
|
p.w('HasConfigurationCondition="true" />')
|
|
p.pop()
|
|
p.pop('</DynamicEnumProperty.DataSource>')
|
|
|
|
p.pop('</DynamicEnumProperty>')
|
|
end
|
|
|
|
|
|
|
|
function m.beforeTargets(r)
|
|
p.push('<DynamicEnumProperty')
|
|
p.w('Name="%sBeforeTargets"', r.name)
|
|
p.w('Category="General"')
|
|
p.w('EnumProvider="Targets"')
|
|
p.w('IncludeInCommandLine="False">')
|
|
|
|
p.push('<DynamicEnumProperty.DisplayName>')
|
|
p.w('<sys:String>Execute Before</sys:String>')
|
|
p.pop('</DynamicEnumProperty.DisplayName>')
|
|
|
|
p.push('<DynamicEnumProperty.Description>')
|
|
p.w('<sys:String>Specifies the targets for the build customization to run before.</sys:String>')
|
|
p.pop('</DynamicEnumProperty.Description>')
|
|
|
|
p.push('<DynamicEnumProperty.ProviderSettings>')
|
|
p.push('<NameValuePair')
|
|
p.w('Name="Exclude"')
|
|
p.w('Value="^%sBeforeTargets|^Compute" />', r.name)
|
|
p.pop()
|
|
p.pop('</DynamicEnumProperty.ProviderSettings>')
|
|
|
|
p.push('<DynamicEnumProperty.DataSource>')
|
|
p.push('<DataSource')
|
|
p.w('Persistence="ProjectFile"')
|
|
p.w('HasConfigurationCondition="true" />')
|
|
p.pop()
|
|
p.pop('</DynamicEnumProperty.DataSource>')
|
|
|
|
p.pop('</DynamicEnumProperty>')
|
|
end
|
|
|
|
|
|
|
|
function m.commandLineTemplate(r)
|
|
p.push('<StringProperty')
|
|
p.w('Name="CommandLineTemplate"')
|
|
p.w('DisplayName="Command Line"')
|
|
p.w('Visible="False"')
|
|
p.w('IncludeInCommandLine="False" />')
|
|
p.pop()
|
|
end
|
|
|
|
|
|
|
|
function m.contentType(r)
|
|
p.push('<ContentType')
|
|
p.w('Name="%s"', r.name)
|
|
p.w('DisplayName="%s"', r.display or r.name)
|
|
p.w('ItemType="%s" />', r.name)
|
|
p.pop()
|
|
end
|
|
|
|
|
|
|
|
function m.dataSource(r)
|
|
p.push('<Rule.DataSource>')
|
|
p.push('<DataSource')
|
|
p.w('Persistence="ProjectFile"')
|
|
p.w('ItemType="%s" />', r.name)
|
|
p.pop()
|
|
p.pop('</Rule.DataSource>')
|
|
end
|
|
|
|
|
|
|
|
function m.executionDescription(r)
|
|
p.push('<StringProperty')
|
|
p.w('Name="ExecutionDescription"')
|
|
p.w('DisplayName="Execution Description"')
|
|
p.w('Visible="False"')
|
|
p.w('IncludeInCommandLine="False" />')
|
|
p.pop()
|
|
end
|
|
|
|
|
|
|
|
function m.fileExtension(r)
|
|
for _, v in ipairs(r.fileextension) do
|
|
p.push('<FileExtension')
|
|
p.w('Name="*%s"', v)
|
|
p.w('ContentType="%s" />', r.name)
|
|
p.pop()
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function m.inputs(r)
|
|
p.push('<StringListProperty')
|
|
p.w('Name="Inputs"')
|
|
p.w('Category="Command Line"')
|
|
p.w('IsRequired="true"')
|
|
p.w('Switch=" ">')
|
|
|
|
p.push('<StringListProperty.DataSource>')
|
|
p.push('<DataSource')
|
|
p.w('Persistence="ProjectFile"')
|
|
p.w('ItemType="%s"', r.name)
|
|
p.w('SourceType="Item" />')
|
|
p.pop()
|
|
|
|
p.pop('</StringListProperty.DataSource>')
|
|
p.pop('</StringListProperty>')
|
|
end
|
|
|
|
|
|
|
|
function m.outputs(r)
|
|
p.push('<StringListProperty')
|
|
p.w('Name="Outputs"')
|
|
p.w('DisplayName="Outputs"')
|
|
p.w('Visible="False"')
|
|
p.w('IncludeInCommandLine="False" />')
|
|
p.pop()
|
|
end
|
|
|
|
|
|
|
|
function m.ruleItem(r)
|
|
p.push('<ItemType')
|
|
p.w('Name="%s"', r.name)
|
|
p.w('DisplayName="%s" />', r.display or r.name)
|
|
p.pop()
|
|
end
|
|
|
|
|
|
|
|
function m.projectSchemaDefinitions(r)
|
|
p.push('<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">')
|
|
end
|
|
|