First pass at refactoring functions implementation

This commit is contained in:
starkos 2008-11-22 20:10:37 +00:00
parent 870d9c65d2
commit 6eedbd8537
6 changed files with 323 additions and 292 deletions

View File

@ -66,8 +66,8 @@
<% if cfg.flags.NoFramePointer then %>
OmitFramePointers="<%= _VS.bool(true) %>"
<% end %>
<% if #cfg.incdirs > 0 then %>
AdditionalIncludeDirectories="<%= table.concat(premake.esc(cfg.incdirs), ";") %>"
<% if #cfg.includedirs > 0 then %>
AdditionalIncludeDirectories="<%= table.concat(premake.esc(cfg.includedirs), ";") %>"
<% end %>
<% if #cfg.defines > 0 then %>
PreprocessorDefinitions="<%= table.concat(premake.esc(cfg.defines), ";") %>"
@ -201,8 +201,8 @@
<% if #cfg.defines > 0 or #cfg.resdefines > 0 then %>
PreprocessorDefinitions="<%= table.concat(premake.esc(table.join(cfg.defines, cfg.resdefines)), ";") %>"
<% end %>
<% if #cfg.incdirs > 0 or #cfg.resincdirs > 0 then %>
AdditionalIncludeDirectories="<%= table.concat(premake.esc(table.join(cfg.incdirs, cfg.resincdirs)), ";") %>"
<% if #cfg.includedirs > 0 or #cfg.resincdirs > 0 then %>
AdditionalIncludeDirectories="<%= table.concat(premake.esc(table.join(cfg.includedirs, cfg.resincdirs)), ";") %>"
<% end %>
/>
<% elseif (block == "VCWebDeploymentTool") then %>

View File

@ -5,6 +5,18 @@
--
--
-- These fields should *not* be copied into configurations.
--
premake.nocopy =
{
"blocks",
"keywords",
"projects"
}
--
-- Returns an iterator for a project's configurations.
--
@ -94,24 +106,26 @@
end
cfg.files = files
-- fix up paths, making them relative to project location where needed
for _,key in ipairs(premake.locationrelative) do
if (type(cfg[key]) == "table") then
for i,p in ipairs(cfg[key]) do
cfg[key][i] = path.getrelative(prj.location, p)
end
else
if (cfg[key]) then
cfg[key] = path.getrelative(prj.location, cfg[key])
for name, field in pairs(premake.fields) do
-- fix up paths, making them relative to project where needed
if (field.kind == "path" or field.kind == "dirlist" or field.kind == "filelist") then
if (type(cfg[name]) == "table") then
for i,p in ipairs(cfg[name]) do
cfg[name][i] = path.getrelative(prj.location, p)
end
else
if (cfg[name]) then
cfg[name] = path.getrelative(prj.location, cfg[name])
end
end
end
end
-- re-key flag fields
for _,key in ipairs(premake.flagfields) do
local field = cfg[key]
for _,flag in ipairs(field) do
field[flag] = true
-- re-key flag fields
if (field.isflags) then
local values = cfg[name]
for _, flag in ipairs(values) do
values[flag] = true
end
end
end

View File

@ -6,114 +6,272 @@
--
-- Validation lists for fields with constrained value sets.
-- Here I define all of the getter/setter functions as metadata. The actual
-- functions are built programmatically below.
--
local valid_flags =
{
"Dylib",
"ExtraWarnings",
"FatalWarnings",
"Managed",
"NativeWChar",
"No64BitChecks",
"NoEditAndContinue",
"NoExceptions",
"NoFramePointer",
"NoImportLib",
"NoManifest",
"NoNativeWChar",
"NoPCH",
"NoRTTI",
"Optimize",
"OptimizeSize",
"OptimizeSpeed",
"SEH",
"StaticRuntime",
"Symbols",
"Unicode",
"WinMain"
}
local valid_kinds =
premake.fields =
{
"ConsoleApp",
"WindowedApp",
"StaticLib",
"SharedLib"
basedir =
{
kind = "path",
scope = "container",
},
buildoptions =
{
kind = "list",
scope = "config",
},
configurations =
{
kind = "list",
scope = "solution",
},
defines =
{
kind = "list",
scope = "config",
},
excludes =
{
kind = "filelist",
scope = "container",
},
files =
{
kind = "filelist",
scope = "container",
},
flags =
{
kind = "list",
scope = "config",
isflags = true,
allowed = {
"Dylib",
"ExtraWarnings",
"FatalWarnings",
"Managed",
"NativeWChar",
"No64BitChecks",
"NoEditAndContinue",
"NoExceptions",
"NoFramePointer",
"NoImportLib",
"NoManifest",
"NoNativeWChar",
"NoPCH",
"NoRTTI",
"Optimize",
"OptimizeSize",
"OptimizeSpeed",
"SEH",
"StaticRuntime",
"Symbols",
"Unicode",
"WinMain"
}
},
implibdir =
{
kind = "path",
scope = "config",
},
implibextension =
{
kind = "string",
scope = "config",
},
implibname =
{
kind = "string",
scope = "config",
},
implibprefix =
{
kind = "string",
scope = "config",
},
includedirs =
{
kind = "dirlist",
scope = "config",
},
kind =
{
kind = "string",
scope = "config",
allowed = {
"ConsoleApp",
"WindowedApp",
"StaticLib",
"SharedLib"
}
},
language =
{
kind = "string",
scope = "container",
allowed = {
"C",
"C++"
}
},
libdirs =
{
kind = "dirlist",
scope = "config",
},
linkoptions =
{
kind = "list",
scope = "config",
},
links =
{
kind = "list",
scope = "config",
},
location =
{
kind = "path",
scope = "config",
},
objdir =
{
kind = "path",
scope = "config",
},
pchheader =
{
kind = "path",
scope = "config",
},
pchsource =
{
kind = "path",
scope = "config",
},
resdefines =
{
kind = "list",
scope = "config",
},
resincludedirs =
{
kind = "dirlist",
scope = "config",
},
resoptions =
{
kind = "list",
scope = "config",
},
targetdir =
{
kind = "path",
scope = "config",
},
targetextension =
{
kind = "string",
scope = "config",
},
targetname =
{
kind = "string",
scope = "config",
},
targetprefix =
{
kind = "string",
scope = "config",
},
uuid =
{
kind = "string",
scope = "container",
allowed = function(value)
local ok = true
if (#value ~= 36) then ok = false end
for i=1,36 do
local ch = value:sub(i,i)
if (not ch:find("[ABCDEFabcdef0123456789-]")) then ok = false end
end
if (value:sub(9,9) ~= "-") then ok = false end
if (value:sub(14,14) ~= "-") then ok = false end
if (value:sub(19,19) ~= "-") then ok = false end
if (value:sub(24,24) ~= "-") then ok = false end
if (not ok) then
return nil, "invalid UUID"
end
return value
end
},
}
--
-- The is the actual implementation of a getter/setter.
--
local function accessor(name, value)
local kind = premake.fields[name].kind
local scope = premake.fields[name].scope
local allowed = premake.fields[name].allowed
if (kind == "string") then
return premake.setstring(scope, name, value, allowed)
elseif (kind == "path") then
return premake.setstring(scope, name, path.getabsolute(value))
elseif (kind == "list") then
return premake.setarray(scope, name, value, allowed)
elseif (kind == "dirlist") then
return premake.setdirarray(scope, name, value)
elseif (kind == "filelist") then
return premake.setfilearray(scope, name, value)
end
end
--
-- Build all of the getter/setter functions from the metadata above.
--
local valid_languages =
{
"C",
"C++",
}
--
-- These list fields should be initialized to an empty table.
--
premake.listfields =
{
"buildoptions",
"defines",
"excludes",
"files",
"flags",
"incdirs",
"libdirs",
"linkoptions",
"links",
"resdefines",
"resincdirs",
"resoptions",
}
--
-- These fields should *not* be copied into configurations.
--
premake.nocopy =
{
"blocks",
"keywords",
"projects"
}
--
-- These fields should be converted from absolute paths into project
-- location relative before being returned in a configuration.
--
premake.locationrelative =
{
"basedir",
"excludes",
"files",
"incdirs",
"libdirs",
"objdir",
"pchheader",
"pchsource",
"resincdirs",
"targetdir",
}
--
-- Flag fields are converted from arrays like:
-- { "Optimize", "NoExceptions" }
-- to mixed tables like:
-- { "Optimize", "NoExceptions", Optimize=true, NoExceptions=true }
--
premake.flagfields =
{
"flags",
}
for name,_ in pairs(premake.fields) do
_G[name] = function(value)
return accessor(name, value)
end
end
@ -121,11 +279,6 @@
-- Project API functions
--
function buildoptions(value)
return premake.setarray("config", "buildoptions", value)
end
function configuration(keywords)
local container, err = premake.getobject("container")
if (not container) then
@ -141,109 +294,16 @@
else
cfg.keywords = { keywords }
end
for _, name in ipairs(premake.listfields) do
cfg[name] = { }
for name, field in pairs(premake.fields) do
if (field.kind ~= "string" and field.kind ~= "path") then
cfg[name] = { }
end
end
return cfg
end
function configurations(value)
return premake.setarray("solution", "configurations", value)
end
function defines(value)
return premake.setarray("config", "defines", value)
end
function excludes(value)
return premake.setfilearray("container", "excludes", value)
end
function files(value)
return premake.setfilearray("container", "files", value)
end
function flags(value)
return premake.setarray("config", "flags", value, valid_flags)
end
function implibname(value)
return premake.setstring("config", "implibname", value)
end
function implibdir(value)
return premake.setstring("config", "implibdir", path.getabsolute(value))
end
function implibextension(value)
return premake.setstring("config", "implibextension", value)
end
function implibprefix(value)
return premake.setstring("config", "implibprefix", value)
end
function includedirs(value)
return premake.setdirarray("config", "incdirs", value)
end
function kind(value)
return premake.setstring("config", "kind", value, valid_kinds)
end
function language(value)
return premake.setstring("container", "language", value, valid_languages)
end
function libdirs(value)
return premake.setdirarray("config", "libdirs", value)
end
function linkoptions(value)
return premake.setarray("config", "linkoptions", value)
end
function links(value)
return premake.setarray("config", "links", value)
end
function location(value)
return premake.setstring("container", "location", path.getabsolute(value))
end
function objdir(value)
return premake.setstring("config", "objdir", path.getabsolute(value))
end
function pchheader(value)
return premake.setstring("config", "pchheader", path.getabsolute(value))
end
function pchsource(value)
return premake.setstring("config", "pchsource", path.getabsolute(value))
end
function project(name)
if (name) then
@ -294,21 +354,6 @@
end
function resdefines(value)
return premake.setarray("config", "resdefines", value)
end
function resincludedirs(value)
return premake.setdirarray("config", "resincdirs", value)
end
function resoptions(value)
return premake.setarray("config", "resoptions", value)
end
function solution(name)
if (name) then
premake.CurrentContainer = _SOLUTIONS[name]
@ -346,42 +391,4 @@
return premake.CurrentContainer
end
function targetname(value)
return premake.setstring("config", "targetname", value)
end
function targetdir(value)
return premake.setstring("config", "targetdir", path.getabsolute(value))
end
function targetextension(value)
return premake.setstring("config", "targetextension", value)
end
function targetprefix(value)
return premake.setstring("config", "targetprefix", value)
end
function uuid(value)
if (value) then
local ok = true
if (#value ~= 36) then ok = false end
for i=1,36 do
local ch = g:sub(i,i)
if (not ch:find("[ABCDEFabcdef0123456789-]")) then ok = false end
end
if (g:sub(9,9) ~= "-") then ok = false end
if (g:sub(14,14) ~= "-") then ok = false end
if (g:sub(19,19) ~= "-") then ok = false end
if (g:sub(24,24) ~= "-") then ok = false end
if (not ok) then
error("invalid UUID", 2)
end
end
return premake.setstring("container", "uuid", value)
end

View File

@ -77,7 +77,7 @@
function premake.tools.gcc.make_includes(cfg)
return table.implode(cfg.incdirs, '-I "', '"', ' ')
return table.implode(cfg.includedirs, '-I "', '"', ' ')
end

View File

@ -41,10 +41,15 @@
function premake.checkvalue(value, allowed)
if (allowed) then
for _,v in ipairs(allowed) do
if (value:lower() == v:lower()) then
return v
if (type(allowed) == "function") then
return allowed(value)
else
for _,v in ipairs(allowed) do
if (value:lower() == v:lower()) then
return v
end
end
return nil, "invalid value '" .. value .. "'"
end
else
return value

View File

@ -200,20 +200,22 @@
container[fieldname] = { }
end
local function doinsert(value)
local function doinsert(value, depth)
if (type(value) == "table") then
for _,v in ipairs(value) do
doinsert(v)
doinsert(v, depth + 1)
end
else
local v = premake.checkvalue(value, allowed)
if (not v) then error("invalid value '" .. value .. "'", 3) end
table.insert(container[fieldname], v)
value, err = premake.checkvalue(value, allowed)
if (not value) then
error(err, depth)
end
table.insert(container[fieldname], value)
end
end
if (value) then
doinsert(value)
doinsert(value, 5)
end
return container[fieldname]
@ -267,14 +269,17 @@
-- find the container for this value
local container, err = premake.getobject(ctype)
if (not container) then
error(err, 3)
error(err, 4)
end
-- if a value was provided, set it
if (value) then
local v = premake.checkvalue(value, allowed)
if (not v) then error("invalid value '" .. value .. "'", 3) end
container[fieldname] = v
value, err = premake.checkvalue(value, allowed)
if (not value) then
error(err, 4)
end
container[fieldname] = value
end
return container[fieldname]