Initial community commit
This commit is contained in:
71
Src/external_dependencies/openmpt-trunk/include/premake/src/_manifest.lua
vendored
Normal file
71
Src/external_dependencies/openmpt-trunk/include/premake/src/_manifest.lua
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
--
|
||||
-- _manifest.lua
|
||||
-- Manage the list of built-in Premake scripts.
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
-- The master list of built-in scripts. Order is important! If you want to
|
||||
-- build a new script into Premake, add it to this list.
|
||||
|
||||
return
|
||||
{
|
||||
-- core files
|
||||
"base/_foundation.lua",
|
||||
"base/string.lua",
|
||||
"base/table.lua",
|
||||
"base/path.lua",
|
||||
"base/os.lua",
|
||||
"base/io.lua",
|
||||
"base/tools.lua",
|
||||
"base/tree.lua",
|
||||
"base/globals.lua",
|
||||
"base/semver.lua",
|
||||
"base/http.lua",
|
||||
"base/json.lua",
|
||||
"base/jsonwrapper.lua",
|
||||
"base/languages.lua",
|
||||
"base/term.lua",
|
||||
|
||||
-- configuration data
|
||||
"base/field.lua",
|
||||
"base/criteria.lua",
|
||||
"base/detoken.lua",
|
||||
"base/configset.lua",
|
||||
"base/context.lua",
|
||||
"base/container.lua",
|
||||
|
||||
-- runtime switches
|
||||
"base/option.lua",
|
||||
"base/action.lua",
|
||||
|
||||
-- project script setup
|
||||
"base/api.lua",
|
||||
|
||||
-- project objects
|
||||
"base/global.lua",
|
||||
"base/workspace.lua",
|
||||
"base/group.lua",
|
||||
"base/project.lua",
|
||||
"base/config.lua",
|
||||
"base/fileconfig.lua",
|
||||
"base/rule.lua",
|
||||
|
||||
-- project script processing
|
||||
"base/oven.lua",
|
||||
"base/validation.lua",
|
||||
"base/premake.lua",
|
||||
"base/help.lua",
|
||||
|
||||
-- tool APIs
|
||||
"tools/dotnet.lua",
|
||||
"tools/gcc.lua",
|
||||
"tools/msc.lua",
|
||||
"tools/snc.lua",
|
||||
"tools/clang.lua",
|
||||
"tools/mingw.lua",
|
||||
|
||||
-- Clean action
|
||||
"actions/clean/_clean.lua",
|
||||
|
||||
"_premake_init.lua",
|
||||
}
|
||||
15
Src/external_dependencies/openmpt-trunk/include/premake/src/_modules.lua
vendored
Normal file
15
Src/external_dependencies/openmpt-trunk/include/premake/src/_modules.lua
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
--
|
||||
-- _modules.lua
|
||||
-- The list of core modules to preload on startup
|
||||
-- Copyright (c) 2015 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
return {
|
||||
"gmake",
|
||||
"vstudio",
|
||||
"xcode",
|
||||
"codelite",
|
||||
"gmake2",
|
||||
"d",
|
||||
"android",
|
||||
}
|
||||
1928
Src/external_dependencies/openmpt-trunk/include/premake/src/_premake_init.lua
vendored
Normal file
1928
Src/external_dependencies/openmpt-trunk/include/premake/src/_premake_init.lua
vendored
Normal file
File diff suppressed because it is too large
Load Diff
398
Src/external_dependencies/openmpt-trunk/include/premake/src/_premake_main.lua
vendored
Normal file
398
Src/external_dependencies/openmpt-trunk/include/premake/src/_premake_main.lua
vendored
Normal file
@@ -0,0 +1,398 @@
|
||||
--
|
||||
-- _premake_main.lua
|
||||
-- Script-side entry point for the main program logic.
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local shorthelp = "Type 'premake5 --help' for help"
|
||||
local versionhelp = "premake5 (Premake Build Script Generator) %s"
|
||||
local startTime = os.clock()
|
||||
|
||||
-- set a global.
|
||||
_PREMAKE_STARTTIME = startTime
|
||||
|
||||
-- Load the collection of core scripts, required for everything else to work
|
||||
|
||||
local modules = dofile("_modules.lua")
|
||||
local manifest = dofile("_manifest.lua")
|
||||
for i = 1, #manifest do
|
||||
dofile(manifest[i])
|
||||
end
|
||||
|
||||
|
||||
-- Create namespaces for myself
|
||||
|
||||
local p = premake
|
||||
p.main = {}
|
||||
|
||||
local m = p.main
|
||||
|
||||
|
||||
-- Keep a table of modules that have been preloaded, and their associated
|
||||
-- "should load" test functions.
|
||||
|
||||
m._preloaded = {}
|
||||
|
||||
|
||||
---
|
||||
-- Add a new module loader that knows how to use the Premake paths like
|
||||
-- PREMAKE_PATH and the --scripts option, and follows the module/module.lua
|
||||
-- naming convention.
|
||||
---
|
||||
|
||||
function m.installModuleLoader()
|
||||
if not os.ishost('windows') then
|
||||
local premakeDir = path.getdirectory(_PREMAKE_COMMAND)
|
||||
package.cpath = package.cpath .. ';' .. premakeDir .. '/?.so'
|
||||
end
|
||||
table.insert(package.searchers, 2, m.moduleLoader)
|
||||
end
|
||||
|
||||
function m.moduleLoader(name)
|
||||
local dir = path.getdirectory(name)
|
||||
local base = path.getname(name)
|
||||
|
||||
if dir ~= "." then
|
||||
dir = dir .. "/" .. base
|
||||
else
|
||||
dir = base
|
||||
end
|
||||
|
||||
local full = dir .. "/" .. base .. ".lua"
|
||||
|
||||
-- list of paths where to look for the module
|
||||
local paths = {
|
||||
".modules/" .. full,
|
||||
"modules/" .. full,
|
||||
full,
|
||||
name .. ".lua"
|
||||
}
|
||||
|
||||
-- If this module is being requested by an embedded script, favor embedded modules.
|
||||
-- This helps prevent local scripts from interfering with release build bootstrapping.
|
||||
if string.startswith(_SCRIPT_DIR, '$/') then
|
||||
table.insert(paths, 1, '$/' .. full)
|
||||
end
|
||||
|
||||
-- try to locate the module
|
||||
for _, p in ipairs(paths) do
|
||||
local file = os.locate(p)
|
||||
if file then
|
||||
local chunk, err = loadfile(file)
|
||||
if chunk then
|
||||
return chunk
|
||||
end
|
||||
if err then
|
||||
return "\n\tload error " .. err
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- didn't find the module in supported paths, try the embedded scripts
|
||||
for _, p in ipairs(paths) do
|
||||
local chunk, err = loadfile("$/" .. p)
|
||||
if chunk then
|
||||
return chunk
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Prepare the script environment; anything that should be done
|
||||
-- before the system script gets a chance to run.
|
||||
---
|
||||
|
||||
function m.prepareEnvironment()
|
||||
math.randomseed(os.time())
|
||||
_PREMAKE_DIR = path.getdirectory(_PREMAKE_COMMAND)
|
||||
p.path = p.path .. ";" .. _PREMAKE_DIR .. ";" .. _MAIN_SCRIPT_DIR
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Load the required core modules that are shipped as part of Premake and
|
||||
-- expected to be present at startup. If a _preload.lua script is present,
|
||||
-- that script is run and the return value (a "should load" test) is cached
|
||||
-- to be called after baking is complete. Otherwise the module's main script
|
||||
-- is run immediately.
|
||||
---
|
||||
|
||||
function m.preloadModules()
|
||||
for i = 1, #modules do
|
||||
local name = modules[i]
|
||||
local preloader = name .. "/_preload.lua"
|
||||
preloader = os.locate("modules/" .. preloader) or os.locate(preloader)
|
||||
if preloader then
|
||||
local modulePath = path.getdirectory(preloader)
|
||||
m._preloaded[modulePath] = include(preloader)
|
||||
if not m._preloaded[modulePath] then
|
||||
p.warn("module '%s' should return function from _preload.lua", name)
|
||||
end
|
||||
else
|
||||
require(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Look for and run the system-wide configuration script; make sure any
|
||||
-- configuration scoping gets cleared before continuing.
|
||||
---
|
||||
|
||||
function m.runSystemScript()
|
||||
dofileopt(_OPTIONS["systemscript"] or { "premake5-system.lua", "premake-system.lua" })
|
||||
filter {}
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Look for a user project script, and set up the related global
|
||||
-- variables if I can find one.
|
||||
---
|
||||
|
||||
function m.locateUserScript()
|
||||
local defaults = { "premake5.lua", "premake4.lua" }
|
||||
for i = 1, #defaults do
|
||||
if os.isfile(defaults[i]) then
|
||||
_MAIN_SCRIPT = defaults[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not _MAIN_SCRIPT then
|
||||
_MAIN_SCRIPT = defaults[1]
|
||||
end
|
||||
|
||||
if _OPTIONS.file then
|
||||
_MAIN_SCRIPT = _OPTIONS.file
|
||||
end
|
||||
|
||||
_MAIN_SCRIPT = path.getabsolute(_MAIN_SCRIPT)
|
||||
_MAIN_SCRIPT_DIR = path.getdirectory(_MAIN_SCRIPT)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Set the action to be performed from the command line arguments.
|
||||
---
|
||||
|
||||
function m.prepareAction()
|
||||
p.action.set(_ACTION)
|
||||
|
||||
-- Allow the action to initialize stuff.
|
||||
local action = p.action.current()
|
||||
if action then
|
||||
p.action.initialize(action.trigger)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- If there is a project script available, run it to get the
|
||||
-- project information, available options and actions, etc.
|
||||
---
|
||||
|
||||
function m.runUserScript()
|
||||
if os.isfile(_MAIN_SCRIPT) then
|
||||
dofile(_MAIN_SCRIPT)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Run the interactive prompt, if requested.
|
||||
---
|
||||
|
||||
function m.checkInteractive()
|
||||
if _OPTIONS.interactive then
|
||||
debug.prompt()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Validate and process the command line options and arguments.
|
||||
---
|
||||
|
||||
function m.processCommandLine()
|
||||
-- Process special options
|
||||
if (_OPTIONS["version"]) then
|
||||
printf(versionhelp, _PREMAKE_VERSION)
|
||||
os.exit(0)
|
||||
end
|
||||
|
||||
if (_OPTIONS["help"]) then
|
||||
p.showhelp()
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Validate the command-line arguments. This has to happen after the
|
||||
-- script has run to allow for project-specific options
|
||||
ok, err = p.option.validate(_OPTIONS)
|
||||
if not ok then
|
||||
print("Error: " .. err)
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- If no further action is possible, show a short help message
|
||||
if not _OPTIONS.interactive then
|
||||
if not _ACTION then
|
||||
print(shorthelp)
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
local action = p.action.current()
|
||||
if not action then
|
||||
print("Error: no such action '" .. _ACTION .. "'")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
if p.action.isConfigurable() and not os.isfile(_MAIN_SCRIPT) then
|
||||
print(string.format("No Premake script (%s) found!", path.getname(_MAIN_SCRIPT)))
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- Start up MobDebug and try to hook up with ZeroBrane
|
||||
---
|
||||
|
||||
function m.tryHookDebugger()
|
||||
|
||||
if (_OPTIONS["debugger"]) then
|
||||
print("Loading luasocket...")
|
||||
require('luasocket')
|
||||
print("Starting debugger...")
|
||||
local mobdebug = require('mobdebug')
|
||||
mobdebug.start()
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- Override point, for logic that should run before baking.
|
||||
---
|
||||
|
||||
function m.preBake()
|
||||
if p.action.isConfigurable() then
|
||||
print("Building configurations...")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- "Bake" the project information, preparing it for use by the action.
|
||||
---
|
||||
|
||||
function m.bake()
|
||||
if p.action.isConfigurable() then
|
||||
p.oven.bake()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Override point, for logic that should run after baking but before
|
||||
-- the configurations are validated.
|
||||
---
|
||||
|
||||
function m.postBake()
|
||||
local function shouldLoad(func)
|
||||
for wks in p.global.eachWorkspace() do
|
||||
for prj in p.workspace.eachproject(wks) do
|
||||
for cfg in p.project.eachconfig(prj) do
|
||||
if func(cfg) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- any modules need to load to support this project?
|
||||
for modulePath, func in pairs(m._preloaded) do
|
||||
local moduleName = path.getbasename(modulePath)
|
||||
if not package.loaded[moduleName] and shouldLoad(func) then
|
||||
_SCRIPT_DIR = modulePath
|
||||
require(moduleName)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Sanity check the current project setup.
|
||||
---
|
||||
|
||||
function m.validate()
|
||||
if p.action.isConfigurable() then
|
||||
p.container.validate(p.api.rootContainer())
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Override point, for logic that should run after validation and
|
||||
-- before the action takes control.
|
||||
---
|
||||
|
||||
function m.preAction()
|
||||
local action = p.action.current()
|
||||
printf("Running action '%s'...", action.trigger)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Hand over control to the action.
|
||||
---
|
||||
|
||||
function m.callAction()
|
||||
local action = p.action.current()
|
||||
p.action.call(action.trigger)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Processing is complete.
|
||||
---
|
||||
|
||||
function m.postAction()
|
||||
if p.action.isConfigurable() then
|
||||
local duration = math.floor((os.clock() - startTime) * 1000);
|
||||
printf("Done (%dms).", duration)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Script-side program entry point.
|
||||
--
|
||||
|
||||
m.elements = {
|
||||
m.tryHookDebugger,
|
||||
m.installModuleLoader,
|
||||
m.locateUserScript,
|
||||
m.prepareEnvironment,
|
||||
m.preloadModules,
|
||||
m.runSystemScript,
|
||||
m.prepareAction,
|
||||
m.runUserScript,
|
||||
m.checkInteractive,
|
||||
m.processCommandLine,
|
||||
m.preBake,
|
||||
m.bake,
|
||||
m.postBake,
|
||||
m.validate,
|
||||
m.preAction,
|
||||
m.callAction,
|
||||
m.postAction,
|
||||
}
|
||||
|
||||
function _premake_main()
|
||||
p.callArray(m.elements)
|
||||
return 0
|
||||
end
|
||||
21
Src/external_dependencies/openmpt-trunk/include/premake/src/actions/clean/_clean.lua
vendored
Normal file
21
Src/external_dependencies/openmpt-trunk/include/premake/src/actions/clean/_clean.lua
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
--
|
||||
-- _clean.lua
|
||||
-- The "clean" action: removes all generated files.
|
||||
-- Copyright (c) 2002-2012 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
premake.clean = {}
|
||||
|
||||
|
||||
--
|
||||
-- Register the "clean" action.
|
||||
--
|
||||
|
||||
newaction {
|
||||
trigger = "clean",
|
||||
description = "Remove all binaries and generated files",
|
||||
|
||||
execute = function()
|
||||
print("** The clean action has not yet been ported")
|
||||
end
|
||||
}
|
||||
438
Src/external_dependencies/openmpt-trunk/include/premake/src/base/_foundation.lua
vendored
Normal file
438
Src/external_dependencies/openmpt-trunk/include/premake/src/base/_foundation.lua
vendored
Normal file
@@ -0,0 +1,438 @@
|
||||
---
|
||||
-- Base definitions required by all the other scripts.
|
||||
-- @copyright 2002-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
premake = premake or {}
|
||||
premake._VERSION = _PREMAKE_VERSION
|
||||
package.loaded["premake"] = premake
|
||||
|
||||
premake.modules = {}
|
||||
premake.extensions = premake.modules
|
||||
|
||||
local semver = dofile('semver.lua')
|
||||
local p = premake
|
||||
|
||||
|
||||
-- Keep track of warnings that have been shown, so they don't get shown twice
|
||||
|
||||
local _warnings = {}
|
||||
|
||||
-- Keep track of aliased functions, so I can resolve to canonical names
|
||||
|
||||
local _aliases = {}
|
||||
|
||||
--
|
||||
-- Define some commonly used symbols, for future-proofing.
|
||||
--
|
||||
|
||||
premake.C = "C"
|
||||
premake.C7 = "c7"
|
||||
premake.CLANG = "clang"
|
||||
premake.CONSOLEAPP = "ConsoleApp"
|
||||
premake.CPP = "C++"
|
||||
premake.CSHARP = "C#"
|
||||
premake.GCC = "gcc"
|
||||
premake.HAIKU = "haiku"
|
||||
premake.ANDROID = "android"
|
||||
premake.IOS = "ios"
|
||||
premake.LINUX = "linux"
|
||||
premake.MACOSX = "macosx"
|
||||
premake.MAKEFILE = "Makefile"
|
||||
premake.MBCS = "MBCS"
|
||||
premake.NONE = "None"
|
||||
premake.DEFAULT = "Default"
|
||||
premake.OBJECTIVEC = "Objective-C"
|
||||
premake.OBJECTIVECPP = "Objective-C++"
|
||||
premake.ON = "On"
|
||||
premake.OFF = "Off"
|
||||
premake.POSIX = "posix"
|
||||
premake.PS3 = "ps3"
|
||||
premake.SHAREDITEMS = "SharedItems"
|
||||
premake.SHAREDLIB = "SharedLib"
|
||||
premake.STATICLIB = "StaticLib"
|
||||
premake.UNICODE = "Unicode"
|
||||
premake.UNIVERSAL = "universal"
|
||||
premake.UTILITY = "Utility"
|
||||
premake.PACKAGING = "Packaging"
|
||||
premake.WINDOWEDAPP = "WindowedApp"
|
||||
premake.WINDOWS = "windows"
|
||||
premake.X86 = "x86"
|
||||
premake.X86_64 = "x86_64"
|
||||
premake.ARM = "ARM"
|
||||
premake.ARM64 = "ARM64"
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Provide an alias for a function in a namespace. Calls to the alias will
|
||||
-- invoke the canonical function, and attempts to override the alias will
|
||||
-- instead override the canonical call.
|
||||
--
|
||||
-- @param scope
|
||||
-- The table containing the function to be overridden. Use _G for
|
||||
-- global functions.
|
||||
-- @param canonical
|
||||
-- The name of the function to be aliased (a string value)
|
||||
-- @param alias
|
||||
-- The new alias for the function (another string value).
|
||||
---
|
||||
|
||||
function p.alias(scope, canonical, alias)
|
||||
scope, canonical = p.resolveAlias(scope, canonical)
|
||||
if not scope[canonical] then
|
||||
error("unable to alias '" .. canonical .. "'; no such function", 2)
|
||||
end
|
||||
|
||||
_aliases[scope] = _aliases[scope] or {}
|
||||
_aliases[scope][alias] = canonical
|
||||
|
||||
scope[alias] = function(...)
|
||||
return scope[canonical](...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Call a list of functions.
|
||||
--
|
||||
-- @param funcs
|
||||
-- The list of functions to be called, or a function that can be called
|
||||
-- to build and return the list. If this is a function, it will be called
|
||||
-- with all of the additional arguments (below).
|
||||
-- @param ...
|
||||
-- An optional set of arguments to be passed to each of the functions as
|
||||
-- as they are called.
|
||||
---
|
||||
|
||||
function premake.callArray(funcs, ...)
|
||||
if type(funcs) == "function" then
|
||||
funcs = funcs(...)
|
||||
end
|
||||
if funcs then
|
||||
for i = 1, #funcs do
|
||||
funcs[i](...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- TODO: THIS IMPLEMENTATION IS GOING AWAY
|
||||
|
||||
function premake.callarray(namespace, array, ...)
|
||||
local n = #array
|
||||
for i = 1, n do
|
||||
local fn = namespace[array[i]]
|
||||
if not fn then
|
||||
error(string.format("Unable to find function '%s'", array[i]))
|
||||
end
|
||||
fn(...)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Compare a version string that uses semver semantics against a
|
||||
-- version comparision string. Comparisions take the form of ">=5.0" (5.0 or
|
||||
-- later), "5.0" (5.0 or later), ">=5.0 <6.0" (5.0 or later but not 6.0 or
|
||||
-- later).
|
||||
--
|
||||
-- @param version
|
||||
-- The version to be tested.
|
||||
-- @param checks
|
||||
-- The comparision string to be evaluated.
|
||||
-- @return
|
||||
-- True if the comparisions pass, false if any fail.
|
||||
---
|
||||
|
||||
function p.checkVersion(version, checks)
|
||||
if not version then
|
||||
return false
|
||||
end
|
||||
|
||||
-- try to parse semver, if it fails, it's not semver compatible and we cannot compare, in which case
|
||||
-- we're going to ignore the checkVersion entirely, but warn.
|
||||
if not premake.isSemVer(version) then
|
||||
p.warn("'" .. version .. "' is not semver compatible, and cannot be compared against '" .. checks .. "'.");
|
||||
return true
|
||||
end
|
||||
|
||||
-- now compare the semver against the checks.
|
||||
local function eq(a, b) return a == b end
|
||||
local function le(a, b) return a <= b end
|
||||
local function lt(a, b) return a < b end
|
||||
local function ge(a, b) return a >= b end
|
||||
local function gt(a, b) return a > b end
|
||||
local function compat(a, b) return a ^ b end
|
||||
|
||||
version = semver(version)
|
||||
checks = string.explode(checks, " ", true)
|
||||
for i = 1, #checks do
|
||||
local check = checks[i]
|
||||
local func
|
||||
if check:startswith(">=") then
|
||||
func = ge
|
||||
check = check:sub(3)
|
||||
elseif check:startswith(">") then
|
||||
func = gt
|
||||
check = check:sub(2)
|
||||
elseif check:startswith("<=") then
|
||||
func = le
|
||||
check = check:sub(3)
|
||||
elseif check:startswith("<") then
|
||||
func = lt
|
||||
check = check:sub(2)
|
||||
elseif check:startswith("=") then
|
||||
func = eq
|
||||
check = check:sub(2)
|
||||
elseif check:startswith("^") then
|
||||
func = compat
|
||||
check = check:sub(2)
|
||||
else
|
||||
func = ge
|
||||
end
|
||||
|
||||
check = semver(check)
|
||||
if not func(version, check) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
function premake.clearWarnings()
|
||||
_warnings = {}
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Raise an error, with a formatted message built from the provided
|
||||
-- arguments.
|
||||
--
|
||||
-- @param message
|
||||
-- The error message, which may contain string formatting tokens.
|
||||
-- @param ...
|
||||
-- Values to fill in the string formatting tokens.
|
||||
--
|
||||
|
||||
function premake.error(message, ...)
|
||||
error(string.format("** Error: " .. message, ...), 0)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Finds the correct premake script filename to be run.
|
||||
--
|
||||
-- @param fname
|
||||
-- The filename of the script to run.
|
||||
-- @return
|
||||
-- The correct location and filename of the script to run.
|
||||
--
|
||||
|
||||
function premake.findProjectScript(fname)
|
||||
return os.locate(fname, fname .. ".lua", path.join(fname, "premake5.lua"), path.join(fname, "premake4.lua"))
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- "Immediate If" - returns one of the two values depending on the value
|
||||
-- of the provided condition. Note that both the true and false expressions
|
||||
-- will be evaluated regardless of the condition, even if only one result
|
||||
-- is returned.
|
||||
--
|
||||
-- @param condition
|
||||
-- A boolean condition, determining which value gets returned.
|
||||
-- @param trueValue
|
||||
-- The value to return if the condition is true.
|
||||
-- @param falseValue
|
||||
-- The value to return if the condition is false.
|
||||
-- @return
|
||||
-- One of trueValue or falseValue.
|
||||
---
|
||||
|
||||
function iif(condition, trueValue, falseValue)
|
||||
if condition then
|
||||
return trueValue
|
||||
else
|
||||
return falseValue
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Override an existing function with a new implementation; the original
|
||||
-- function is passed as the first argument to the replacement when called.
|
||||
--
|
||||
-- @param scope
|
||||
-- The table containing the function to be overridden. Use _G for
|
||||
-- global functions.
|
||||
-- @param name
|
||||
-- The name of the function to override (a string value).
|
||||
-- @param repl
|
||||
-- The replacement function. The first argument to the function
|
||||
-- will be the original implementation, followed by the arguments
|
||||
-- passed to the original call.
|
||||
---
|
||||
|
||||
function premake.override(scope, name, repl)
|
||||
scope, name = p.resolveAlias(scope, name)
|
||||
|
||||
local original = scope[name]
|
||||
if not original then
|
||||
error("unable to override '" .. name .. "'; no such function", 2)
|
||||
end
|
||||
|
||||
scope[name] = function(...)
|
||||
return repl(original, ...)
|
||||
end
|
||||
|
||||
-- Functions from premake.main are special in that they are fetched
|
||||
-- from an array, which can be modified by system and project scripts,
|
||||
-- instead of a function which would have already been called before
|
||||
-- those scripts could have run. Since the array will have already
|
||||
-- been evaluated by the time override() is called, the new value
|
||||
-- won't be picked up as it would with the function-fetched call
|
||||
-- lists. Special case the workaround for that here so everyone else
|
||||
-- can just override without having to think about the difference.
|
||||
if scope == premake.main then
|
||||
table.replace(premake.main.elements, original, scope[name])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Find the canonical name and scope of a function, resolving any aliases.
|
||||
--
|
||||
-- @param scope
|
||||
-- The table containing the function to be overridden. Use _G for
|
||||
-- global functions.
|
||||
-- @param name
|
||||
-- The name of the function to resolve.
|
||||
-- @return
|
||||
-- The canonical scope and function name (a string value).
|
||||
---
|
||||
|
||||
function p.resolveAlias(scope, name)
|
||||
local aliases = _aliases[scope]
|
||||
if aliases then
|
||||
while aliases[name] do
|
||||
name = aliases[name]
|
||||
end
|
||||
end
|
||||
return scope, name
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Display a warning, with a formatted message built from the provided
|
||||
-- arguments.
|
||||
--
|
||||
-- @param message
|
||||
-- The warning message, which may contain string formatting tokens.
|
||||
-- @param ...
|
||||
-- Values to fill in the string formatting tokens.
|
||||
--
|
||||
|
||||
function premake.warn(message, ...)
|
||||
message = string.format(message, ...)
|
||||
if _OPTIONS.fatal then
|
||||
error(message)
|
||||
else
|
||||
term.pushColor(term.warningColor)
|
||||
io.stderr:write(string.format("** Warning: " .. message .. "\n", ...))
|
||||
term.popColor();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Displays a warning just once per run.
|
||||
--
|
||||
-- @param key
|
||||
-- A unique key to identify this warning. Subsequent warnings messages
|
||||
-- using the same key will not be shown.
|
||||
-- @param message
|
||||
-- The warning message, which may contain string formatting tokens.
|
||||
-- @param ...
|
||||
-- Values to fill in the string formatting tokens.
|
||||
--
|
||||
|
||||
function premake.warnOnce(key, message, ...)
|
||||
if not _warnings[key] then
|
||||
_warnings[key] = true
|
||||
premake.warn(message, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Display information in the term.infoColor color.
|
||||
--
|
||||
-- @param message
|
||||
-- The info message, which may contain string formatting tokens.
|
||||
-- @param ...
|
||||
-- Values to fill in the string formatting tokens.
|
||||
--
|
||||
|
||||
function premake.info(message, ...)
|
||||
message = string.format(message, ...)
|
||||
term.pushColor(term.infoColor)
|
||||
io.stdout:write(string.format("** Info: " .. message .. "\n", ...))
|
||||
term.popColor();
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- A shortcut for printing formatted output.
|
||||
--
|
||||
|
||||
function printf(msg, ...)
|
||||
print(string.format(msg, ...))
|
||||
end
|
||||
|
||||
--
|
||||
-- A shortcut for printing formatted output in verbose mode.
|
||||
--
|
||||
function verbosef(msg, ...)
|
||||
if _OPTIONS.verbose then
|
||||
print(string.format(msg, ...))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- make a string from debug.getinfo information.
|
||||
--
|
||||
function filelineinfo(level)
|
||||
local info = debug.getinfo(level+1, "Sl")
|
||||
if info == nil then
|
||||
return nil
|
||||
end
|
||||
if info.what == "C" then
|
||||
return "C function"
|
||||
else
|
||||
local sep = iif(os.ishost('windows'), '\\', '/')
|
||||
return string.format("%s(%d)", path.translate(info.short_src, sep), info.currentline)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- check if version is semver.
|
||||
---
|
||||
|
||||
function premake.isSemVer(version)
|
||||
local sMajor, sMinor, sPatch, sPrereleaseAndBuild = version:match("^(%d+)%.?(%d*)%.?(%d*)(.-)$")
|
||||
return (type(sMajor) == 'string')
|
||||
end
|
||||
274
Src/external_dependencies/openmpt-trunk/include/premake/src/base/action.lua
vendored
Normal file
274
Src/external_dependencies/openmpt-trunk/include/premake/src/base/action.lua
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
---
|
||||
-- action.lua
|
||||
-- Work with the list of registered actions.
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.action = {}
|
||||
|
||||
local action = p.action
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Process the raw command line arguments from _ARGV to populate
|
||||
-- the _ACTION global and _ARGS table.
|
||||
--
|
||||
|
||||
_ACTION = nil
|
||||
_ARGS = {}
|
||||
|
||||
for i, arg in ipairs(_ARGV) do
|
||||
if not arg:startswith("/") and not arg:startswith("--") then
|
||||
if not _ACTION then
|
||||
_ACTION = arg
|
||||
else
|
||||
table.insert(_ARGS, arg)
|
||||
_ARGS[arg] = arg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- The list of registered actions. Calls to newaction() will add
|
||||
-- new entries here.
|
||||
--
|
||||
|
||||
action._list = {}
|
||||
|
||||
|
||||
---
|
||||
-- Register a new action.
|
||||
--
|
||||
-- @param act
|
||||
-- The new action object.
|
||||
---
|
||||
|
||||
function action.add(act)
|
||||
-- validate the action object, at least a little bit
|
||||
local missing
|
||||
for _, field in ipairs({"description", "trigger"}) do
|
||||
if not act[field] then
|
||||
missing = field
|
||||
end
|
||||
end
|
||||
|
||||
if missing then
|
||||
local name = act.trigger or ""
|
||||
error(string.format('action "%s" needs a %s', name, missing), 3)
|
||||
end
|
||||
|
||||
if act.os ~= nil then
|
||||
p.warnOnce(act.trigger, "action '" .. act.trigger .. "' sets 'os' field, which is deprecated, use 'targetos' instead.")
|
||||
act.targetos = act.os
|
||||
act.os = nil
|
||||
end
|
||||
|
||||
action._list[act.trigger] = act
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Initialize an action.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the action to be initialized.
|
||||
---
|
||||
|
||||
function action.initialize(name)
|
||||
local a = action._list[name]
|
||||
if (a.onInitialize) then
|
||||
a.onInitialize()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Trigger an action.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the action to be triggered.
|
||||
---
|
||||
|
||||
function action.call(name)
|
||||
local a = action._list[name]
|
||||
|
||||
if a.onStart then
|
||||
a.onStart()
|
||||
end
|
||||
|
||||
for wks in p.global.eachWorkspace() do
|
||||
local onWorkspace = a.onWorkspace or a.onSolution or a.onsolution
|
||||
if onWorkspace and not wks.external then
|
||||
onWorkspace(wks)
|
||||
end
|
||||
|
||||
for prj in p.workspace.eachproject(wks) do
|
||||
local onProject = a.onProject or a.onproject
|
||||
if onProject and not prj.external then
|
||||
onProject(prj)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for rule in p.global.eachRule() do
|
||||
local onRule = a.onRule or a.onrule
|
||||
if onRule and not rule.external then
|
||||
onRule(rule)
|
||||
end
|
||||
end
|
||||
|
||||
if a.execute then
|
||||
a.execute()
|
||||
end
|
||||
|
||||
if a.onEnd then
|
||||
a.onEnd()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve the current action, as determined by _ACTION.
|
||||
--
|
||||
-- @return
|
||||
-- The current action, or nil if _ACTION is nil or does not match any action.
|
||||
---
|
||||
|
||||
function action.current()
|
||||
return action.get(_ACTION)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve an action by name.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the action to retrieve.
|
||||
-- @returns
|
||||
-- The requested action, or nil if the action does not exist.
|
||||
---
|
||||
|
||||
function action.get(name)
|
||||
return action._list[name]
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Iterator for the list of actions.
|
||||
---
|
||||
|
||||
function action.each()
|
||||
-- sort the list by trigger
|
||||
local keys = { }
|
||||
for _, act in pairs(action._list) do
|
||||
table.insert(keys, act.trigger)
|
||||
end
|
||||
table.sort(keys)
|
||||
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
return action._list[keys[i]]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Determines if an action makes use of the configuration information
|
||||
-- provided by the project scripts (i.e. it is an exporter) or if it
|
||||
-- simply performs an action irregardless of configuration, in which
|
||||
-- case the baking and validation phases can be skipped.
|
||||
---
|
||||
|
||||
function action.isConfigurable(self)
|
||||
if not self then
|
||||
self = action.current() or {}
|
||||
end
|
||||
if self.onWorkspace or self.onSolution or self.onsolution then
|
||||
return true
|
||||
end
|
||||
if self.onProject or self.onproject then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Activates a particular action.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the action to activate.
|
||||
---
|
||||
|
||||
function action.set(name)
|
||||
_ACTION = name
|
||||
|
||||
-- Some actions imply a particular operating system
|
||||
local act = action.get(name)
|
||||
if act then
|
||||
_TARGET_OS = act.targetos or _TARGET_OS
|
||||
end
|
||||
|
||||
-- Some are implemented in standalone modules
|
||||
if act and act.module then
|
||||
require(act.module)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Determines if an action supports a particular language or target type.
|
||||
--
|
||||
-- @param feature
|
||||
-- The feature to check, either a programming language or a target type.
|
||||
-- @returns
|
||||
-- True if the feature is supported, false otherwise.
|
||||
---
|
||||
|
||||
function action.supports(feature)
|
||||
if not feature then
|
||||
return true
|
||||
end
|
||||
local self = action.current()
|
||||
if not self then
|
||||
return false
|
||||
end
|
||||
|
||||
if not self.valid_languages and not self.valid_kinds then
|
||||
return true
|
||||
end
|
||||
|
||||
if self.valid_languages and table.contains(self.valid_languages, feature) then
|
||||
return true
|
||||
end
|
||||
|
||||
if self.valid_kinds and table.contains(self.valid_kinds, feature) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determines if an action supports a particular configuration.
|
||||
-- @return
|
||||
-- True if the configuration is supported, false otherwise.
|
||||
--
|
||||
function p.action.supportsconfig(action, cfg)
|
||||
if not action then
|
||||
return false
|
||||
end
|
||||
if action.supportsconfig then
|
||||
return action.supportsconfig(cfg)
|
||||
end
|
||||
return true
|
||||
end
|
||||
1205
Src/external_dependencies/openmpt-trunk/include/premake/src/base/api.lua
vendored
Normal file
1205
Src/external_dependencies/openmpt-trunk/include/premake/src/base/api.lua
vendored
Normal file
File diff suppressed because it is too large
Load Diff
614
Src/external_dependencies/openmpt-trunk/include/premake/src/base/config.lua
vendored
Normal file
614
Src/external_dependencies/openmpt-trunk/include/premake/src/base/config.lua
vendored
Normal file
@@ -0,0 +1,614 @@
|
||||
--
|
||||
-- config.lua
|
||||
-- Premake configuration object API
|
||||
-- Copyright (c) 2011-2015 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
|
||||
p.config = {}
|
||||
|
||||
local project = p.project
|
||||
local config = p.config
|
||||
|
||||
|
||||
---
|
||||
-- Helper function for getlinkinfo() and gettargetinfo(); builds the
|
||||
-- name parts for a configuration, for building or linking.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration object being queried.
|
||||
-- @param kind
|
||||
-- The target kind (SharedLib, StaticLib).
|
||||
-- @param field
|
||||
-- One of "target" or "implib", used to locate the naming information
|
||||
-- in the configuration object (i.e. targetdir, targetname, etc.)
|
||||
-- @return
|
||||
-- A target info object; see one of getlinkinfo() or gettargetinfo()
|
||||
-- for more information.
|
||||
---
|
||||
|
||||
function config.buildtargetinfo(cfg, kind, field)
|
||||
local basedir = cfg.project.location
|
||||
|
||||
local targetdir
|
||||
if cfg.platform then
|
||||
targetdir = path.join(basedir, 'bin', cfg.platform, cfg.buildcfg)
|
||||
else
|
||||
targetdir = path.join(basedir, 'bin', cfg.buildcfg)
|
||||
end
|
||||
|
||||
local directory = cfg[field.."dir"] or cfg.targetdir or targetdir
|
||||
local basename = cfg[field.."name"] or cfg.targetname or cfg.project.name
|
||||
|
||||
local prefix = cfg[field.."prefix"] or cfg.targetprefix or ""
|
||||
local suffix = cfg[field.."suffix"] or cfg.targetsuffix or ""
|
||||
local extension = cfg[field.."extension"] or cfg.targetextension or ""
|
||||
|
||||
local bundlename = ""
|
||||
local bundlepath = ""
|
||||
|
||||
if table.contains(os.getSystemTags(cfg.system), "darwin") and (kind == p.WINDOWEDAPP or (kind == p.SHAREDLIB and cfg.sharedlibtype)) then
|
||||
bundlename = basename .. extension
|
||||
bundlepath = path.join(bundlename, iif(kind == p.SHAREDLIB and cfg.sharedlibtype == "OSXFramework", "Versions/A", "Contents/MacOS"))
|
||||
end
|
||||
|
||||
local info = {}
|
||||
info.directory = directory
|
||||
info.basename = basename .. suffix
|
||||
info.name = prefix .. info.basename .. extension
|
||||
info.extension = extension
|
||||
info.abspath = path.join(directory, info.name)
|
||||
info.fullpath = info.abspath
|
||||
info.bundlename = bundlename
|
||||
info.bundlepath = path.join(directory, bundlepath)
|
||||
info.prefix = prefix
|
||||
info.suffix = suffix
|
||||
return info
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Determine whether the given configuration can meaningfully link
|
||||
-- against the target object.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to be tested.
|
||||
-- @param target
|
||||
-- The object to test against. This can be a library file name, or a
|
||||
-- configuration from another project.
|
||||
-- @param linkage
|
||||
-- Optional. For languages or environments that support different kinds of
|
||||
-- linking (i.e. Managed/CLR C++, which can link both managed and unmanaged
|
||||
-- libs), which one to return. One of "unmanaged", "managed". If not
|
||||
-- specified, the default for the configuration will be used.
|
||||
-- @return
|
||||
-- True if linking the target into the configuration makes sense.
|
||||
---
|
||||
|
||||
function config.canLink(cfg, target, linkage)
|
||||
|
||||
-- Have I got a project configuration? If so, I've got some checks
|
||||
-- I can do with the extra information
|
||||
|
||||
if type(target) ~= "string" then
|
||||
|
||||
-- Can't link against executables
|
||||
|
||||
if target.kind ~= "SharedLib" and target.kind ~= "StaticLib" then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Can link mixed C++ with native projects
|
||||
|
||||
if cfg.language == "C++" then
|
||||
if cfg.clr == p.ON then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if target.language == "C++" then
|
||||
if target.clr == p.ON then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Can't link managed and unmanaged projects
|
||||
|
||||
local cfgManaged = project.isdotnet(cfg.project) or (cfg.clr ~= p.OFF)
|
||||
local tgtManaged = project.isdotnet(target.project) or (target.clr ~= p.OFF)
|
||||
return (cfgManaged == tgtManaged)
|
||||
|
||||
end
|
||||
|
||||
-- For now, I assume that everything listed in a .NET project can be
|
||||
-- linked; unmanaged code is simply not supported
|
||||
|
||||
if project.isdotnet(cfg.project) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- In C++ projects, managed dependencies must explicitly include
|
||||
-- the ".dll" extension, to distinguish from unmanaged libraries
|
||||
|
||||
local isManaged = (path.getextension(target) == ".dll")
|
||||
|
||||
-- Unmanaged projects can never link managed assemblies
|
||||
|
||||
if isManaged and cfg.clr == p.OFF then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Only allow this link it matches the requested linkage
|
||||
|
||||
return (isManaged) == (linkage == "managed")
|
||||
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determines if this configuration can be linked incrementally.
|
||||
--
|
||||
|
||||
function config.canLinkIncremental(cfg)
|
||||
if cfg.kind == "StaticLib"
|
||||
or config.isOptimizedBuild(cfg)
|
||||
or cfg.flags.NoIncrementalLink then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Check a configuration for a source code file with the specified
|
||||
-- extension. Used for locating special files, such as Windows
|
||||
-- ".def" module definition files.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration object to query.
|
||||
-- @param ext
|
||||
-- The file extension for which to search.
|
||||
-- @return
|
||||
-- The full file name if found, nil otherwise.
|
||||
--
|
||||
|
||||
function config.findfile(cfg, ext)
|
||||
for _, fname in ipairs(cfg.files) do
|
||||
if fname:endswith(ext) then
|
||||
return project.getrelative(cfg.project, fname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve linking information for a specific configuration. That is,
|
||||
-- the path information that is required to link against the library
|
||||
-- built by this configuration.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration object to query.
|
||||
-- @return
|
||||
-- A table with these values:
|
||||
-- basename - the target with no directory or file extension
|
||||
-- name - the target name and extension, with no directory
|
||||
-- directory - relative path to the target, with no file name
|
||||
-- extension - the file extension
|
||||
-- prefix - the file name prefix
|
||||
-- suffix - the file name suffix
|
||||
-- fullpath - directory, name, and extension relative to project
|
||||
-- abspath - absolute directory, name, and extension
|
||||
---
|
||||
|
||||
function config.getlinkinfo(cfg)
|
||||
-- if the configuration target is a DLL, and an import library
|
||||
-- is provided, change the kind as import libraries are static.
|
||||
local kind = cfg.kind
|
||||
if project.isnative(cfg.project) then
|
||||
if cfg.system == p.WINDOWS and kind == p.SHAREDLIB and not cfg.flags.NoImportLib then
|
||||
kind = p.STATICLIB
|
||||
end
|
||||
end
|
||||
return config.buildtargetinfo(cfg, kind, "implib")
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve a list of link targets from a configuration.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration object to query.
|
||||
-- @param kind
|
||||
-- The type of links to retrieve; one of:
|
||||
-- siblings - linkable sibling projects
|
||||
-- system - system (non-sibling) libraries
|
||||
-- dependencies - all sibling dependencies, including non-linkable
|
||||
-- all - return everything
|
||||
-- @param part
|
||||
-- How the link target should be expressed; one of:
|
||||
-- name - the decorated library name with no directory
|
||||
-- basename - the undecorated library name
|
||||
-- directory - just the directory, no name
|
||||
-- fullpath - full path with decorated name
|
||||
-- object - return the project object of the dependency
|
||||
-- Or, a function(original, decorated) can be supplied, in which case it
|
||||
-- will be called for each matching link, providing the original value as
|
||||
-- it was specified in links(), and the decorated value.
|
||||
-- @param linkage
|
||||
-- Optional. For languages or environments that support different kinds of
|
||||
-- linking (i.e. Managed/CLR C++, which can link both managed and unmanaged
|
||||
-- libs), which one to return. One of "unmanaged", "managed". If not
|
||||
-- specified, the default for the configuration will be used.
|
||||
-- @return
|
||||
-- An array containing the requested link target information.
|
||||
--
|
||||
|
||||
function config.getlinks(cfg, kind, part, linkage)
|
||||
local result = {}
|
||||
|
||||
-- If I'm building a list of link directories, include libdirs
|
||||
|
||||
if part == "directory" then
|
||||
table.foreachi(cfg.libdirs, function(dir)
|
||||
table.insert(result, project.getrelative(cfg.project, dir))
|
||||
end)
|
||||
end
|
||||
|
||||
-- Iterate all of the links listed in the configuration and boil
|
||||
-- them down to the requested data set
|
||||
|
||||
for i = 1, #cfg.links do
|
||||
local link = cfg.links[i]
|
||||
local item
|
||||
|
||||
-- Sort the links into "sibling" (is another project in this same
|
||||
-- workspace) and "system" (is not part of this workspace) libraries.
|
||||
|
||||
local prj = p.workspace.findproject(cfg.workspace, link)
|
||||
if prj and kind ~= "system" then
|
||||
|
||||
-- Sibling; is there a matching configuration in this project that
|
||||
-- is compatible with linking to me?
|
||||
|
||||
local prjcfg = project.getconfig(prj, cfg.buildcfg, cfg.platform)
|
||||
if prjcfg and (kind == "dependencies" or config.canLink(cfg, prjcfg)) then
|
||||
|
||||
-- Yes; does the caller want the whole project config or only part?
|
||||
if part == "object" then
|
||||
item = prjcfg
|
||||
else
|
||||
item = project.getrelative(cfg.project, prjcfg.linktarget.fullpath)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
elseif not prj and (kind == "system" or kind == "all") then
|
||||
|
||||
-- Make sure this library makes sense for the requested linkage; don't
|
||||
-- link managed .DLLs into unmanaged code, etc.
|
||||
|
||||
if config.canLink(cfg, link, linkage) then
|
||||
-- if the target is listed via an explicit path (i.e. not a
|
||||
-- system library or assembly), make it project-relative
|
||||
item = link
|
||||
if item:find("/", nil, true) then
|
||||
item = project.getrelative(cfg.project, item)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- If this is something I can link against, pull out the requested part
|
||||
-- dont link against my self
|
||||
if item and item ~= cfg then
|
||||
if part == "directory" then
|
||||
item = path.getdirectory(item)
|
||||
if item == "." then
|
||||
item = nil
|
||||
end
|
||||
elseif part == "name" then
|
||||
item = path.getname(item)
|
||||
elseif part == "basename" then
|
||||
item = path.getbasename(item)
|
||||
elseif type(part) == "function" then
|
||||
part(link, item)
|
||||
end
|
||||
end
|
||||
|
||||
-- Add it to the list, skipping duplicates
|
||||
|
||||
if item and not table.contains(result, item) then
|
||||
table.insert(result, item)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns the list of sibling target directories
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration object to query.
|
||||
-- @return
|
||||
-- Absolute path list
|
||||
--
|
||||
function config.getsiblingtargetdirs(cfg)
|
||||
local paths = {}
|
||||
for _, sibling in ipairs(config.getlinks(cfg, "siblings", "object")) do
|
||||
if (sibling.kind == p.SHAREDLIB) then
|
||||
local p = sibling.linktarget.directory
|
||||
if not (table.contains(paths, p)) then
|
||||
table.insert(paths, p)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return paths
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determines the correct runtime library for a configuration.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration object to query.
|
||||
-- @return
|
||||
-- A string identifying the runtime library, one of
|
||||
-- StaticDebug, StaticRelease, SharedDebug, SharedRelease.
|
||||
--
|
||||
|
||||
function config.getruntime(cfg)
|
||||
if (not cfg.staticruntime or cfg.staticruntime == "Default") and not cfg.runtime then
|
||||
return nil -- indicate that no runtime was explicitly selected
|
||||
end
|
||||
|
||||
local linkage = iif(cfg.staticruntime == "On", "Static", "Shared") -- assume 'Shared' is default?
|
||||
|
||||
if not cfg.runtime then
|
||||
return linkage .. iif(config.isDebugBuild(cfg), "Debug", "Release")
|
||||
else
|
||||
return linkage .. cfg.runtime
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve information about a configuration's build target.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration object to query.
|
||||
-- @return
|
||||
-- A table with these values:
|
||||
-- basename - the target with no directory or file extension
|
||||
-- name - the target name and extension, with no directory
|
||||
-- directory - relative path to the target, with no file name
|
||||
-- extension - the file extension
|
||||
-- prefix - the file name prefix
|
||||
-- suffix - the file name suffix
|
||||
-- fullpath - directory, name, and extension, relative to project
|
||||
-- abspath - absolute directory, name, and extension
|
||||
-- bundlepath - the relative path and file name of the bundle
|
||||
--
|
||||
|
||||
function config.gettargetinfo(cfg)
|
||||
return config.buildtargetinfo(cfg, cfg.kind, "target")
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Returns true if any of the files in the provided container pass the
|
||||
-- provided test function.
|
||||
---
|
||||
|
||||
function config.hasFile(self, testfn)
|
||||
local files = self.files
|
||||
for i = 1, #files do
|
||||
if testfn(files[i]) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Determine if the specified library or assembly reference should be copied
|
||||
-- to the build's target directory. "Copy Local" is the terminology used by
|
||||
-- Visual Studio C# projects for this feature.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to query. Can be a project (and will be for C#
|
||||
-- projects).
|
||||
-- @param linkname
|
||||
-- The name of the library or assembly reference to check. This should
|
||||
-- match the name as it was provided in the call to links().
|
||||
-- @param default
|
||||
-- The value to return if the library is not mentioned in any settings.
|
||||
-- @return
|
||||
-- True if the library should be copied local, false otherwise.
|
||||
--
|
||||
|
||||
function config.isCopyLocal(cfg, linkname, default)
|
||||
if cfg.flags.NoCopyLocal then
|
||||
return false
|
||||
end
|
||||
|
||||
if #cfg.copylocal > 0 then
|
||||
return table.contains(cfg.copylocal, linkname)
|
||||
end
|
||||
|
||||
return default
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determine if a configuration represents a "debug" or "release" build.
|
||||
-- This controls the runtime library selected for Visual Studio builds
|
||||
-- (and might also be useful elsewhere).
|
||||
--
|
||||
|
||||
function config.isDebugBuild(cfg)
|
||||
return cfg.symbols ~= nil and
|
||||
cfg.symbols ~= p.OFF and
|
||||
cfg.symbols ~= "Default" and
|
||||
not config.isOptimizedBuild(cfg)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determine if this configuration uses one of the optimize flags.
|
||||
-- Optimized builds get different treatment, such as full linking
|
||||
-- instead of incremental.
|
||||
--
|
||||
|
||||
function config.isOptimizedBuild(cfg)
|
||||
return cfg.optimize ~= nil and cfg.optimize ~= p.OFF and cfg.optimize ~= "Debug"
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Does this configuration's list of links contain the specified
|
||||
-- project? Performs a case-insensitive search for the project's
|
||||
-- name in the configuration's link array.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to query.
|
||||
-- @param prjName
|
||||
-- The name of the project for which to search.
|
||||
-- @return
|
||||
-- True if the project name is found in the configuration's
|
||||
-- list of links; nil otherwise.
|
||||
--
|
||||
|
||||
function config.linksToProject(cfg, prjName)
|
||||
prjName = prjName:lower()
|
||||
local n = #cfg.links
|
||||
for i = 1,n do
|
||||
if cfg.links[i]:lower() == prjName then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Map the values contained in the configuration to an array of flags.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to map.
|
||||
-- @param mappings
|
||||
-- A mapping from configuration fields and values to flags. See
|
||||
-- the GCC tool interface for examples of these mappings.
|
||||
-- @return
|
||||
-- An array containing the translated flags.
|
||||
--
|
||||
|
||||
function config.mapFlags(cfg, mappings)
|
||||
local flags = {}
|
||||
|
||||
-- Helper function to append replacement values to the result
|
||||
|
||||
local function add(replacement)
|
||||
if type(replacement) == "function" then
|
||||
replacement = replacement(cfg)
|
||||
end
|
||||
table.insertflat(flags, replacement)
|
||||
end
|
||||
|
||||
-- To ensure we get deterministic results that don't change as more keys
|
||||
-- are added to the map, and to open the possibility to controlling the
|
||||
-- application order of flags, use a prioritized list of fields to order
|
||||
-- the mapping, even though it takes a little longer.
|
||||
|
||||
for field in p.field.eachOrdered() do
|
||||
local map = mappings[field.name]
|
||||
if type(map) == "function" then
|
||||
map = map(cfg, mappings)
|
||||
end
|
||||
if map then
|
||||
|
||||
-- Pass each cfg value in the list through the map and append the
|
||||
-- replacement, if any, to the result
|
||||
|
||||
local values = cfg[field.name]
|
||||
if type(values) == "boolean" then
|
||||
values = iif(values, "On", "Off")
|
||||
end
|
||||
if type(values) ~= "table" then
|
||||
values = { values }
|
||||
end
|
||||
|
||||
local foundValue = false
|
||||
table.foreachi(values, function(value)
|
||||
local replacement = map[value]
|
||||
if replacement ~= nil then
|
||||
foundValue = true
|
||||
add(replacement)
|
||||
end
|
||||
end)
|
||||
|
||||
-- If no value was mapped, check to see if the map specifies a
|
||||
-- default value and, if so, push that into the result
|
||||
|
||||
if not foundValue then
|
||||
add(map._)
|
||||
end
|
||||
|
||||
-- Finally, check for "not values", which should be added to the
|
||||
-- result if the corresponding value is not present
|
||||
|
||||
for key, replacement in pairs(map) do
|
||||
if #key > 1 and key:startswith("_") then
|
||||
key = key:sub(2)
|
||||
if values[key] == nil then
|
||||
add(replacement)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Returns both a project configuration and a file configuration from a
|
||||
-- configuration argument that could be either.
|
||||
--
|
||||
-- @param cfg
|
||||
-- A project or file configuration object.
|
||||
-- @return
|
||||
-- Both a project configuration and a file configuration. If the input
|
||||
-- argument is a project configuration, the file configuration value is
|
||||
-- returned as nil.
|
||||
---
|
||||
|
||||
function config.normalize(cfg)
|
||||
if cfg and cfg.config ~= nil then
|
||||
return cfg.config, cfg
|
||||
else
|
||||
return cfg, nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Return the appropriate toolset adapter for the provided configuration,
|
||||
-- or nil if no toolset is specified. If a specific version was provided,
|
||||
-- returns that as a second argument.
|
||||
---
|
||||
|
||||
function config.toolset(cfg)
|
||||
if cfg.toolset then
|
||||
return p.tools.canonical(cfg.toolset)
|
||||
end
|
||||
end
|
||||
499
Src/external_dependencies/openmpt-trunk/include/premake/src/base/configset.lua
vendored
Normal file
499
Src/external_dependencies/openmpt-trunk/include/premake/src/base/configset.lua
vendored
Normal file
@@ -0,0 +1,499 @@
|
||||
--
|
||||
-- base/configset.lua
|
||||
--
|
||||
-- A configuration set manages a collection of fields, which are organized
|
||||
-- into "blocks". Each block stores a set of field-value pairs, along with
|
||||
-- a list of terms which indicate the context in which those field values
|
||||
-- should be applied.
|
||||
--
|
||||
-- Configurations use the field definitions to know what fields are available,
|
||||
-- and the corresponding value types for those fields. Only fields that have
|
||||
-- been registered via field.new() can be stored.
|
||||
--
|
||||
-- TODO: I may roll this functionality up into the container API at some
|
||||
-- point. If you find yourself using or extending this code for your own
|
||||
-- work give me a shout before you go too far with it so we can coordinate.
|
||||
--
|
||||
-- Copyright (c) 2012-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
|
||||
p.configset = {}
|
||||
|
||||
local configset = p.configset
|
||||
local criteria = p.criteria
|
||||
|
||||
|
||||
--
|
||||
-- Create a new configuration set.
|
||||
--
|
||||
-- @param parent
|
||||
-- An optional parent configuration set. If provided, the parent provides
|
||||
-- a base configuration, which this set will extend.
|
||||
-- @return
|
||||
-- A new, empty configuration set.
|
||||
--
|
||||
|
||||
function configset.new(parent)
|
||||
local cset = {}
|
||||
cset.parent = parent
|
||||
cset.blocks = {}
|
||||
cset.current = nil
|
||||
cset.compiled = false
|
||||
return cset
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a value from the configuration set.
|
||||
--
|
||||
-- This and the criteria supporting code are the inner loops of the app. Some
|
||||
-- readability has been sacrificed for overall performance.
|
||||
--
|
||||
-- @param cset
|
||||
-- The configuration set to query.
|
||||
-- @param field
|
||||
-- The definition of field to be queried.
|
||||
-- @param filter
|
||||
-- A list of lowercase context terms to use during the fetch. Only those
|
||||
-- blocks with terms fully contained by this list will be considered in
|
||||
-- determining the returned value. Terms should be lower case to make
|
||||
-- the context filtering case-insensitive.
|
||||
-- @param ctx
|
||||
-- The context that will be used for detoken.expand
|
||||
-- @param origin
|
||||
-- The originating configset if set.
|
||||
-- @return
|
||||
-- The requested value.
|
||||
---
|
||||
|
||||
function configset.fetch(cset, field, filter, ctx, origin)
|
||||
filter = filter or {}
|
||||
ctx = ctx or {}
|
||||
|
||||
if p.field.merges(field) then
|
||||
return configset._fetchMerged(cset, field, filter, ctx, origin)
|
||||
else
|
||||
return configset._fetchDirect(cset, field, filter, ctx, origin)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function configset._dofilter(cset, block, filter)
|
||||
if not filter.matcher then
|
||||
return (cset.compiled or criteria.matches(block._criteria, filter))
|
||||
else
|
||||
return filter.matcher(cset, block, filter)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function configset._fetchDirect(cset, field, filter, ctx, origin)
|
||||
-- If the originating configset hasn't been compiled, then the value will still
|
||||
-- be on that configset.
|
||||
if origin and origin ~= cset and not origin.compiled then
|
||||
return configset._fetchDirect(origin, field, filter, ctx, origin)
|
||||
end
|
||||
|
||||
local abspath = filter.files
|
||||
local basedir
|
||||
|
||||
local key = field.name
|
||||
local blocks = cset.blocks
|
||||
local n = #blocks
|
||||
for i = n, 1, -1 do
|
||||
local block = blocks[i]
|
||||
|
||||
if not origin or block._origin == origin then
|
||||
local value = block[key]
|
||||
|
||||
-- If the filter contains a file path, make it relative to
|
||||
-- this block's basedir
|
||||
if value ~= nil and abspath and not cset.compiled and block._basedir and block._basedir ~= basedir then
|
||||
basedir = block._basedir
|
||||
filter.files = path.getrelative(basedir, abspath)
|
||||
end
|
||||
|
||||
if value ~= nil and configset._dofilter(cset, block, filter) then
|
||||
-- If value is an object, return a copy of it so that any
|
||||
-- changes later made to it by the caller won't alter the
|
||||
-- original value (that was a tough bug to find)
|
||||
if type(value) == "table" then
|
||||
value = table.deepcopy(value)
|
||||
end
|
||||
-- Detoken
|
||||
if field.tokens and ctx.environ then
|
||||
value = p.detoken.expand(value, ctx.environ, field, ctx._basedir)
|
||||
end
|
||||
return value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
filter.files = abspath
|
||||
|
||||
if cset.parent then
|
||||
return configset._fetchDirect(cset.parent, field, filter, ctx, origin)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function configset._fetchMerged(cset, field, filter, ctx, origin)
|
||||
-- If the originating configset hasn't been compiled, then the value will still
|
||||
-- be on that configset.
|
||||
if origin and origin ~= cset and not origin.compiled then
|
||||
return configset._fetchMerged(origin, field, filter, ctx, origin)
|
||||
end
|
||||
|
||||
local result = {}
|
||||
|
||||
local function remove(patterns)
|
||||
for _, pattern in ipairs(patterns) do
|
||||
-- Detoken
|
||||
if field.tokens and ctx.environ then
|
||||
pattern = p.detoken.expand(pattern, ctx.environ, field, ctx._basedir)
|
||||
end
|
||||
pattern = path.wildcards(pattern):lower()
|
||||
|
||||
local j = 1
|
||||
while j <= #result do
|
||||
local value = result[j]:lower()
|
||||
if value:match(pattern) == value then
|
||||
result[result[j]] = nil
|
||||
table.remove(result, j)
|
||||
else
|
||||
j = j + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if cset.parent then
|
||||
result = configset._fetchMerged(cset.parent, field, filter, ctx, origin)
|
||||
end
|
||||
|
||||
local abspath = filter.files
|
||||
local basedir
|
||||
|
||||
local key = field.name
|
||||
local blocks = cset.blocks
|
||||
local n = #blocks
|
||||
for i = 1, n do
|
||||
local block = blocks[i]
|
||||
if not origin or block._origin == origin then
|
||||
-- If the filter contains a file path, make it relative to
|
||||
-- this block's basedir
|
||||
if abspath and block._basedir and block._basedir ~= basedir and not cset.compiled then
|
||||
basedir = block._basedir
|
||||
filter.files = path.getrelative(basedir, abspath)
|
||||
end
|
||||
|
||||
if configset._dofilter(cset, block, filter) then
|
||||
if block._removes and block._removes[key] then
|
||||
remove(block._removes[key])
|
||||
end
|
||||
|
||||
local value = block[key]
|
||||
-- If value is an object, return a copy of it so that any
|
||||
-- changes later made to it by the caller won't alter the
|
||||
-- original value (that was a tough bug to find)
|
||||
if type(value) == "table" then
|
||||
value = table.deepcopy(value)
|
||||
end
|
||||
|
||||
if value then
|
||||
-- Detoken
|
||||
if field.tokens and ctx.environ then
|
||||
value = p.detoken.expand(value, ctx.environ, field, ctx._basedir)
|
||||
end
|
||||
-- Translate
|
||||
if field and p.field.translates(field) then
|
||||
value = p.field.translate(field, value)
|
||||
end
|
||||
|
||||
result = p.field.merge(field, result, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
filter.files = abspath
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create and return a metatable which allows a configuration set to act as a
|
||||
-- "backing store" for a regular Lua table. Table operations that access a
|
||||
-- registered field will fetch from or store to the configurations set, while
|
||||
-- unknown keys are get and set to the table normally.
|
||||
---
|
||||
|
||||
function configset.metatable(cset)
|
||||
return {
|
||||
__newindex = function(tbl, key, value)
|
||||
local f = p.field.get(key)
|
||||
if f then
|
||||
local status, err = configset.store(cset, f, value)
|
||||
if err then
|
||||
error(err, 2)
|
||||
end
|
||||
else
|
||||
rawset(tbl, key, value)
|
||||
return value
|
||||
end
|
||||
end,
|
||||
__index = function(tbl, key)
|
||||
local f = p.field.get(key)
|
||||
if f then
|
||||
return configset.fetch(cset, f)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new block of configuration field-value pairs, using a set of
|
||||
-- old-style, non-prefixed context terms to control their application. This
|
||||
-- approach will eventually be phased out in favor of prefixed filters;
|
||||
-- see addFilter() below.
|
||||
--
|
||||
-- @param cset
|
||||
-- The configuration set to hold the new block.
|
||||
-- @param terms
|
||||
-- A set of context terms to control the application of values contained
|
||||
-- in the block.
|
||||
-- @param basedir
|
||||
-- An optional base directory; if set, filename filter tests will be made
|
||||
-- relative to this basis before pattern testing.
|
||||
-- @return
|
||||
-- The new configuration data block.
|
||||
---
|
||||
|
||||
function configset.addblock(cset, terms, basedir)
|
||||
configset.addFilter(cset, terms, basedir, true)
|
||||
return cset.current
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new block of configuration field-value pairs, using a set
|
||||
-- of new-style, prefixed context terms to control their application.
|
||||
--
|
||||
-- @param cset
|
||||
-- The configuration set to hold the new block.
|
||||
-- @param terms
|
||||
-- A set of terms used to control the application of the values
|
||||
-- contained in the block.
|
||||
-- @param basedir
|
||||
-- An optional base directory. If set, filename filter tests will be
|
||||
-- made relative to this base before pattern testing.
|
||||
-- @param unprefixed
|
||||
-- If true, uses the old, unprefixed style for filter terms. This will
|
||||
-- eventually be phased out in favor of prefixed filters.
|
||||
---
|
||||
|
||||
function configset.addFilter(cset, terms, basedir, unprefixed)
|
||||
local crit, err = criteria.new(terms, unprefixed)
|
||||
if not crit then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
local block = {}
|
||||
block._criteria = crit
|
||||
block._origin = cset
|
||||
|
||||
if basedir then
|
||||
block._basedir = basedir:lower()
|
||||
end
|
||||
|
||||
table.insert(cset.blocks, block)
|
||||
cset.current = block
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Allow calling code to save and restore a filter. Particularly useful for
|
||||
-- modules.
|
||||
---
|
||||
function configset.getFilter(cset)
|
||||
return {
|
||||
_criteria = cset.current._criteria,
|
||||
_basedir = cset.current._basedir
|
||||
}
|
||||
end
|
||||
|
||||
function configset.setFilter(cset, filter)
|
||||
local block = {}
|
||||
block._criteria = filter._criteria
|
||||
block._basedir = filter._basedir
|
||||
block._origin = cset
|
||||
table.insert(cset.blocks, block)
|
||||
cset.current = block;
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Add a new field-value pair to the current configuration data block. The
|
||||
-- data type of the field is taken into account when adding the values:
|
||||
-- strings are replaced, arrays are merged, etc.
|
||||
--
|
||||
-- @param cset
|
||||
-- The configuration set to hold the new value.
|
||||
-- @param fieldname
|
||||
-- The name of the field being set. The field should have already been
|
||||
-- defined using the api.register() function.
|
||||
-- @param value
|
||||
-- The new value for the field.
|
||||
-- @return
|
||||
-- If successful, returns true. If an error occurred, returns nil and
|
||||
-- an error message.
|
||||
---
|
||||
|
||||
function configset.store(cset, field, value)
|
||||
if not cset.current then
|
||||
configset.addblock(cset, {})
|
||||
end
|
||||
|
||||
local key = field.name
|
||||
local current = cset.current
|
||||
|
||||
local status, result = pcall(function ()
|
||||
current[key] = p.field.store(field, current[key], value)
|
||||
end)
|
||||
|
||||
if not status then
|
||||
if type(result) == "table" then
|
||||
result = result.msg
|
||||
end
|
||||
return nil, result
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Remove values from a configuration set.
|
||||
--
|
||||
-- @param cset
|
||||
-- The configuration set from which to remove.
|
||||
-- @param field
|
||||
-- The field holding the values to be removed.
|
||||
-- @param values
|
||||
-- A list of values to be removed.
|
||||
--
|
||||
|
||||
function configset.remove(cset, field, values)
|
||||
-- removes are always processed first; starting a new block here
|
||||
-- ensures that they will be processed in the proper order
|
||||
local block = {}
|
||||
block._basedir = cset.current._basedir
|
||||
block._criteria = cset.current._criteria
|
||||
block._origin = cset
|
||||
table.insert(cset.blocks, block)
|
||||
cset.current = block
|
||||
|
||||
-- TODO This comment is not completely valid anymore
|
||||
-- This needs work; right now it is hardcoded to only work for lists.
|
||||
-- To support removing from keyed collections, I first need to figure
|
||||
-- out how to move the wildcard():lower() bit into the value
|
||||
-- processing call chain (i.e. that should happen somewhere inside of
|
||||
-- the field.remove() call). And then I will probably need to add
|
||||
-- another accessor to actually do the removing, which right now is
|
||||
-- hardcoded inside of _fetchMerged(). Oh, and some of the logic in
|
||||
-- api.remove() needs to get pushed down to here (or field).
|
||||
|
||||
values = p.field.remove(field, {}, values)
|
||||
|
||||
-- add a list of removed values to the block
|
||||
current = cset.current
|
||||
current._removes = {}
|
||||
current._removes[field.name] = values
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Check to see if a configuration set is empty; that is, it does
|
||||
-- not contain any configuration blocks.
|
||||
--
|
||||
-- @param cset
|
||||
-- The configuration set to query.
|
||||
-- @return
|
||||
-- True if the set does not contain any blocks.
|
||||
--
|
||||
|
||||
function configset.empty(cset)
|
||||
return (#cset.blocks == 0)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Compiles a new configuration set containing only the blocks which match
|
||||
-- the specified criteria. Fetches against this compiled configuration set
|
||||
-- may omit the context argument, resulting in faster fetches against a
|
||||
-- smaller set of configuration blocks.
|
||||
--
|
||||
-- @param cset
|
||||
-- The configuration set to query.
|
||||
-- @param filter
|
||||
-- A list of lowercase context terms to use during the fetch. Only those
|
||||
-- blocks with terms fully contained by this list will be considered in
|
||||
-- determining the returned value. Terms should be lower case to make
|
||||
-- the context filtering case-insensitive.
|
||||
-- @return
|
||||
-- A new configuration set containing only the selected blocks, and the
|
||||
-- "compiled" field set to true.
|
||||
--
|
||||
|
||||
function configset.compile(cset, filter)
|
||||
-- always start with the parent
|
||||
local result
|
||||
if cset.parent then
|
||||
result = configset.compile(cset.parent, filter)
|
||||
else
|
||||
result = configset.new()
|
||||
end
|
||||
|
||||
local blocks = cset.blocks
|
||||
local n = #blocks
|
||||
|
||||
local abspath = filter.files
|
||||
local basedir
|
||||
|
||||
for i = 1, n do
|
||||
local block = blocks[i]
|
||||
if block._origin == cset then
|
||||
block._origin = result
|
||||
end
|
||||
|
||||
-- If the filter contains a file path, make it relative to
|
||||
-- this block's basedir
|
||||
if abspath and block._basedir and block._basedir ~= basedir then
|
||||
basedir = block._basedir
|
||||
filter.files = path.getrelative(basedir, abspath)
|
||||
end
|
||||
|
||||
if criteria.matches(block._criteria, filter) then
|
||||
table.insert(result.blocks, block)
|
||||
end
|
||||
end
|
||||
|
||||
filter.files = abspath
|
||||
|
||||
result.compiled = true
|
||||
return result
|
||||
end
|
||||
361
Src/external_dependencies/openmpt-trunk/include/premake/src/base/container.lua
vendored
Normal file
361
Src/external_dependencies/openmpt-trunk/include/premake/src/base/container.lua
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
---
|
||||
-- container.lua
|
||||
-- Implementation of configuration containers.
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.container = {}
|
||||
|
||||
local container = p.container
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Keep a master dictionary of container class, so they can be easily looked
|
||||
-- up by name (technically you could look at premake["name"] but that is just
|
||||
-- a coding convention and I don't want to count on it)
|
||||
---
|
||||
|
||||
container.classes = {}
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Define a new class of containers.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the new container class. Used wherever the class needs to
|
||||
-- be shown to the end user in a readable way.
|
||||
-- @param parent (optional)
|
||||
-- If this class of container is intended to be contained within another,
|
||||
-- the containing class object.
|
||||
-- @param extraScopes (optional)
|
||||
-- Each container can hold fields scoped to itself (by putting the container's
|
||||
-- class name into its scope attribute), or any of the container's children.
|
||||
-- If a container can hold scopes other than these (i.e. "config"), it can
|
||||
-- provide a list of those scopes in this argument.
|
||||
-- @return
|
||||
-- If successful, the new class descriptor object (a table). Otherwise,
|
||||
-- returns nil and an error message.
|
||||
---
|
||||
|
||||
function container.newClass(name, parent, extraScopes)
|
||||
local class = p.configset.new(parent)
|
||||
class.name = name
|
||||
class.pluralName = name:plural()
|
||||
class.containedClasses = {}
|
||||
class.extraScopes = extraScopes
|
||||
|
||||
if parent then
|
||||
table.insert(parent.containedClasses, class)
|
||||
end
|
||||
|
||||
container.classes[name] = class
|
||||
return class
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new instance of a configuration container. This is just the
|
||||
-- generic base implementation, each container class will define their
|
||||
-- own version.
|
||||
--
|
||||
-- @param parent
|
||||
-- The class of container being instantiated.
|
||||
-- @param name
|
||||
-- The name for the new container instance.
|
||||
-- @return
|
||||
-- A new container instance.
|
||||
---
|
||||
|
||||
function container.new(class, name)
|
||||
local self = p.configset.new()
|
||||
setmetatable(self, p.configset.metatable(self))
|
||||
|
||||
self.class = class
|
||||
self.name = name
|
||||
self.filename = name
|
||||
self.script = _SCRIPT
|
||||
self.basedir = os.getcwd()
|
||||
self.external = false
|
||||
|
||||
for childClass in container.eachChildClass(class) do
|
||||
self[childClass.pluralName] = {}
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Add a new child to an existing container instance.
|
||||
--
|
||||
-- @param self
|
||||
-- The container instance to hold the child.
|
||||
-- @param child
|
||||
-- The child container instance.
|
||||
---
|
||||
|
||||
function container.addChild(self, child)
|
||||
local children = self[child.class.pluralName]
|
||||
table.insert(children, child)
|
||||
children[child.name] = child
|
||||
|
||||
child.parent = self
|
||||
child[self.class.name] = self
|
||||
if self.class.alias then
|
||||
child[self.class.alias] = self
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Process the contents of a container, which were populated by the project
|
||||
-- script, in preparation for doing work on the results, such as exporting
|
||||
-- project files.
|
||||
---
|
||||
|
||||
function container.bake(self)
|
||||
if self._isBaked then
|
||||
return self
|
||||
end
|
||||
self._isBaked = true
|
||||
|
||||
local ctx = p.context.new(self)
|
||||
|
||||
for key, value in pairs(self) do
|
||||
ctx[key] = value
|
||||
end
|
||||
|
||||
local parent = self.parent
|
||||
if parent then
|
||||
ctx[parent.class.name] = parent
|
||||
end
|
||||
|
||||
for class in container.eachChildClass(self.class) do
|
||||
for child in container.eachChild(self, class) do
|
||||
child.parent = ctx
|
||||
child[self.class.name] = ctx
|
||||
end
|
||||
end
|
||||
|
||||
if type(self.class.bake) == "function" then
|
||||
self.class.bake(ctx)
|
||||
end
|
||||
|
||||
return ctx
|
||||
end
|
||||
|
||||
|
||||
function container.bakeChildren(self)
|
||||
for class in container.eachChildClass(self.class) do
|
||||
local children = self[class.pluralName]
|
||||
for i = 1, #children do
|
||||
local ctx = container.bake(children[i])
|
||||
children[i] = ctx
|
||||
children[ctx.name] = ctx
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Returns true if the container can hold any of the specified field scopes.
|
||||
--
|
||||
-- @param class
|
||||
-- The container class to test.
|
||||
-- @param scope
|
||||
-- A scope string (e.g. "project", "config") or an array of scope strings.
|
||||
-- @return
|
||||
-- True if this container can hold any of the specified scopes.
|
||||
---
|
||||
|
||||
function container.classCanContain(class, scope)
|
||||
if type(scope) == "table" then
|
||||
for i = 1, #scope do
|
||||
if container.classCanContain(class, scope[i]) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- if I have child classes, check with them first, since scopes
|
||||
-- are usually specified for leaf nodes in the hierarchy
|
||||
for child in container.eachChildClass(class) do
|
||||
if (container.classCanContain(child, scope)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if class.name == scope or class.alias == scope then
|
||||
return true
|
||||
end
|
||||
|
||||
-- is it in my extra scopes list?
|
||||
if class.extraScopes and table.contains(class.extraScopes, scope) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Return true if a container class is or inherits from the
|
||||
-- specified class.
|
||||
--
|
||||
-- @param class
|
||||
-- The container class to be tested.
|
||||
-- @param scope
|
||||
-- The name of the class to be checked against. If the container
|
||||
-- class matches this scope (i.e. class is a project and the
|
||||
-- scope is "project"), or if it is a parent object of it (i.e.
|
||||
-- class is a workspace and scope is "project"), then returns
|
||||
-- true.
|
||||
---
|
||||
|
||||
function container.classIsA(class, scope)
|
||||
while class do
|
||||
if class.name == scope or class.alias == scope then
|
||||
return true
|
||||
end
|
||||
class = class.parent
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Enumerate all of the registered child classes of a specific container class.
|
||||
--
|
||||
-- @param class
|
||||
-- The container class to be enumerated.
|
||||
-- @return
|
||||
-- An iterator function for the container's child classes.
|
||||
---
|
||||
|
||||
function container.eachChildClass(class)
|
||||
local children = class.containedClasses
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= #children then
|
||||
return children[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Enumerate all of the registered child instances of a specific container.
|
||||
--
|
||||
-- @param self
|
||||
-- The container to be queried.
|
||||
-- @param class
|
||||
-- The class of child containers to be enumerated.
|
||||
-- @return
|
||||
-- An iterator function for the container's child classes.
|
||||
---
|
||||
|
||||
function container.eachChild(self, class)
|
||||
local children = self[class.pluralName]
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= #children then
|
||||
return children[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve the child container with the specified class and name.
|
||||
--
|
||||
-- @param self
|
||||
-- The container instance to query.
|
||||
-- @param class
|
||||
-- The class of the child container to be fetched.
|
||||
-- @param name
|
||||
-- The name of the child container to be fetched.
|
||||
-- @return
|
||||
-- The child instance if it exists, nil otherwise.
|
||||
---
|
||||
|
||||
function container.getChild(self, class, name)
|
||||
local children = self[class.pluralName]
|
||||
return children[name]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a container class object.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the container class to retrieve.
|
||||
-- @return
|
||||
-- The container class object if it exists, nil otherwise.
|
||||
---
|
||||
|
||||
function container.getClass(name)
|
||||
return container.classes[name]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Determine if the container contains a child of the specified class which
|
||||
-- meets the criteria of a testing function.
|
||||
--
|
||||
-- @param self
|
||||
-- The container to be queried.
|
||||
-- @param class
|
||||
-- The class of the child containers to be enumerated.
|
||||
-- @param func
|
||||
-- A function that takes a child container as its only argument, and
|
||||
-- returns true if it meets the selection criteria for the call.
|
||||
-- @return
|
||||
-- True if the test function returns true for any child.
|
||||
---
|
||||
|
||||
function container.hasChild(self, class, func)
|
||||
for child in container.eachChild(self, class) do
|
||||
if func(child) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Call out to the container validation to make sure everything
|
||||
-- is as it should be before handing off to the actions.
|
||||
---
|
||||
|
||||
function container.validate(self)
|
||||
if type(self.class.validate) == "function" then
|
||||
self.class.validate(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function container.validateChildren(self)
|
||||
for class in container.eachChildClass(self.class) do
|
||||
local children = self[class.pluralName]
|
||||
for i = 1, #children do
|
||||
container.validate(children[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
256
Src/external_dependencies/openmpt-trunk/include/premake/src/base/context.lua
vendored
Normal file
256
Src/external_dependencies/openmpt-trunk/include/premake/src/base/context.lua
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
--
|
||||
-- base/context.lua
|
||||
--
|
||||
-- Provide a context for pulling out values from a configuration set. Each
|
||||
-- context has an associated list of terms which constrain the values that
|
||||
-- it will retrieve, i.e. "Windows, "Debug", "x64", and so on.
|
||||
--
|
||||
-- The context also provides caching for the values returned from the set.
|
||||
--
|
||||
-- TODO: I may roll this functionality up into the container API at some
|
||||
-- point. If you find yourself using or extending this code for your own
|
||||
-- work give me a shout before you go too far with it so we can coordinate.
|
||||
--
|
||||
-- Copyright (c) 2012-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
|
||||
p.context = {}
|
||||
|
||||
local context = p.context
|
||||
local configset = p.configset
|
||||
|
||||
|
||||
--
|
||||
-- Create a new context object.
|
||||
--
|
||||
-- @param cfgset
|
||||
-- The configuration set to provide the data from this context.
|
||||
-- @param environ
|
||||
-- An optional key-value environment table for token expansion; keys and
|
||||
-- values provided in this table will be available for tokens to use.
|
||||
-- @param filename
|
||||
-- An optional filename, which will limit the fetched results to blocks
|
||||
-- which specifically match the provided name.
|
||||
-- @return
|
||||
-- A new context object.
|
||||
--
|
||||
|
||||
function context.new(cfgset, environ)
|
||||
local ctx = {}
|
||||
ctx._cfgset = cfgset
|
||||
ctx.environ = environ or {}
|
||||
ctx.terms = {}
|
||||
|
||||
-- This base directory is used when expanding path tokens encountered
|
||||
-- in non-path value; such values will be made relative to this value
|
||||
-- so the resulting projects will only contain relative paths. It is
|
||||
-- expected that the creator of the context will set this value using
|
||||
-- the setbasedir() function.
|
||||
|
||||
ctx._basedir = os.getcwd()
|
||||
|
||||
-- when a missing field is requested, fetch it from my config
|
||||
-- set, and then cache the value for future lookups
|
||||
setmetatable(ctx, context.__mt)
|
||||
|
||||
return ctx
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Create an extended and uncached context based on another context object.
|
||||
--
|
||||
-- @param baseContext
|
||||
-- The base context to extent
|
||||
-- @param newEnvVars
|
||||
-- An optional key-value environment table for token expansion; keys and
|
||||
-- values provided in this table will be available for tokens to use.
|
||||
-- @return
|
||||
-- A new context object.
|
||||
--
|
||||
|
||||
function context.extent(baseContext, newEnvVars)
|
||||
local ctx = {}
|
||||
ctx._ctx = baseContext
|
||||
ctx.environ = newEnvVars or baseContext.environ
|
||||
ctx.terms = {}
|
||||
ctx._basedir = baseContext._basedir
|
||||
|
||||
setmetatable(ctx, context.__mt_uncached)
|
||||
|
||||
return ctx
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Add a new key-value pair to refine the context filtering.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The context to be filtered.
|
||||
-- @param key
|
||||
-- The new (or an existing) key value.
|
||||
-- @param value
|
||||
-- The filtering value for the key.
|
||||
---
|
||||
|
||||
function context.addFilter(ctx, key, value)
|
||||
if type(value) == "table" then
|
||||
for i = 1, #value do
|
||||
value[i] = tostring(value[i]):lower()
|
||||
end
|
||||
elseif value ~= nil then
|
||||
value = tostring(value):lower()
|
||||
end
|
||||
ctx.terms[key:lower()] = value
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Copies the list of terms from an existing context.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The context to receive the copied terms.
|
||||
-- @param src
|
||||
-- The context containing the terms to copy.
|
||||
--
|
||||
|
||||
function context.copyFilters(ctx, src)
|
||||
ctx.terms = {}
|
||||
for k,v in pairs(src.terms) do
|
||||
ctx.terms[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Merges the list of terms from an existing context.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The context to receive the copied terms.
|
||||
-- @param src
|
||||
-- The context containing the terms to copy.
|
||||
--
|
||||
|
||||
function context.mergeFilters(ctx, src)
|
||||
for k, v in pairs(src.terms) do
|
||||
if k == "tags" then
|
||||
ctx.terms[k] = table.join(ctx.terms[k], v)
|
||||
else
|
||||
ctx.terms[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Sets the base directory for path token expansion in non-path fields; such
|
||||
-- values will be made relative to this path.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The context in which to set the value.
|
||||
-- @param basedir
|
||||
-- The new base directory for path token expansion. This should be
|
||||
-- provided as an absolute path. This may be left nil to simply fetch
|
||||
-- the current base directory.
|
||||
-- @return
|
||||
-- The context's base directory.
|
||||
--
|
||||
|
||||
function context.basedir(ctx, basedir)
|
||||
ctx._basedir = basedir or ctx._basedir
|
||||
return ctx._basedir
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Compiles the context for better performance. The list of context terms
|
||||
-- becomes locked down; any subsequent changes are ignored.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The context to compile.
|
||||
--
|
||||
|
||||
function context.compile(ctx)
|
||||
ctx._cfgset = configset.compile(ctx._cfgset, ctx.terms)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Check to see if a context's underlying configuration set is empty; that
|
||||
-- is, it does not contain any configuration blocks.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The context to query.
|
||||
-- @return
|
||||
-- True if the set does not contain any blocks.
|
||||
--
|
||||
|
||||
function context.empty(ctx)
|
||||
return configset.empty(ctx._cfgset)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Fetch a value from underlying configuration set.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The context to query.
|
||||
-- @param key
|
||||
-- The property key to query.
|
||||
-- @param onlylocal
|
||||
-- If true, don't combine values from parent contexts.
|
||||
-- @return
|
||||
-- The value of the key, as determined by the configuration set. If
|
||||
-- there is a corresponding Premake field, and it the field is enabled
|
||||
-- for tokens, any contained tokens will be expanded.
|
||||
--
|
||||
|
||||
function context.fetchvalue(ctx, key, onlylocal)
|
||||
if not onlylocal then
|
||||
local value = rawget(ctx, key)
|
||||
if value ~= nil then
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
-- The underlying configuration set will only hold registered fields.
|
||||
-- If the requested key doesn't have a corresponding field, it is just
|
||||
-- a regular value to be stored and fetched from the table.
|
||||
|
||||
local field = p.field.get(key)
|
||||
if not field then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- If there is a matching field, then go fetch the aggregated value
|
||||
-- from my configuration set, and then cache it future lookups.
|
||||
|
||||
local value = configset.fetch(ctx._cfgset, field, ctx.terms, ctx, onlylocal and ctx._cfgset)
|
||||
if value then
|
||||
-- store the result for later lookups
|
||||
rawset(ctx, key, value)
|
||||
end
|
||||
|
||||
return value
|
||||
end
|
||||
|
||||
context.__mt = {
|
||||
__index = context.fetchvalue
|
||||
}
|
||||
|
||||
context.__mt_uncached = {
|
||||
__index = function(ctx, key)
|
||||
local field = p.field.get(key)
|
||||
if not field then
|
||||
return nil
|
||||
end
|
||||
local parent = rawget(ctx, '_ctx')
|
||||
return configset.fetch(parent._cfgset, field, ctx.terms, ctx, nil)
|
||||
end
|
||||
}
|
||||
|
||||
179
Src/external_dependencies/openmpt-trunk/include/premake/src/base/criteria.lua
vendored
Normal file
179
Src/external_dependencies/openmpt-trunk/include/premake/src/base/criteria.lua
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
--
|
||||
-- criteria.lua
|
||||
--
|
||||
-- Stores a list of criteria terms with support for negation, conjunction,
|
||||
-- and wildcard matches. Provides functions match match these criteria
|
||||
-- against various contexts.
|
||||
--
|
||||
-- Copyright (c) 2012-2015 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
|
||||
p.criteria = criteria -- criteria namespace is defined in C host
|
||||
local criteria = p.criteria
|
||||
|
||||
|
||||
--
|
||||
-- These prefixes correspond to the context information built by the oven
|
||||
-- during baking. In theory, any field could be used as a filter, but right
|
||||
-- now only these are set.
|
||||
--
|
||||
|
||||
criteria._validPrefixes = {
|
||||
_action = true,
|
||||
action = true,
|
||||
architecture = true,
|
||||
configurations = true,
|
||||
files = true,
|
||||
kind = true,
|
||||
language = true,
|
||||
_options = true,
|
||||
options = true,
|
||||
platforms = true,
|
||||
sharedlibtype = true,
|
||||
system = true,
|
||||
toolset = true,
|
||||
tags = true,
|
||||
host = true,
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
-- Flattens a hierarchy of criteria terms into a single array containing all
|
||||
-- of the values as strings in the form of "term:value1 or value2" etc.
|
||||
--
|
||||
function criteria.flatten(terms)
|
||||
local result = {}
|
||||
|
||||
local function flatten(terms)
|
||||
for key, value in pairs(terms) do
|
||||
if type(key) == "number" then
|
||||
if type(value) == "table" then
|
||||
flatten(value)
|
||||
elseif value then
|
||||
table.insert(result, value)
|
||||
end
|
||||
elseif type(key) == "string" then
|
||||
local word = key .. ":"
|
||||
if type(value) == "table" then
|
||||
local values = table.flatten(value)
|
||||
word = word .. table.concat(values, " or ")
|
||||
else
|
||||
word = word .. value
|
||||
end
|
||||
table.insert(result, word)
|
||||
else
|
||||
error("Unknown key type in terms.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
flatten(terms)
|
||||
return result
|
||||
end
|
||||
|
||||
---
|
||||
-- Create a new criteria object.
|
||||
--
|
||||
-- @param terms
|
||||
-- A list of criteria terms.
|
||||
-- @param unprefixed
|
||||
-- If true, use the old style, unprefixed filter terms. This will
|
||||
-- eventually be phased out in favor of prefixed terms only.
|
||||
-- @return
|
||||
-- A new criteria object.
|
||||
---
|
||||
|
||||
function criteria.new(terms, unprefixed)
|
||||
terms = criteria.flatten(terms)
|
||||
|
||||
-- Preprocess the list of terms for better performance in matches().
|
||||
-- Each term is replaced with a pattern, with an implied AND between
|
||||
-- them. Each pattern contains one or more words, with an implied OR
|
||||
-- between them. A word maybe be flagged as negated, or as a wildcard
|
||||
-- pattern, and may have a field prefix associated with it.
|
||||
|
||||
local patterns = {}
|
||||
|
||||
for i, term in ipairs(terms) do
|
||||
term = term:lower()
|
||||
|
||||
local pattern = {}
|
||||
local prefix = iif(unprefixed, nil, "configurations")
|
||||
|
||||
local words = term:explode(" or ")
|
||||
for _, word in ipairs(words) do
|
||||
word, prefix = criteria._word(word, prefix)
|
||||
if prefix and not criteria._validPrefixes[prefix] then
|
||||
return nil, string.format("Invalid field prefix '%s'", prefix)
|
||||
end
|
||||
|
||||
-- check for field value aliases
|
||||
if prefix then
|
||||
local fld = p.field.get(prefix)
|
||||
if fld and fld.aliases then
|
||||
word[1] = fld.aliases[word[1]] or word[1]
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(pattern, word)
|
||||
end
|
||||
|
||||
table.insert(patterns, pattern)
|
||||
end
|
||||
|
||||
-- The matching logic is written in C now for performance; compile
|
||||
-- this collection of patterns to C data structures to make that
|
||||
-- code easier to read and maintain.
|
||||
|
||||
local crit = {}
|
||||
crit.patterns = patterns
|
||||
crit.data = criteria._compile(patterns)
|
||||
crit.terms = terms
|
||||
return crit
|
||||
end
|
||||
|
||||
|
||||
|
||||
function criteria._word(word, prefix)
|
||||
local wildcard
|
||||
local assertion = true
|
||||
|
||||
-- Trim off all "not" and field prefixes and check for wildcards
|
||||
while (true) do
|
||||
if word:startswith("not ") then
|
||||
assertion = not assertion
|
||||
word = word:sub(5)
|
||||
else
|
||||
local i = word:find(":", 1, true)
|
||||
if prefix and i then
|
||||
prefix = word:sub(1, i - 1)
|
||||
word = word:sub(i + 1)
|
||||
else
|
||||
wildcard = (word:find("*", 1, true) ~= nil)
|
||||
if wildcard then
|
||||
word = path.wildcards(word)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return { word, prefix, assertion, wildcard }, prefix
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Add a new prefix to the list of allowed values for filters. Note
|
||||
-- setting a prefix on its own has no effect on the output; a filter
|
||||
-- term must also be set on the corresponding context during baking.
|
||||
--
|
||||
-- @param prefix
|
||||
-- The new prefix to be allowed.
|
||||
---
|
||||
|
||||
function criteria.allowPrefix(prefix)
|
||||
criteria._validPrefixes[prefix:lower()] = true
|
||||
end
|
||||
|
||||
202
Src/external_dependencies/openmpt-trunk/include/premake/src/base/detoken.lua
vendored
Normal file
202
Src/external_dependencies/openmpt-trunk/include/premake/src/base/detoken.lua
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
--
|
||||
-- detoken.lua
|
||||
--
|
||||
-- Expands tokens.
|
||||
--
|
||||
-- Copyright (c) 2011-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
p.detoken = {}
|
||||
|
||||
local detoken = p.detoken
|
||||
|
||||
|
||||
--
|
||||
-- Expand tokens in a value.
|
||||
--
|
||||
-- @param value
|
||||
-- The value containing the tokens to be expanded.
|
||||
-- @param environ
|
||||
-- An execution environment for any token expansion. This is a list of
|
||||
-- key-value pairs that will be inserted as global variables into the
|
||||
-- token expansion runtime environment.
|
||||
-- @param field
|
||||
-- The definition of the field which stores the value.
|
||||
-- @param basedir
|
||||
-- If provided, path tokens encountered in non-path fields (where
|
||||
-- field.paths is set to false) will be made relative to this location.
|
||||
-- @return
|
||||
-- The value with any contained tokens expanded.
|
||||
--
|
||||
|
||||
function detoken.expand(value, environ, field, basedir)
|
||||
function expandtoken(token, e, f)
|
||||
-- fetch the path variable from the action, if needed
|
||||
local varMap = {}
|
||||
if f.pathVars or e.overridePathVars then
|
||||
local action = p.action.current()
|
||||
if action then
|
||||
varMap = action.pathVars or {}
|
||||
end
|
||||
end
|
||||
|
||||
-- fetch the pathVars from the enviroment.
|
||||
local envMap = e.pathVars or {}
|
||||
|
||||
-- enable access to the global environment
|
||||
setmetatable(e, {__index = _G})
|
||||
|
||||
local isAbs = false
|
||||
local err
|
||||
local result
|
||||
local success
|
||||
|
||||
-- if the token starts with a !, don't try making it relative.
|
||||
local dontMakeRelative = token:startswith('!')
|
||||
if dontMakeRelative then
|
||||
token = token:sub(2, -1)
|
||||
end
|
||||
|
||||
-- If this token is in my path variable mapping tables, replace the
|
||||
-- value with the one from the map. This needs to go here because
|
||||
-- I don't want to make the result relative, but I don't want the
|
||||
-- absolute path handling below.
|
||||
local mapped = envMap[token] or varMap[token]
|
||||
if mapped then
|
||||
err = nil
|
||||
result = mapped
|
||||
if type(result) == "function" then
|
||||
success, result = pcall(result, e)
|
||||
if not success then
|
||||
return nil, result
|
||||
end
|
||||
end
|
||||
|
||||
if (type(result) == "table") then
|
||||
isAbs = result.absolute
|
||||
result = result.token
|
||||
else
|
||||
isAbs = path.isabsolute(result)
|
||||
end
|
||||
else
|
||||
-- convert the token into a function to execute
|
||||
local func
|
||||
func, err = load("return " .. token, nil, 't', e)
|
||||
if not func then
|
||||
return nil, "load error: " .. err
|
||||
end
|
||||
|
||||
-- run it and get the result
|
||||
success, result = pcall(func)
|
||||
if not success then
|
||||
err = result
|
||||
result = nil
|
||||
else
|
||||
err = nil
|
||||
result = result or ""
|
||||
end
|
||||
|
||||
if result ~= nil then
|
||||
-- ensure we got a string.
|
||||
result = tostring(result)
|
||||
|
||||
-- If the result is an absolute path, and it is being inserted into
|
||||
-- a NON-path value, I need to make it relative to the project that
|
||||
-- will contain it. Otherwise I ended up with an absolute path in
|
||||
-- the generated project, and it can no longer be moved around.
|
||||
if path.hasdeferredjoin(result) then
|
||||
result = path.resolvedeferredjoin(result)
|
||||
end
|
||||
isAbs = path.isabsolute(result)
|
||||
if isAbs and not f.paths and basedir and not dontMakeRelative then
|
||||
result = path.getrelative(basedir, result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If the result is an absolute path, and it is being inserted into
|
||||
-- a path value, place a special marker at the start of it. After
|
||||
-- all results have been processed, I can look for these markers to
|
||||
-- find the last absolute path expanded.
|
||||
--
|
||||
-- Example: the value "/home/user/myprj/%{cfg.objdir}" expands to:
|
||||
-- "/home/user/myprj//home/user/myprj/obj/Debug".
|
||||
--
|
||||
-- By inserting a marker this becomes:
|
||||
-- "/home/user/myprj/[\0]/home/user/myprj/obj/Debug".
|
||||
--
|
||||
-- I can now trim everything before the marker to get the right
|
||||
-- result, which should always be the last absolute path specified:
|
||||
-- "/home/user/myprj/obj/Debug"
|
||||
|
||||
if result ~= nil and isAbs and f.paths then
|
||||
result = "\0" .. result
|
||||
end
|
||||
return result, err
|
||||
end
|
||||
|
||||
function expandvalue(value, e, f)
|
||||
if type(value) ~= "string" then
|
||||
return value
|
||||
end
|
||||
|
||||
local count
|
||||
repeat
|
||||
value, count = value:gsub("%%{(.-)}", function(token)
|
||||
local result, err = expandtoken(token:gsub("\\", "\\\\"), e, f)
|
||||
if err then
|
||||
error(err .. " in token: " .. token, 0)
|
||||
end
|
||||
if not result then
|
||||
error("Token returned nil, it may not exist: " .. token, 0)
|
||||
end
|
||||
return result
|
||||
end)
|
||||
until count == 0
|
||||
|
||||
-- if a path, look for a split out embedded absolute paths
|
||||
if f.paths then
|
||||
local i, j
|
||||
repeat
|
||||
i, j = value:find("\0")
|
||||
if i then
|
||||
value = value:sub(i + 1)
|
||||
end
|
||||
until not i
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local expand_cache = {}
|
||||
|
||||
function recurse(value, e, f)
|
||||
if type(value) == "table" then
|
||||
local res_table = {}
|
||||
|
||||
for k, v in pairs(value) do
|
||||
if tonumber(k) ~= nil then
|
||||
res_table[k] = recurse(v, e, f)
|
||||
else
|
||||
local nk = recurse(k, e, f)
|
||||
res_table[nk] = recurse(v, e, f)
|
||||
end
|
||||
end
|
||||
|
||||
return res_table
|
||||
else
|
||||
local res = expand_cache[value]
|
||||
if res == nil then
|
||||
if type(value) == "string" and path.hasdeferredjoin(value) then
|
||||
value = path.resolvedeferredjoin(value)
|
||||
end
|
||||
res = expandvalue(value, e, f)
|
||||
expand_cache[value] = res
|
||||
end
|
||||
return res
|
||||
end
|
||||
end
|
||||
|
||||
return recurse(value, environ, field or {})
|
||||
end
|
||||
|
||||
391
Src/external_dependencies/openmpt-trunk/include/premake/src/base/field.lua
vendored
Normal file
391
Src/external_dependencies/openmpt-trunk/include/premake/src/base/field.lua
vendored
Normal file
@@ -0,0 +1,391 @@
|
||||
---
|
||||
-- base/field.lua
|
||||
--
|
||||
-- Fields hold a particular bit of information about a configuration, such
|
||||
-- as the language of a project or the list of files it uses. Each field has
|
||||
-- a particular data "kind", which describes the structure of the information
|
||||
-- it holds, such a simple string, or a list of paths.
|
||||
--
|
||||
-- The field.* functions here manage the definition of these fields, and the
|
||||
-- accessor functions required to get, set, remove, and merge their values.
|
||||
--
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.field = {}
|
||||
local field = p.field
|
||||
|
||||
|
||||
-- Lists to hold all of the registered fields and data kinds
|
||||
|
||||
field._list = {}
|
||||
field._loweredList = {}
|
||||
field._sortedList = nil
|
||||
field._kinds = {}
|
||||
|
||||
-- For historical reasons
|
||||
premake.fields = field._list
|
||||
|
||||
-- A cache for data kind accessor functions
|
||||
|
||||
field._accessors = {}
|
||||
|
||||
|
||||
---
|
||||
-- Register a new field.
|
||||
--
|
||||
-- @param f
|
||||
-- A table describing the new field, with these keys:
|
||||
-- name A unique string name for the field, to be used to identify
|
||||
-- the field in future operations.
|
||||
-- kind The kind of values that can be stored into this field. Kinds
|
||||
-- can be chained together to create more complex types, such as
|
||||
-- "list:string".
|
||||
--
|
||||
-- In addition, any custom keys set on the field description will be
|
||||
-- maintained.
|
||||
--
|
||||
-- @return
|
||||
-- A populated field object. Or nil and an error message if the field could
|
||||
-- not be registered.
|
||||
---
|
||||
|
||||
function field.new(f)
|
||||
-- Translate the old approaches to data kind definitions to the new
|
||||
-- one used here. These should probably be deprecated eventually.
|
||||
|
||||
if f.kind:startswith("key-") then
|
||||
f.kind = f.kind:sub(5)
|
||||
f.keyed = true
|
||||
end
|
||||
|
||||
if f.kind:endswith("-list") then
|
||||
f.kind = f.kind:sub(1, -6)
|
||||
f.list = true
|
||||
end
|
||||
|
||||
local kind = f.kind
|
||||
|
||||
if kind == "object" or kind == "array" then
|
||||
kind = "table"
|
||||
end
|
||||
|
||||
if f.list then
|
||||
kind = "list:" .. kind
|
||||
end
|
||||
|
||||
if f.keyed then
|
||||
kind = "keyed:" .. kind
|
||||
end
|
||||
|
||||
-- Store the translated kind with a new name, so legacy add-on code
|
||||
-- can continue to work with the old value.
|
||||
|
||||
f._kind = kind
|
||||
|
||||
-- Make sure scope is always an array; don't overwrite old value
|
||||
if type(f.scope) == "table" then
|
||||
f.scopes = f.scope
|
||||
else
|
||||
f.scopes = { f.scope }
|
||||
end
|
||||
|
||||
-- All fields must have a valid store() function
|
||||
if not field.accessor(f, "store") then
|
||||
return nil, "invalid field kind '" .. f._kind .. "'"
|
||||
end
|
||||
|
||||
field._list[f.name] = f
|
||||
field._loweredList[f.name:lower()] = f
|
||||
field._sortedList = nil
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Remove a previously created field definition.
|
||||
---
|
||||
|
||||
function field.unregister(f)
|
||||
field._list[f.name] = nil
|
||||
field._loweredList[f.name:lower()] = nil
|
||||
field._sortedList = nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Returns an iterator for the list of registered fields; the
|
||||
-- ordering of returned results is arbitrary.
|
||||
---
|
||||
|
||||
function field.each()
|
||||
local index
|
||||
return function ()
|
||||
index = next(field._list, index)
|
||||
return field._list[index]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Returns an iterator for the list of registered fields; the
|
||||
-- results are in a prioritized order, then alphabetized.
|
||||
---
|
||||
|
||||
function field.eachOrdered()
|
||||
if not field._sortedList then
|
||||
-- no priorities yet, just alpha sort
|
||||
local keys = table.keys(field._list)
|
||||
table.sort(keys)
|
||||
|
||||
field._sortedList = {}
|
||||
for i = 1, #keys do
|
||||
field._sortedList[i] = field._list[keys[i]]
|
||||
end
|
||||
end
|
||||
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
return field._sortedList[i]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Register a new kind of data for field storage.
|
||||
--
|
||||
-- @param tag
|
||||
-- A unique name of the kind; used in the kind string in new field
|
||||
-- definitions (see new(), above).
|
||||
-- @param settings
|
||||
-- A table containing the processor functions for the new kind. If
|
||||
-- nil, no change is made to the current field settings.
|
||||
-- @return
|
||||
-- The settings table for the specified tag.
|
||||
---
|
||||
|
||||
function field.kind(tag, settings)
|
||||
if settings then
|
||||
field._kinds[tag] = settings
|
||||
end
|
||||
return field._kinds[tag]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Build an "accessor" function to process incoming values for a field. This
|
||||
-- function should be an interview question.
|
||||
--
|
||||
-- An accessor function takes the form of:
|
||||
--
|
||||
-- function (field, current, value, nextAccessor)
|
||||
--
|
||||
-- It receives the target field, the current value of that field, and the new
|
||||
-- value that has been provided by the project script. It then returns the
|
||||
-- new value for the target field.
|
||||
--
|
||||
-- @param f
|
||||
-- The field for which an accessor should be returned.
|
||||
-- @param method
|
||||
-- The type of accessor function required; currently this should be one of
|
||||
-- "store", "remove", or "merge" though it is possible for add-on modules to
|
||||
-- extend the available methods by implementing appropriate processing
|
||||
-- functions.
|
||||
-- @return
|
||||
-- An accessor function for the field's kind and method. May return nil
|
||||
-- if no processing functions are available for the given method.
|
||||
---
|
||||
|
||||
|
||||
function field.accessor(f, method)
|
||||
-- Prepare a cache for accessors using this method; each encountered
|
||||
-- kind only needs to be fully processed once.
|
||||
|
||||
field._accessors[method] = field._accessors[method] or {}
|
||||
local cache = field._accessors[method]
|
||||
|
||||
-- Helper function recurses over each piece of the field's data kind,
|
||||
-- building an accessor function for each sequence encountered. Results
|
||||
-- cached from earlier calls are reused again.
|
||||
|
||||
local function accessorForKind(kind)
|
||||
-- I'll end up with a kind of "" when I hit the end of the string
|
||||
if kind == "" then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Have I already cached a result from an earlier call?
|
||||
if cache[kind] then
|
||||
return cache[kind]
|
||||
end
|
||||
|
||||
-- Split off the first piece from the rest of the kind. If the
|
||||
-- incoming kind is "list:key:string", thisKind will be "list"
|
||||
-- and nextKind will be "key:string".
|
||||
|
||||
local thisKind = kind:match('(.-):') or kind
|
||||
local nextKind = kind:sub(#thisKind + 2)
|
||||
|
||||
-- Get the processor function for this kind. Processors perform
|
||||
-- data validation and storage appropriate for the data structure.
|
||||
|
||||
local functions = field._kinds[thisKind]
|
||||
if not functions then
|
||||
return nil, "Invalid field kind '" .. thisKind .. "'"
|
||||
end
|
||||
|
||||
local processor = functions[method]
|
||||
if not processor then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Now recurse to get the accessor function for the remaining parts
|
||||
-- of the field's data kind. If the kind was "list:key:string", then
|
||||
-- the processor function handles the "list" part, and this function
|
||||
-- takes care of the "key:string" part.
|
||||
|
||||
local nextAccessor = accessorForKind(nextKind)
|
||||
|
||||
-- Now here's the magic: wrap the processor and the next accessor
|
||||
-- up together into a Matryoshka doll of function calls, each call
|
||||
-- handling just it's level of the kind.
|
||||
|
||||
accessor = function(f, current, value)
|
||||
return processor(f, current, value, nextAccessor)
|
||||
end
|
||||
|
||||
-- And cache the result so I don't have to go through that again
|
||||
cache[kind] = accessor
|
||||
return accessor
|
||||
end
|
||||
|
||||
return accessorForKind(f._kind)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function field.compare(f, a, b)
|
||||
local processor = field.accessor(f, "compare")
|
||||
if processor then
|
||||
return processor(f, a, b)
|
||||
else
|
||||
return (a == b)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Fetch a field description by name.
|
||||
---
|
||||
|
||||
function field.get(name)
|
||||
return field._list[name] or field._loweredList[name:lower()]
|
||||
end
|
||||
|
||||
|
||||
|
||||
function field.merge(f, current, value)
|
||||
local processor = field.accessor(f, "merge")
|
||||
if processor then
|
||||
return processor(f, current, value)
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Is this a field that supports merging values together? Non-merging fields
|
||||
-- can simply overwrite their values, merging fields can call merge() to
|
||||
-- combine two values together.
|
||||
---
|
||||
|
||||
function field.merges(f)
|
||||
return (field.accessor(f, "merge") ~= nil)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a property from a field, based on it's data kind. Allows extra
|
||||
-- information to be stored along with the data kind definitions; use this
|
||||
-- call to find the first value in the field's data kind chain.
|
||||
---
|
||||
|
||||
function field.property(f, tag)
|
||||
local kinds = string.explode(f._kind, ":", true)
|
||||
for i, kind in ipairs(kinds) do
|
||||
local value = field._kinds[kind][tag]
|
||||
if value ~= nil then
|
||||
return value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Override one of the field kind accessor functions. This works just like
|
||||
-- p.override(), but applies the new function to the internal field
|
||||
-- description and clears the accessor caches to make sure the change gets
|
||||
-- picked up by future operations.
|
||||
---
|
||||
|
||||
function field.override(fieldName, accessorName, func)
|
||||
local kind = field.kind(fieldName)
|
||||
p.override(kind, accessorName, func)
|
||||
field._accessors = {}
|
||||
end
|
||||
|
||||
|
||||
function field.remove(f, current, value)
|
||||
local processor = field.accessor(f, "remove")
|
||||
if processor then
|
||||
return processor(f, current, value)
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function field.removes(f)
|
||||
return (field.accessor(f, "merge") ~= nil and field.accessor(f, "remove") ~= nil)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function field.store(f, current, value)
|
||||
local processor = field.accessor(f, "store")
|
||||
if processor then
|
||||
return processor(f, current, value)
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function field.translate(f, value)
|
||||
local processor = field.accessor(f, "translate")
|
||||
if processor then
|
||||
return processor(f, value, nil)[1]
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function field.translates(f)
|
||||
return (field.accessor(f, "translate") ~= nil)
|
||||
end
|
||||
|
||||
300
Src/external_dependencies/openmpt-trunk/include/premake/src/base/fileconfig.lua
vendored
Normal file
300
Src/external_dependencies/openmpt-trunk/include/premake/src/base/fileconfig.lua
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
--
|
||||
-- fileconfig.lua
|
||||
-- The set of configuration information for a specific file.
|
||||
-- Copyright (c) 2011-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
p.fileconfig = {}
|
||||
|
||||
local fileconfig = p.fileconfig
|
||||
local context = p.context
|
||||
local project = p.project
|
||||
|
||||
|
||||
--
|
||||
-- A little confusing: the file configuration actually contains two objects.
|
||||
-- The first object, the one that is returned by fileconfig.new() and later
|
||||
-- passed back in as *the* file configuration object, contains the common
|
||||
-- project-wide settings for the file. This object also contains a list of
|
||||
-- "sub-configurations", one for each project configuration to which the file
|
||||
-- belongs.
|
||||
--
|
||||
-- Internally, I'm calling the first object the "file configuration" (fcfg)
|
||||
-- and the children "file sub-configurations" (fsub). To distinguish them
|
||||
-- from the project configurations (cfg).
|
||||
--
|
||||
-- Define metatables for each of types; more info below.
|
||||
--
|
||||
|
||||
fileconfig.fcfg_mt = {}
|
||||
fileconfig.fsub_mt = {}
|
||||
|
||||
|
||||
--
|
||||
-- Create a new file configuration object.
|
||||
--
|
||||
-- @param fname
|
||||
-- The absolute path to the file.
|
||||
-- @param prj
|
||||
-- The project which contains the file.
|
||||
-- @return
|
||||
-- A new file configuration object.
|
||||
--
|
||||
|
||||
function fileconfig.new(fname, prj)
|
||||
local environ = { }
|
||||
local fcfg = context.new(prj, environ)
|
||||
context.copyFilters(fcfg, prj)
|
||||
context.addFilter(fcfg, "files", fname:lower())
|
||||
|
||||
for key, value in pairs(prj.environ) do
|
||||
environ[key] = value
|
||||
end
|
||||
|
||||
environ.file = fcfg
|
||||
context.compile(fcfg)
|
||||
|
||||
fcfg.project = prj
|
||||
fcfg.workspace = prj.workspace
|
||||
fcfg.configs = {}
|
||||
fcfg.abspath = fname
|
||||
|
||||
context.basedir(fcfg, prj.location)
|
||||
|
||||
-- Most of the other path properties are computed on demand
|
||||
-- from the file's absolute path.
|
||||
|
||||
setmetatable(fcfg, fileconfig.fcfg_mt)
|
||||
|
||||
-- Except for the virtual path, which is expensive to compute, and
|
||||
-- can be used across all the sub-configurations
|
||||
|
||||
local vpath = project.getvpath(prj, fname)
|
||||
if vpath ~= fcfg.abspath then
|
||||
fcfg.vpath = vpath
|
||||
end
|
||||
|
||||
return fcfg
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Associate a new project configuration with a file. It is possible for a
|
||||
-- file to only appear in a subset of a project's configurations.
|
||||
--
|
||||
-- @param fcfg
|
||||
-- The file configuration to which the project configuration should be
|
||||
-- associated.
|
||||
-- @param cfg
|
||||
-- The project configuration to associate.
|
||||
--
|
||||
|
||||
function fileconfig.addconfig(fcfg, cfg)
|
||||
local prj = cfg.project
|
||||
local wks = cfg.workspace
|
||||
|
||||
-- Create a new context object for this configuration-file pairing.
|
||||
-- The context has the ability to pull out configuration settings
|
||||
-- specific to the file.
|
||||
|
||||
local environ = {}
|
||||
local fsub = context.new(prj, environ)
|
||||
context.copyFilters(fsub, fcfg)
|
||||
context.mergeFilters(fsub, cfg)
|
||||
|
||||
fcfg.configs[cfg] = fsub
|
||||
|
||||
-- set up an environment for expanding tokens contained by this file
|
||||
-- configuration; based on the configuration's environment so that
|
||||
-- any magic set up there gets maintained
|
||||
|
||||
for key, value in pairs(cfg.environ) do
|
||||
environ[key] = value
|
||||
end
|
||||
|
||||
for key, value in pairs(fcfg.environ) do
|
||||
environ[key] = value
|
||||
end
|
||||
|
||||
-- finish the setup
|
||||
|
||||
context.compile(fsub)
|
||||
fsub.abspath = fcfg.abspath
|
||||
fsub.vpath = fcfg.vpath
|
||||
fsub.config = cfg
|
||||
fsub.project = prj
|
||||
fsub.workspace = wks
|
||||
|
||||
-- Set the context's base directory to the project's file system
|
||||
-- location. Any path tokens which are expanded in non-path fields
|
||||
-- (such as the custom build commands) will be made relative to
|
||||
-- this path, ensuring a portable generated project.
|
||||
|
||||
context.basedir(fsub, prj.location)
|
||||
|
||||
return setmetatable(fsub, fileconfig.fsub_mt)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the configuration settings for a particular file/project
|
||||
-- configuration pairing.
|
||||
--
|
||||
-- @param fcfg
|
||||
-- The file configuration to query.
|
||||
-- @param cfg
|
||||
-- The project configuration to query.
|
||||
-- @return
|
||||
-- The configuration context for the pairing, or nil if this project
|
||||
-- configuration is not associated with this file.
|
||||
--
|
||||
|
||||
function fileconfig.getconfig(fcfg, cfg)
|
||||
return fcfg.configs[cfg]
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Checks to see if the project or file configuration contains a
|
||||
-- custom build rule.
|
||||
--
|
||||
-- @param cfg
|
||||
-- A project or file configuration.
|
||||
-- @return
|
||||
-- True if the configuration contains settings for a custom
|
||||
-- build rule.
|
||||
--
|
||||
|
||||
function fileconfig.hasCustomBuildRule(fcfg)
|
||||
return fcfg and (#fcfg.buildcommands > 0) and (#fcfg.buildoutputs > 0)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Checks to see if the file configuration contains any unique information,
|
||||
-- or if it is the same as its parent configuration.
|
||||
--
|
||||
-- @param fcfg
|
||||
-- A file configuration.
|
||||
-- @return
|
||||
-- True if the file configuration contains values which differ from the
|
||||
-- parent project configuration, false otherwise.
|
||||
--
|
||||
|
||||
function fileconfig.hasFileSettings(fcfg)
|
||||
if not fcfg then
|
||||
return false
|
||||
end
|
||||
for key, field in pairs(p.fields) do
|
||||
if field.scopes[1] == "config" then
|
||||
local value = fcfg[field.name]
|
||||
if value then
|
||||
if type(value) == "table" then
|
||||
if #value > 0 then
|
||||
return true
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Rather than store pre-computed strings for all of the path variations
|
||||
-- (abspath, relpath, vpath, name, etc.) for each file (there can be quite
|
||||
-- a lot of them) I assign a metatable to the file configuration objects
|
||||
-- that will build these values on the fly.
|
||||
--
|
||||
-- I am using these pseudo-properties, rather than explicit functions, to make
|
||||
-- it easier to fetch them script tokens (i.e. %{file.relpath} with no need
|
||||
-- for knowledge of the internal Premake APIs.
|
||||
--
|
||||
|
||||
|
||||
--
|
||||
-- The indexer for the file configurations. If I have a path building function
|
||||
-- to fulfill the request, call it. Else fall back to the context's own value lookups.
|
||||
--
|
||||
|
||||
local fcfg_mt = fileconfig.fcfg_mt
|
||||
|
||||
fcfg_mt.__index = function(fcfg, key)
|
||||
if type(fcfg_mt[key]) == "function" then
|
||||
return fcfg_mt[key](fcfg)
|
||||
end
|
||||
return context.__mt.__index(fcfg, key)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- The indexer for the file sub-configurations. Check for a path building
|
||||
-- function first, and then fall back to the context's own value lookups.
|
||||
-- TODO: Would be great if this didn't require inside knowledge of context.
|
||||
--
|
||||
|
||||
fileconfig.fsub_mt.__index = function(fsub, key)
|
||||
if type(fcfg_mt[key]) == "function" then
|
||||
return fcfg_mt[key](fsub)
|
||||
end
|
||||
return context.__mt.__index(fsub, key)
|
||||
end
|
||||
|
||||
--
|
||||
-- And here are the path building functions.
|
||||
--
|
||||
|
||||
function fcfg_mt.basename(fcfg)
|
||||
return path.getbasename(fcfg.abspath)
|
||||
end
|
||||
|
||||
|
||||
function fcfg_mt.directory(fcfg)
|
||||
return path.getdirectory(fcfg.abspath)
|
||||
end
|
||||
|
||||
function fcfg_mt.reldirectory(fcfg)
|
||||
return path.getdirectory(fcfg.relpath)
|
||||
end
|
||||
|
||||
function fcfg_mt.name(fcfg)
|
||||
return path.getname(fcfg.abspath)
|
||||
end
|
||||
|
||||
|
||||
function fcfg_mt.objname(fcfg)
|
||||
if fcfg.sequence ~= nil and fcfg.sequence > 0 then
|
||||
return fcfg.basename .. fcfg.sequence
|
||||
else
|
||||
return fcfg.basename
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function fcfg_mt.path(fcfg)
|
||||
return fcfg.relpath
|
||||
end
|
||||
|
||||
|
||||
function fcfg_mt.relpath(fcfg)
|
||||
return project.getrelative(fcfg.project, fcfg.abspath)
|
||||
end
|
||||
|
||||
|
||||
function fcfg_mt.vpath(fcfg)
|
||||
-- This only gets called if no explicit virtual path was set
|
||||
return fcfg.relpath
|
||||
end
|
||||
|
||||
|
||||
function fcfg_mt.extension(fcfg)
|
||||
return path.getextension(fcfg.abspath)
|
||||
end
|
||||
113
Src/external_dependencies/openmpt-trunk/include/premake/src/base/global.lua
vendored
Normal file
113
Src/external_dependencies/openmpt-trunk/include/premake/src/base/global.lua
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
-- global.lua
|
||||
-- The global container holds workspaces and rules.
|
||||
-- Copyright (c) 2014-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.global = p.api.container("global")
|
||||
local global = p.global
|
||||
|
||||
|
||||
---
|
||||
-- Create a new global container instance.
|
||||
---
|
||||
|
||||
function global.new(name)
|
||||
return p.container.new(p.global, name)
|
||||
end
|
||||
|
||||
---
|
||||
-- Bakes the global scope.
|
||||
---
|
||||
function global.bake(self)
|
||||
p.container.bakeChildren(self)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Iterate over the collection of rules in a session.
|
||||
--
|
||||
-- @returns
|
||||
-- An iterator function.
|
||||
---
|
||||
|
||||
function global.eachRule()
|
||||
local root = p.api.rootContainer()
|
||||
return p.container.eachChild(root, p.rule)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Iterate over the collection of workspaces in a session.
|
||||
--
|
||||
-- @returns
|
||||
-- A workspace iterator function.
|
||||
---
|
||||
|
||||
function global.eachWorkspace()
|
||||
local root = p.api.rootContainer()
|
||||
return p.container.eachChild(root, p.workspace)
|
||||
end
|
||||
|
||||
p.alias(global, "eachWorkspace", "eachSolution")
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a rule by name or index.
|
||||
--
|
||||
-- @param key
|
||||
-- The rule key, either a string name or integer index.
|
||||
-- @returns
|
||||
-- The rule with the provided key.
|
||||
---
|
||||
|
||||
function global.getRule(key)
|
||||
local root = p.api.rootContainer()
|
||||
return root.rules[key]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve the rule to applies to the provided file name, if any such
|
||||
-- rule exists.
|
||||
--
|
||||
-- @param fname
|
||||
-- The name of the file.
|
||||
-- @param rules
|
||||
-- A list of rule names to be included in the search. If not specified,
|
||||
-- all rules will be checked.
|
||||
-- @returns
|
||||
-- The rule, is one has been registered, or nil.
|
||||
---
|
||||
|
||||
function global.getRuleForFile(fname, rules)
|
||||
for rule in global.eachRule() do
|
||||
if not rules or table.contains(rules, rule.name) then
|
||||
if path.hasextension(fname, rule.fileextension) then
|
||||
return rule
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a workspace by name or index.
|
||||
--
|
||||
-- @param key
|
||||
-- The workspace key, either a string name or integer index.
|
||||
-- @returns
|
||||
-- The workspace with the provided key.
|
||||
---
|
||||
|
||||
function global.getWorkspace(key)
|
||||
local root = p.api.rootContainer()
|
||||
return root.workspaces[key]
|
||||
end
|
||||
|
||||
p.alias(global, "getWorkspace", "getSolution")
|
||||
85
Src/external_dependencies/openmpt-trunk/include/premake/src/base/globals.lua
vendored
Normal file
85
Src/external_dependencies/openmpt-trunk/include/premake/src/base/globals.lua
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
--
|
||||
-- globals.lua
|
||||
-- Replacements and extensions to Lua's global functions.
|
||||
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
--
|
||||
-- Find and execute a Lua source file present on the filesystem, but
|
||||
-- continue without error if the file is not present. This is used to
|
||||
-- handle optional files such as the premake-system.lua script.
|
||||
--
|
||||
-- @param fname
|
||||
-- The name of the file to load. This may be specified as a single
|
||||
-- file path or an array of file paths, in which case the first
|
||||
-- file found is run.
|
||||
-- @return
|
||||
-- True if a file was found and executed, nil otherwise.
|
||||
--
|
||||
|
||||
function dofileopt(fname)
|
||||
if type(fname) == "string" then fname = {fname} end
|
||||
for i = 1, #fname do
|
||||
local found = os.locate(fname[i])
|
||||
if not found then
|
||||
found = os.locate(fname[i] .. ".lua")
|
||||
end
|
||||
if found then
|
||||
dofile(found)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Load and run an external script file, with a bit of extra logic to make
|
||||
-- including projects easier. if "path" is a directory, will look for
|
||||
-- path/premake5.lua. And each file is tracked, and loaded only once.
|
||||
--
|
||||
-- @param fname
|
||||
-- The name of the directory or file to include. If a directory, will
|
||||
-- automatically include the contained premake5.lua or premake4.lua
|
||||
-- script at that lcoation.
|
||||
---
|
||||
|
||||
io._includedFiles = {}
|
||||
|
||||
function include(fname)
|
||||
local fullPath = premake.findProjectScript(fname)
|
||||
fname = fullPath or fname
|
||||
if not io._includedFiles[fname] then
|
||||
io._includedFiles[fname] = true
|
||||
return dofile(fname)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Extend require() with a second argument to specify the expected
|
||||
-- version of the loaded module. Raises an error if the version criteria
|
||||
-- are not met.
|
||||
--
|
||||
-- @param modname
|
||||
-- The name of the module to load.
|
||||
-- @param versions
|
||||
-- An optional version criteria string; see premake.checkVersion()
|
||||
-- for more information on the format.
|
||||
-- @return
|
||||
-- If successful, the loaded module, which is also stored into the
|
||||
-- global package.loaded table.
|
||||
---
|
||||
|
||||
premake.override(_G, "require", function(base, modname, versions)
|
||||
local result, mod = pcall(base,modname)
|
||||
if not result then
|
||||
error(mod, 3)
|
||||
end
|
||||
if mod and versions and not premake.checkVersion(mod._VERSION, versions) then
|
||||
error(string.format("module %s %s does not meet version criteria %s",
|
||||
modname, mod._VERSION or "(none)", versions), 3)
|
||||
end
|
||||
return mod
|
||||
end)
|
||||
22
Src/external_dependencies/openmpt-trunk/include/premake/src/base/group.lua
vendored
Normal file
22
Src/external_dependencies/openmpt-trunk/include/premake/src/base/group.lua
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
-- group.lua
|
||||
-- A psuedo-configuration container to represent project groups.
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.group = p.api.container("group", p.workspace)
|
||||
local group = p.group
|
||||
|
||||
|
||||
---
|
||||
-- Bit of a hack: prevent groups from holding any configuration data.
|
||||
---
|
||||
|
||||
group.placeholder = true
|
||||
|
||||
|
||||
|
||||
function group.new(name)
|
||||
return p.container.new(group, name)
|
||||
end
|
||||
81
Src/external_dependencies/openmpt-trunk/include/premake/src/base/help.lua
vendored
Normal file
81
Src/external_dependencies/openmpt-trunk/include/premake/src/base/help.lua
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
--
|
||||
-- help.lua
|
||||
-- User help, displayed on /help option.
|
||||
-- Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
function premake.showhelp()
|
||||
|
||||
-- display the basic usage
|
||||
printf("Premake %s, a build script generator", _PREMAKE_VERSION)
|
||||
printf(_PREMAKE_COPYRIGHT)
|
||||
printf("%s %s", _VERSION, _COPYRIGHT)
|
||||
printf("")
|
||||
printf("Usage: premake5 [options] action [arguments]")
|
||||
printf("")
|
||||
|
||||
-- filter all options by category.
|
||||
local categories = {}
|
||||
for option in premake.option.each() do
|
||||
local cat = "OPTIONS - General"
|
||||
if option.category then
|
||||
cat = "OPTIONS - " .. option.category;
|
||||
end
|
||||
|
||||
if categories[cat] then
|
||||
table.insert(categories[cat], option)
|
||||
else
|
||||
categories[cat] = {option}
|
||||
end
|
||||
end
|
||||
|
||||
-- display all options
|
||||
for k, options in spairs(categories) do
|
||||
printf(k)
|
||||
printf("")
|
||||
|
||||
local length = 0
|
||||
for _, option in ipairs(options) do
|
||||
local trigger = option.trigger
|
||||
if (option.value) then trigger = trigger .. "=" .. option.value end
|
||||
if (#trigger > length) then length = #trigger end
|
||||
end
|
||||
|
||||
for _, option in ipairs(options) do
|
||||
local trigger = option.trigger
|
||||
local description = option.description
|
||||
if (option.value) then trigger = trigger .. "=" .. option.value end
|
||||
if (option.allowed) then description = description .. "; one of:" end
|
||||
|
||||
printf(" --%-" .. length .. "s %s", trigger, description)
|
||||
if (option.allowed) then
|
||||
local function compareValue(a, b)
|
||||
return a[1] < b[1]
|
||||
end
|
||||
table.sort(option.allowed, compareValue)
|
||||
|
||||
for _, value in ipairs(option.allowed) do
|
||||
printf(" %-" .. length-1 .. "s %s", value[1], value[2])
|
||||
end
|
||||
printf("")
|
||||
end
|
||||
end
|
||||
printf("")
|
||||
end
|
||||
|
||||
-- display all actions
|
||||
printf("ACTIONS")
|
||||
printf("")
|
||||
for action in premake.action.each() do
|
||||
printf(" %-17s %s", action.trigger, action.description)
|
||||
end
|
||||
printf("")
|
||||
|
||||
|
||||
-- see more
|
||||
printf("For additional information, see https://premake.github.io")
|
||||
|
||||
end
|
||||
|
||||
|
||||
68
Src/external_dependencies/openmpt-trunk/include/premake/src/base/http.lua
vendored
Normal file
68
Src/external_dependencies/openmpt-trunk/include/premake/src/base/http.lua
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
--
|
||||
-- http.lua
|
||||
-- Additions to the http namespace.
|
||||
-- Copyright (c) 2008-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
if http == nil then
|
||||
return
|
||||
end
|
||||
|
||||
---
|
||||
-- Simple progress bar on stdout for curl downloads.
|
||||
---
|
||||
|
||||
function http.reportProgress(total, current)
|
||||
local width = 70
|
||||
local progress = math.floor(current * width / total)
|
||||
|
||||
if progress == width then
|
||||
io.write(string.rep(' ', width + 2) .. '\r')
|
||||
else
|
||||
io.write('[' .. string.rep('=', progress) .. string.rep(' ', width - progress) .. ']\r')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Correctly escape parameters for use in a url.
|
||||
---
|
||||
|
||||
function http.escapeUrlParam(param)
|
||||
local url_encodings = {
|
||||
[' '] = '%%20',
|
||||
['!'] = '%%21',
|
||||
['"'] = '%%22',
|
||||
['#'] = '%%23',
|
||||
['$'] = '%%24',
|
||||
['&'] = '%%26',
|
||||
['\''] = '%%27',
|
||||
['('] = '%%28',
|
||||
[')'] = '%%29',
|
||||
['*'] = '%%2A',
|
||||
['+'] = '%%2B',
|
||||
['-'] = '%%2D',
|
||||
['.'] = '%%2E',
|
||||
['/'] = '%%2F',
|
||||
[':'] = '%%3A',
|
||||
[';'] = '%%3B',
|
||||
['<'] = '%%3C',
|
||||
['='] = '%%3D',
|
||||
['>'] = '%%3E',
|
||||
['?'] = '%%3F',
|
||||
['@'] = '%%40',
|
||||
['['] = '%%5B',
|
||||
['\\'] = '%%5C',
|
||||
[']'] = '%%5D',
|
||||
['^'] = '%%5E',
|
||||
['_'] = '%%5F',
|
||||
['`'] = '%%60'
|
||||
}
|
||||
|
||||
param = param:gsub('%%', '%%25')
|
||||
for k,v in pairs(url_encodings) do
|
||||
param = param:gsub('%' .. k, v)
|
||||
end
|
||||
|
||||
return param
|
||||
end
|
||||
47
Src/external_dependencies/openmpt-trunk/include/premake/src/base/io.lua
vendored
Normal file
47
Src/external_dependencies/openmpt-trunk/include/premake/src/base/io.lua
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
--
|
||||
-- io.lua
|
||||
-- Additions to the I/O namespace.
|
||||
-- Copyright (c) 2008-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
--
|
||||
-- Open an overload of the io.open() function, which will create any missing
|
||||
-- subdirectories in the filename if "mode" is set to writeable.
|
||||
--
|
||||
|
||||
premake.override(io, "open", function(base, fname, mode)
|
||||
if mode and (mode:find("w") or mode:find("a")) then
|
||||
local dir = path.getdirectory(fname)
|
||||
ok, err = os.mkdir(dir)
|
||||
if not ok then
|
||||
error(err, 0)
|
||||
end
|
||||
end
|
||||
return base(fname, mode)
|
||||
end)
|
||||
|
||||
|
||||
--
|
||||
-- Write content to a new file.
|
||||
--
|
||||
function io.writefile(filename, content)
|
||||
local file = io.open(filename, "w+b")
|
||||
if file then
|
||||
file:write(content)
|
||||
file:close()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Read content from new file.
|
||||
--
|
||||
function io.readfile(filename)
|
||||
local file = io.open(filename, "rb")
|
||||
if file then
|
||||
local content = file:read("*a")
|
||||
file:close()
|
||||
return content
|
||||
end
|
||||
end
|
||||
1548
Src/external_dependencies/openmpt-trunk/include/premake/src/base/json.lua
vendored
Normal file
1548
Src/external_dependencies/openmpt-trunk/include/premake/src/base/json.lua
vendored
Normal file
File diff suppressed because it is too large
Load Diff
59
Src/external_dependencies/openmpt-trunk/include/premake/src/base/jsonwrapper.lua
vendored
Normal file
59
Src/external_dependencies/openmpt-trunk/include/premake/src/base/jsonwrapper.lua
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
--
|
||||
-- jsonwrapper.lua
|
||||
-- Provides JSON encoding and decoding API by wrapping a third-party JSON library
|
||||
-- Copyright (c) 2017 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
json = {}
|
||||
|
||||
local implementation = dofile('json.lua')
|
||||
local err
|
||||
json.implementation = implementation
|
||||
|
||||
function implementation.assert(condition, message)
|
||||
if not condition then
|
||||
err = message
|
||||
end
|
||||
|
||||
-- The JSON library we're using assumes that encode error handlers will
|
||||
-- abort on error. It doesn't have the same assumption for decode error
|
||||
-- handlers, but we're using this same function for both.
|
||||
|
||||
assert(condition, message)
|
||||
end
|
||||
|
||||
function json.encode(value)
|
||||
err = nil
|
||||
|
||||
local success, result = pcall(implementation.encode, implementation, value)
|
||||
|
||||
if not success then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function json.encode_pretty(value)
|
||||
err = nil
|
||||
|
||||
local success, result = pcall(implementation.encode_pretty, implementation, value)
|
||||
|
||||
if not success then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function json.decode(value)
|
||||
err = nil
|
||||
|
||||
local success, result = pcall(implementation.decode, implementation, value)
|
||||
|
||||
if not success then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
24
Src/external_dependencies/openmpt-trunk/include/premake/src/base/languages.lua
vendored
Normal file
24
Src/external_dependencies/openmpt-trunk/include/premake/src/base/languages.lua
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
-- languages.lua
|
||||
-- Language helpers.
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.languages = {}
|
||||
|
||||
function p.languages.isc(value)
|
||||
return value == "C";
|
||||
end
|
||||
|
||||
function p.languages.iscpp(value)
|
||||
return value == "C++";
|
||||
end
|
||||
|
||||
function p.languages.iscsharp(value)
|
||||
return value == "C#";
|
||||
end
|
||||
|
||||
function p.languages.isfsharp(value)
|
||||
return value == "F#";
|
||||
end
|
||||
174
Src/external_dependencies/openmpt-trunk/include/premake/src/base/option.lua
vendored
Normal file
174
Src/external_dependencies/openmpt-trunk/include/premake/src/base/option.lua
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
--
|
||||
-- option.lua
|
||||
-- Work with the list of registered options.
|
||||
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
p.option = {}
|
||||
local m = p.option
|
||||
|
||||
|
||||
--
|
||||
-- We can't control how people will type in the command line arguments, or how
|
||||
-- project scripts will define their custom options, so case becomes an issue.
|
||||
-- To mimimize issues, set up the _OPTIONS table to always use lowercase keys.
|
||||
--
|
||||
|
||||
local _OPTIONS_metatable = {
|
||||
__index = function(tbl, key)
|
||||
if type(key) == "string" then
|
||||
key = key:lower()
|
||||
end
|
||||
return rawget(tbl, key)
|
||||
end,
|
||||
__newindex = function(tbl, key, value)
|
||||
if type(key) == "string" then
|
||||
key = key:lower()
|
||||
end
|
||||
rawset(tbl, key, value)
|
||||
end
|
||||
}
|
||||
|
||||
_OPTIONS = {}
|
||||
setmetatable(_OPTIONS, _OPTIONS_metatable)
|
||||
|
||||
|
||||
--
|
||||
-- Process the raw command line arguments from _ARGV to populate
|
||||
-- the _OPTIONS table
|
||||
--
|
||||
|
||||
for i, arg in ipairs(_ARGV) do
|
||||
local key, value
|
||||
local i = arg:find("=", 1, true)
|
||||
if i then
|
||||
key = arg:sub(1, i - 1)
|
||||
value = arg:sub(i + 1)
|
||||
else
|
||||
key = arg
|
||||
value = ""
|
||||
end
|
||||
|
||||
if key:startswith("/") then
|
||||
_OPTIONS[key:sub(2)] = value
|
||||
elseif key:startswith("--") then
|
||||
_OPTIONS[key:sub(3)] = value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- The list of registered options. Calls to newoption() will add
|
||||
-- new entries here.
|
||||
--
|
||||
|
||||
m.list = {}
|
||||
|
||||
|
||||
--
|
||||
-- Register a new option.
|
||||
--
|
||||
-- @param opt
|
||||
-- The new option object.
|
||||
--
|
||||
|
||||
function m.add(opt)
|
||||
-- some sanity checking
|
||||
local missing
|
||||
for _, field in ipairs({ "description", "trigger" }) do
|
||||
if (not opt[field]) then
|
||||
missing = field
|
||||
end
|
||||
end
|
||||
|
||||
if (missing) then
|
||||
error("option needs a " .. missing, 3)
|
||||
end
|
||||
|
||||
-- add it to the master list
|
||||
p.option.list[opt.trigger:lower()] = opt
|
||||
|
||||
-- if it has a default value, set it.
|
||||
if opt.default and not _OPTIONS[opt.trigger] then
|
||||
_OPTIONS[opt.trigger] = opt.default
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve an option by name.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the option to retrieve.
|
||||
-- @returns
|
||||
-- The requested option, or nil if the option does not exist.
|
||||
--
|
||||
|
||||
function m.get(name)
|
||||
return p.option.list[name]
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Iterator for the list of options.
|
||||
--
|
||||
|
||||
function m.each()
|
||||
-- sort the list by trigger
|
||||
local keys = { }
|
||||
for _, option in pairs(p.option.list) do
|
||||
table.insert(keys, option.trigger)
|
||||
end
|
||||
table.sort(keys)
|
||||
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
return p.option.list[keys[i]]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Validate a list of user supplied key/value pairs against the list of registered options.
|
||||
--
|
||||
-- @param values
|
||||
-- The list of user supplied key/value pairs.
|
||||
-- @returns
|
||||
--- True if the list of pairs are valid, false and an error message otherwise.
|
||||
--
|
||||
|
||||
function m.validate(values)
|
||||
for key, value in pairs(values) do
|
||||
-- does this option exist
|
||||
local opt = p.option.get(key)
|
||||
if (not opt) then
|
||||
return false, "invalid option '" .. key .. "'"
|
||||
end
|
||||
|
||||
-- does it need a value?
|
||||
if (opt.value and value == "") then
|
||||
return false, "no value specified for option '" .. key .. "'"
|
||||
end
|
||||
|
||||
-- is the value allowed?
|
||||
if opt.allowed then
|
||||
local found = false
|
||||
for _, match in ipairs(opt.allowed) do
|
||||
if match[1] == value then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
return false, string.format("invalid value '%s' for option '%s'", value, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
809
Src/external_dependencies/openmpt-trunk/include/premake/src/base/os.lua
vendored
Normal file
809
Src/external_dependencies/openmpt-trunk/include/premake/src/base/os.lua
vendored
Normal file
@@ -0,0 +1,809 @@
|
||||
--
|
||||
-- os.lua
|
||||
-- Additions to the OS namespace.
|
||||
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
---
|
||||
-- Extend Lua's built-in os.execute() with token expansion and
|
||||
-- path normalization.
|
||||
--
|
||||
|
||||
premake.override(os, "execute", function(base, cmd)
|
||||
cmd = os.translateCommands(cmd)
|
||||
return base(cmd)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Same as os.execute(), but accepts string formatting arguments.
|
||||
---
|
||||
|
||||
function os.executef(cmd, ...)
|
||||
cmd = string.format(cmd, ...)
|
||||
return os.execute(cmd)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Scan the well-known system locations for a particular library.
|
||||
--
|
||||
|
||||
local function parse_ld_so_conf(conf_file)
|
||||
-- Linux ldconfig file parser to find system library locations
|
||||
local first, last
|
||||
local dirs = { }
|
||||
for line in io.lines(conf_file) do
|
||||
-- ignore comments
|
||||
first = line:find("#", 1, true)
|
||||
if first ~= nil then
|
||||
line = line:sub(1, first - 1)
|
||||
end
|
||||
|
||||
if line ~= "" then
|
||||
-- check for include files
|
||||
first, last = line:find("include%s+")
|
||||
if first ~= nil then
|
||||
-- found include glob
|
||||
local include_glob = line:sub(last + 1)
|
||||
local includes = os.matchfiles(include_glob)
|
||||
for _, v in ipairs(includes) do
|
||||
dirs = table.join(dirs, parse_ld_so_conf(v))
|
||||
end
|
||||
else
|
||||
-- found an actual ld path entry
|
||||
table.insert(dirs, line)
|
||||
end
|
||||
end
|
||||
end
|
||||
return dirs
|
||||
end
|
||||
|
||||
local function get_library_search_path()
|
||||
local path
|
||||
if os.istarget("windows") then
|
||||
path = os.getenv("PATH") or ""
|
||||
elseif os.istarget("haiku") then
|
||||
path = os.getenv("LIBRARY_PATH") or ""
|
||||
else
|
||||
if os.istarget("darwin") then
|
||||
path = os.getenv("DYLD_LIBRARY_PATH") or ""
|
||||
else
|
||||
path = os.getenv("LD_LIBRARY_PATH") or ""
|
||||
|
||||
for _, prefix in ipairs({"", "/opt"}) do
|
||||
local conf_file = prefix .. "/etc/ld.so.conf"
|
||||
if os.isfile(conf_file) then
|
||||
for _, v in ipairs(parse_ld_so_conf(conf_file)) do
|
||||
if (#path > 0) then
|
||||
path = path .. ":" .. v
|
||||
else
|
||||
path = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
path = path or ""
|
||||
local archpath = "/lib:/usr/lib:/usr/local/lib"
|
||||
if os.is64bit() and not (os.istarget("darwin")) then
|
||||
archpath = "/lib64:/usr/lib64/:usr/local/lib64" .. ":" .. archpath
|
||||
end
|
||||
if (#path > 0) then
|
||||
path = path .. ":" .. archpath
|
||||
else
|
||||
path = archpath
|
||||
end
|
||||
end
|
||||
|
||||
return path
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Attempt to locate and return the path to a shared library.
|
||||
--
|
||||
-- This function does not work to locate system libraries on macOS 11 or later; it may still
|
||||
-- be used to locate user libraries: _"New in macOS Big Sur 11.0.1, the system ships with
|
||||
-- a built-in dynamic linker cache of all system-provided libraries. As part of this change,
|
||||
-- copies of dynamic libraries are no longer present on the filesystem. Code that attempts to
|
||||
-- check for dynamic library presence by looking for a file at a path or enumerating a directory
|
||||
-- will fail."
|
||||
-- https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11_0_1-release-notes
|
||||
--
|
||||
-- @param libname
|
||||
-- The library name with or without prefix and suffix.
|
||||
-- @param libdirs
|
||||
-- An array of paths to be searched.
|
||||
-- @returns
|
||||
-- The full path to the library if found; `nil` otherwise.
|
||||
---
|
||||
function os.findlib(libname, libdirs)
|
||||
local path = get_library_search_path()
|
||||
local formats
|
||||
|
||||
-- assemble a search path, depending on the platform
|
||||
if os.istarget("windows") then
|
||||
formats = { "%s.dll", "%s" }
|
||||
elseif os.istarget("haiku") then
|
||||
formats = { "lib%s.so", "%s.so" }
|
||||
else
|
||||
if os.istarget("darwin") then
|
||||
formats = { "lib%s.dylib", "%s.dylib" }
|
||||
else
|
||||
formats = { "lib%s.so", "%s.so" }
|
||||
end
|
||||
|
||||
table.insert(formats, "%s")
|
||||
end
|
||||
|
||||
local userpath = ""
|
||||
|
||||
if type(libdirs) == "string" then
|
||||
userpath = libdirs
|
||||
elseif type(libdirs) == "table" then
|
||||
userpath = table.implode(libdirs, "", "", ":")
|
||||
end
|
||||
|
||||
if (#userpath > 0) then
|
||||
if (#path > 0) then
|
||||
path = userpath .. ":" .. path
|
||||
else
|
||||
path = userpath
|
||||
end
|
||||
end
|
||||
|
||||
for _, fmt in ipairs(formats) do
|
||||
local name = string.format(fmt, libname)
|
||||
local result = os.pathsearch(name, path)
|
||||
if result then return result end
|
||||
end
|
||||
end
|
||||
|
||||
function os.findheader(headerpath, headerdirs)
|
||||
-- headerpath: a partial header file path
|
||||
-- headerdirs: additional header search paths
|
||||
|
||||
local path = get_library_search_path()
|
||||
|
||||
-- replace all /lib by /include
|
||||
path = path .. ':'
|
||||
path = path:gsub ('/lib[0-9]*([:/])', '/include%1')
|
||||
path = path:sub (1, #path - 1)
|
||||
|
||||
local userpath = ""
|
||||
|
||||
if type(headerdirs) == "string" then
|
||||
userpath = headerdirs
|
||||
elseif type(headerdirs) == "table" then
|
||||
userpath = table.implode(headerdirs, "", "", ":")
|
||||
end
|
||||
|
||||
if (#userpath > 0) then
|
||||
if (#path > 0) then
|
||||
path = userpath .. ":" .. path
|
||||
else
|
||||
path = userpath
|
||||
end
|
||||
end
|
||||
|
||||
local result = os.pathsearch (headerpath, path)
|
||||
return result
|
||||
end
|
||||
|
||||
--
|
||||
-- Retrieve the current target operating system ID string.
|
||||
--
|
||||
|
||||
function os.target()
|
||||
return _OPTIONS.os or _TARGET_OS
|
||||
end
|
||||
|
||||
function os.get()
|
||||
local caller = filelineinfo(2)
|
||||
premake.warnOnce(caller, "os.get() is deprecated, use 'os.target()' or 'os.host()'.\n @%s\n", caller)
|
||||
return os.target()
|
||||
end
|
||||
|
||||
-- deprecate _OS
|
||||
_G_metatable = {
|
||||
__index = function(t, k)
|
||||
if (k == '_OS') then
|
||||
premake.warnOnce("_OS+get", "_OS is deprecated, use '_TARGET_OS'.")
|
||||
return rawget(t, "_TARGET_OS")
|
||||
else
|
||||
return rawget(t, k)
|
||||
end
|
||||
end,
|
||||
|
||||
__newindex = function(t, k, v)
|
||||
if (k == '_OS') then
|
||||
premake.warnOnce("_OS+set", "_OS is deprecated, use '_TARGET_OS'.")
|
||||
rawset(t, "_TARGET_OS", v)
|
||||
else
|
||||
rawset(t, k, v)
|
||||
end
|
||||
end
|
||||
}
|
||||
setmetatable(_G, _G_metatable)
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Check the current target operating system; may be set with the /os command line flag.
|
||||
--
|
||||
|
||||
function os.istarget(id)
|
||||
local tags = os.getSystemTags(os.target())
|
||||
return table.contains(tags, id:lower())
|
||||
end
|
||||
|
||||
function os.is(id)
|
||||
local caller = filelineinfo(2)
|
||||
premake.warnOnce(caller, "os.is() is deprecated, use 'os.istarget()' or 'os.ishost()'.\n @%s\n", caller)
|
||||
return os.istarget(id)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Check the current host operating system.
|
||||
--
|
||||
|
||||
function os.ishost(id)
|
||||
local tags = os.getSystemTags(os.host())
|
||||
return table.contains(tags, id:lower())
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Determine if a directory exists on the file system, and that it is a
|
||||
-- directory and not a file.
|
||||
--
|
||||
-- @param p
|
||||
-- The path to check.
|
||||
-- @return
|
||||
-- True if a directory exists at the given path.
|
||||
---
|
||||
|
||||
premake.override(os, "isdir", function(base, p)
|
||||
p = path.normalize(p)
|
||||
return base(p)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Determine if a file exists on the file system, and that it is a
|
||||
-- file and not a directory.
|
||||
--
|
||||
-- @param p
|
||||
-- The path to check.
|
||||
-- @return
|
||||
-- True if a file exists at the given path.
|
||||
---
|
||||
|
||||
premake.override(os, "isfile", function(base, p)
|
||||
p = path.normalize(p)
|
||||
return base(p)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Determine if the current system is running a 64-bit architecture.
|
||||
--
|
||||
|
||||
local _is64bit
|
||||
|
||||
local _64BitHostTypes = {
|
||||
"x86_64",
|
||||
"ia64",
|
||||
"amd64",
|
||||
"ppc64",
|
||||
"powerpc64",
|
||||
"sparc64"
|
||||
}
|
||||
|
||||
function os.is64bit()
|
||||
-- This can be expensive to compute, so cache and reuse the response
|
||||
if _is64bit ~= nil then
|
||||
return _is64bit
|
||||
end
|
||||
|
||||
_is64bit = false
|
||||
|
||||
-- Call the native code implementation. If this returns true then
|
||||
-- we're 64-bit, otherwise do more checking locally
|
||||
if (os._is64bit()) then
|
||||
_is64bit = true
|
||||
else
|
||||
-- Identify the system
|
||||
local arch
|
||||
if os.ishost("windows") then
|
||||
arch = os.getenv("PROCESSOR_ARCHITECTURE")
|
||||
elseif os.ishost("macosx") then
|
||||
arch = os.outputof("echo $HOSTTYPE")
|
||||
else
|
||||
arch = os.outputof("uname -m")
|
||||
end
|
||||
|
||||
-- Check our known 64-bit identifiers
|
||||
arch = arch:lower()
|
||||
for _, hosttype in ipairs(_64BitHostTypes) do
|
||||
if arch:find(hosttype) then
|
||||
_is64bit = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return _is64bit
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Perform a wildcard search for files and directories.
|
||||
--
|
||||
-- @param mask
|
||||
-- The file search pattern. Use "*" to match any part of a file or
|
||||
-- directory name, "**" to recurse into subdirectories.
|
||||
-- @return
|
||||
-- A table containing the matched file or directory names.
|
||||
---
|
||||
|
||||
function os.match(mask)
|
||||
mask = path.normalize(mask)
|
||||
local starpos = mask:find("%*")
|
||||
local before = path.getdirectory(starpos and mask:sub(1, starpos - 1) or mask)
|
||||
local slashpos = starpos and mask:find("/", starpos)
|
||||
local after = slashpos and mask:sub(slashpos + 1)
|
||||
|
||||
-- Only recurse for path components starting with '**':
|
||||
local recurse = starpos and
|
||||
mask:sub(starpos + 1, starpos + 1) == '*' and
|
||||
(starpos == 1 or mask:sub(starpos - 1, starpos - 1) == '/')
|
||||
|
||||
local results = { }
|
||||
|
||||
if recurse then
|
||||
local submask = mask:sub(1, starpos) .. mask:sub(starpos + 2)
|
||||
results = os.match(submask)
|
||||
|
||||
local pattern = mask:sub(1, starpos)
|
||||
local m = os.matchstart(pattern)
|
||||
while os.matchnext(m) do
|
||||
if not os.matchisfile(m) then
|
||||
local matchpath = path.join(before, os.matchname(m), mask:sub(starpos))
|
||||
results = table.join(results, os.match(matchpath))
|
||||
end
|
||||
end
|
||||
os.matchdone(m)
|
||||
else
|
||||
local pattern = mask:sub(1, slashpos and slashpos - 1)
|
||||
local m = os.matchstart(pattern)
|
||||
while os.matchnext(m) do
|
||||
if not (slashpos and os.matchisfile(m)) then
|
||||
local matchpath = path.join(before, matchpath, os.matchname(m))
|
||||
if after then
|
||||
results = table.join(results, os.match(path.join(matchpath, after)))
|
||||
else
|
||||
table.insert(results, matchpath)
|
||||
end
|
||||
end
|
||||
end
|
||||
os.matchdone(m)
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Perform a wildcard search for directories.
|
||||
--
|
||||
-- @param mask
|
||||
-- The search pattern. Use "*" to match any part of a directory
|
||||
-- name, "**" to recurse into subdirectories.
|
||||
-- @return
|
||||
-- A table containing the matched directory names.
|
||||
---
|
||||
|
||||
function os.matchdirs(mask)
|
||||
local results = os.match(mask)
|
||||
for i = #results, 1, -1 do
|
||||
if not os.isdir(results[i]) then
|
||||
table.remove(results, i)
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Perform a wildcard search for files.
|
||||
--
|
||||
-- @param mask
|
||||
-- The search pattern. Use "*" to match any part of a file
|
||||
-- name, "**" to recurse into subdirectories.
|
||||
-- @return
|
||||
-- A table containing the matched directory names.
|
||||
---
|
||||
|
||||
function os.matchfiles(mask)
|
||||
local results = os.match(mask)
|
||||
for i = #results, 1, -1 do
|
||||
if not os.isfile(results[i]) then
|
||||
table.remove(results, i)
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
--
|
||||
-- An overload of the os.mkdir() function, which will create any missing
|
||||
-- subdirectories along the path.
|
||||
--
|
||||
|
||||
local builtin_mkdir = os.mkdir
|
||||
function os.mkdir(p)
|
||||
p = path.normalize(p)
|
||||
|
||||
local dir = iif(p:startswith("/"), "/", "")
|
||||
for part in p:gmatch("[^/]+") do
|
||||
dir = dir .. part
|
||||
|
||||
if (part ~= "" and not path.isabsolute(part) and not os.isdir(dir)) then
|
||||
local ok, err = builtin_mkdir(dir)
|
||||
if (not ok) then
|
||||
return nil, err
|
||||
end
|
||||
end
|
||||
|
||||
dir = dir .. "/"
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Run a shell command and return the output.
|
||||
--
|
||||
-- @param cmd Command to execute
|
||||
-- @param streams Standard stream(s) to output
|
||||
-- Must be one of
|
||||
-- - "both" (default)
|
||||
-- - "output" Return standard output stream content only
|
||||
-- - "error" Return standard error stream content only
|
||||
--
|
||||
|
||||
function os.outputof(cmd, streams)
|
||||
cmd = path.normalize(cmd)
|
||||
streams = streams or "both"
|
||||
local redirection
|
||||
if streams == "both" then
|
||||
redirection = " 2>&1"
|
||||
elseif streams == "output" then
|
||||
redirection = " 2>/dev/null"
|
||||
elseif streams == "error" then
|
||||
redirection = " 2>&1 1>/dev/null"
|
||||
else
|
||||
error ('Invalid stream(s) selection. "output", "error", or "both" expected.')
|
||||
end
|
||||
|
||||
local pipe = io.popen(cmd .. redirection)
|
||||
local result = pipe:read('*a')
|
||||
local success, what, code = pipe:close()
|
||||
if success then
|
||||
-- chomp trailing newlines
|
||||
if result then
|
||||
result = string.gsub(result, "[\r\n]+$", "")
|
||||
end
|
||||
|
||||
return result, code, what
|
||||
else
|
||||
return nil, code, what
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- @brief An overloaded os.remove() that will be able to handle list of files,
|
||||
-- as well as wildcards for files. Uses the syntax os.matchfiles() for
|
||||
-- matching pattern wildcards.
|
||||
--
|
||||
-- @param f A file, a wildcard, or a list of files or wildcards to be removed
|
||||
--
|
||||
-- @return true on success, false and an appropriate error message on error
|
||||
--
|
||||
-- @example ok, err = os.remove{"**.bak", "**.log"}
|
||||
-- if not ok then
|
||||
-- error(err)
|
||||
-- end
|
||||
--
|
||||
|
||||
local builtin_remove = os.remove
|
||||
function os.remove(f)
|
||||
-- in case of string, just match files
|
||||
if type(f) == "string" then
|
||||
local p = os.matchfiles(f)
|
||||
for _, v in pairs(p) do
|
||||
local ok, err, code = builtin_remove(v)
|
||||
if not ok then
|
||||
return ok, err, code
|
||||
end
|
||||
end
|
||||
if #p == 0 then
|
||||
return nil, "Couldn't find any file matching: " .. f, 1
|
||||
end
|
||||
-- in case of table, match files for every table entry
|
||||
elseif type(f) == "table" then
|
||||
for _, v in pairs(f) do
|
||||
local ok, err, code = os.remove(v)
|
||||
if not ok then
|
||||
return ok, err, code
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Remove a directory, along with any contained files or subdirectories.
|
||||
--
|
||||
-- @return true on success, false and an appropriate error message on error
|
||||
|
||||
local builtin_rmdir = os.rmdir
|
||||
function os.rmdir(p)
|
||||
-- recursively remove subdirectories
|
||||
local dirs = os.matchdirs(p .. "/*")
|
||||
for _, dname in ipairs(dirs) do
|
||||
local ok, err = os.rmdir(dname)
|
||||
if not ok then
|
||||
return ok, err
|
||||
end
|
||||
end
|
||||
|
||||
-- remove any files
|
||||
local files = os.matchfiles(p .. "/*")
|
||||
for _, fname in ipairs(files) do
|
||||
local ok, err = os.remove(fname)
|
||||
if not ok then
|
||||
return ok, err
|
||||
end
|
||||
end
|
||||
|
||||
-- remove this directory
|
||||
return builtin_rmdir(p)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Return information about a file.
|
||||
---
|
||||
|
||||
premake.override(os, "stat", function(base, p)
|
||||
p = path.normalize(p)
|
||||
return base(p)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Translate command tokens into their OS or action specific equivalents.
|
||||
---
|
||||
|
||||
os.commandTokens = {
|
||||
_ = {
|
||||
chdir = function(v)
|
||||
return "cd " .. path.normalize(v)
|
||||
end,
|
||||
copy = function(v)
|
||||
return "cp -rf " .. path.normalize(v)
|
||||
end,
|
||||
copyfile = function(v)
|
||||
return "cp -f " .. path.normalize(v)
|
||||
end,
|
||||
copydir = function(v)
|
||||
return "cp -rf " .. path.normalize(v)
|
||||
end,
|
||||
delete = function(v)
|
||||
return "rm -f " .. path.normalize(v)
|
||||
end,
|
||||
echo = function(v)
|
||||
return "echo " .. v
|
||||
end,
|
||||
mkdir = function(v)
|
||||
return "mkdir -p " .. path.normalize(v)
|
||||
end,
|
||||
move = function(v)
|
||||
return "mv -f " .. path.normalize(v)
|
||||
end,
|
||||
rmdir = function(v)
|
||||
return "rm -rf " .. path.normalize(v)
|
||||
end,
|
||||
touch = function(v)
|
||||
return "touch " .. path.normalize(v)
|
||||
end,
|
||||
},
|
||||
windows = {
|
||||
chdir = function(v)
|
||||
return "chdir " .. path.translate(path.normalize(v))
|
||||
end,
|
||||
copy = function(v)
|
||||
v = path.translate(path.normalize(v))
|
||||
|
||||
-- Detect if there's multiple parts to the input, if there is grab the first part else grab the whole thing
|
||||
local src = string.match(v, '^".-"') or string.match(v, '^.- ') or v
|
||||
|
||||
-- Strip the trailing space from the second condition so that we don't have a space between src and '\\NUL'
|
||||
src = string.match(src, '^.*%S')
|
||||
|
||||
return "IF EXIST " .. src .. "\\ (xcopy /Q /E /Y /I " .. v .. " > nul) ELSE (xcopy /Q /Y /I " .. v .. " > nul)"
|
||||
end,
|
||||
copyfile = function(v)
|
||||
v = path.translate(path.normalize(v))
|
||||
-- XCOPY doesn't have a switch to assume destination is a file when it doesn't exist.
|
||||
-- A trailing * will suppress the prompt but requires the file extensions be the same length.
|
||||
-- Just use COPY instead, it actually works.
|
||||
return "copy /B /Y " .. v
|
||||
end,
|
||||
copydir = function(v)
|
||||
v = path.translate(path.normalize(v))
|
||||
return "xcopy /Q /E /Y /I " .. v
|
||||
end,
|
||||
delete = function(v)
|
||||
return "del " .. path.translate(path.normalize(v))
|
||||
end,
|
||||
echo = function(v)
|
||||
return "echo " .. v
|
||||
end,
|
||||
mkdir = function(v)
|
||||
v = path.translate(path.normalize(v))
|
||||
return "IF NOT EXIST " .. v .. " (mkdir " .. v .. ")"
|
||||
end,
|
||||
move = function(v)
|
||||
return "move /Y " .. path.translate(path.normalize(v))
|
||||
end,
|
||||
rmdir = function(v)
|
||||
return "rmdir /S /Q " .. path.translate(path.normalize(v))
|
||||
end,
|
||||
touch = function(v)
|
||||
v = path.translate(path.normalize(v))
|
||||
return string.format("type nul >> %s && copy /b %s+,, %s", v, v, v)
|
||||
end,
|
||||
}
|
||||
}
|
||||
|
||||
function os.translateCommands(cmd, map)
|
||||
map = map or os.target()
|
||||
if type(map) == "string" then
|
||||
map = os.commandTokens[map] or os.commandTokens["_"]
|
||||
end
|
||||
|
||||
local processOne = function(cmd)
|
||||
local i, j, prev
|
||||
repeat
|
||||
i, j = cmd:find("{.-}")
|
||||
if i then
|
||||
if i == prev then
|
||||
break
|
||||
end
|
||||
|
||||
local token = cmd:sub(i + 1, j - 1):lower()
|
||||
local args = cmd:sub(j + 2)
|
||||
local func = map[token] or os.commandTokens["_"][token]
|
||||
if func then
|
||||
cmd = cmd:sub(1, i -1) .. func(args)
|
||||
end
|
||||
|
||||
prev = i
|
||||
end
|
||||
until i == nil
|
||||
return cmd
|
||||
end
|
||||
|
||||
if type(cmd) == "table" then
|
||||
local result = {}
|
||||
for i = 1, #cmd do
|
||||
result[i] = processOne(cmd[i])
|
||||
end
|
||||
return result
|
||||
else
|
||||
return processOne(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Apply os slashes for decorated command paths.
|
||||
---
|
||||
function os.translateCommandAndPath(dir, map)
|
||||
if map == 'windows' then
|
||||
return path.translate(dir)
|
||||
end
|
||||
return dir
|
||||
end
|
||||
|
||||
---
|
||||
-- Translate decorated command paths into their OS equivalents.
|
||||
---
|
||||
function os.translateCommandsAndPaths(cmds, basedir, location, map)
|
||||
local translatedBaseDir = path.getrelative(location, basedir)
|
||||
|
||||
map = map or os.target()
|
||||
|
||||
local translateFunction = function(value)
|
||||
local result = path.join(translatedBaseDir, value)
|
||||
result = os.translateCommandAndPath(result, map)
|
||||
if value:endswith('/') or value:endswith('\\') or -- if orginal path ends with a slash then ensure the same
|
||||
value:endswith('/"') or value:endswith('\\"') then
|
||||
result = result .. '/'
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local processOne = function(cmd)
|
||||
local replaceFunction = function(value)
|
||||
value = value:sub(3, #value - 1)
|
||||
return '"' .. translateFunction(value) .. '"'
|
||||
end
|
||||
return string.gsub(cmd, "%%%[[^%]\r\n]*%]", replaceFunction)
|
||||
end
|
||||
|
||||
if type(cmds) == "table" then
|
||||
local result = {}
|
||||
for i = 1, #cmds do
|
||||
result[i] = processOne(cmds[i])
|
||||
end
|
||||
return os.translateCommands(result, map)
|
||||
else
|
||||
return os.translateCommands(processOne(cmds), map)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Generate a UUID.
|
||||
--
|
||||
|
||||
os._uuids = {}
|
||||
|
||||
local builtin_uuid = os.uuid
|
||||
function os.uuid(name)
|
||||
local id = builtin_uuid(name)
|
||||
if name then
|
||||
if os._uuids[id] and os._uuids[id] ~= name then
|
||||
premake.warnOnce(id, "UUID clash between %s and %s", os._uuids[id], name)
|
||||
end
|
||||
os._uuids[id] = name
|
||||
end
|
||||
return id
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Get a set of tags for different 'platforms'
|
||||
--
|
||||
|
||||
os.systemTags =
|
||||
{
|
||||
["aix"] = { "aix", "posix" },
|
||||
["bsd"] = { "bsd", "posix" },
|
||||
["haiku"] = { "haiku", "posix" },
|
||||
["ios"] = { "ios", "darwin", "posix", "mobile" },
|
||||
["linux"] = { "linux", "posix" },
|
||||
["macosx"] = { "macosx", "darwin", "posix" },
|
||||
["solaris"] = { "solaris", "posix" },
|
||||
["windows"] = { "windows", "win32" },
|
||||
}
|
||||
|
||||
function os.getSystemTags(name)
|
||||
return os.systemTags[name:lower()] or { name:lower() }
|
||||
end
|
||||
792
Src/external_dependencies/openmpt-trunk/include/premake/src/base/oven.lua
vendored
Normal file
792
Src/external_dependencies/openmpt-trunk/include/premake/src/base/oven.lua
vendored
Normal file
@@ -0,0 +1,792 @@
|
||||
--
|
||||
-- base/oven.lua
|
||||
--
|
||||
-- Process the workspaces, projects, and configurations that were specified
|
||||
-- by the project script, and make them suitable for use by the exporters
|
||||
-- and actions. Fills in computed values (e.g. object directories) and
|
||||
-- optimizes the layout of the data for faster fetches.
|
||||
--
|
||||
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
|
||||
p.oven = {}
|
||||
|
||||
local oven = p.oven
|
||||
local context = p.context
|
||||
|
||||
|
||||
--
|
||||
-- These fields get special treatment, "bubbling up" from the configurations
|
||||
-- to the project. This allows you to express, for example: "use this config
|
||||
-- map if this configuration is present in the project", and saves the step
|
||||
-- of clearing the current configuration filter before creating the map.
|
||||
--
|
||||
|
||||
p.oven.bubbledFields = {
|
||||
configmap = true,
|
||||
vpaths = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Traverses the container hierarchy built up by the project scripts and
|
||||
-- filters, merges, and munges the information based on the current runtime
|
||||
-- environment in preparation for doing work on the results, like exporting
|
||||
-- project files.
|
||||
--
|
||||
-- This call replaces the existing the container objects with their
|
||||
-- processed replacements. If you are using the provided container APIs
|
||||
-- (p.global.*, p.workspace.*, etc.) this will be transparent.
|
||||
---
|
||||
|
||||
function oven.bake()
|
||||
-- reset the root _isBaked state.
|
||||
-- this really only affects the unit-tests, since that is the only place
|
||||
-- where multiple bakes per 'exe run' happen.
|
||||
local root = p.api.rootContainer()
|
||||
root._isBaked = false;
|
||||
|
||||
p.container.bake(root)
|
||||
end
|
||||
|
||||
function oven.bakeWorkspace(wks)
|
||||
return p.container.bake(wks)
|
||||
end
|
||||
|
||||
p.alias(oven, "bakeWorkspace", "bakeSolution")
|
||||
|
||||
|
||||
local function addCommonContextFilters(self)
|
||||
context.addFilter(self, "_ACTION", _ACTION)
|
||||
context.addFilter(self, "action", _ACTION)
|
||||
|
||||
self.system = self.system or os.target()
|
||||
context.addFilter(self, "system", os.getSystemTags(self.system))
|
||||
context.addFilter(self, "host", os.getSystemTags(os.host()))
|
||||
|
||||
-- Add command line options to the filtering options
|
||||
local options = {}
|
||||
for key, value in pairs(_OPTIONS) do
|
||||
local term = key
|
||||
if value ~= "" then
|
||||
term = term .. "=" .. tostring(value)
|
||||
end
|
||||
table.insert(options, term)
|
||||
end
|
||||
context.addFilter(self, "_OPTIONS", options)
|
||||
context.addFilter(self, "options", options)
|
||||
end
|
||||
|
||||
---
|
||||
-- Bakes a specific workspace object.
|
||||
---
|
||||
|
||||
function p.workspace.bake(self)
|
||||
-- Add filtering terms to the context and then compile the results. These
|
||||
-- terms describe the "operating environment"; only results contained by
|
||||
-- configuration blocks which match these terms will be returned.
|
||||
|
||||
addCommonContextFilters(self)
|
||||
|
||||
-- Set up my token expansion environment
|
||||
|
||||
self.environ = {
|
||||
wks = self,
|
||||
sln = self,
|
||||
}
|
||||
|
||||
context.compile(self)
|
||||
|
||||
-- Specify the workspaces's file system location; when path tokens are
|
||||
-- expanded in workspace values, they will be made relative to this.
|
||||
|
||||
self.location = self.location or self.basedir
|
||||
context.basedir(self, self.location)
|
||||
|
||||
-- Build a master list of configuration/platform pairs from all of the
|
||||
-- projects contained by the workspace; I will need this when generating
|
||||
-- workspace files in order to provide a map from workspace configurations
|
||||
-- to project configurations.
|
||||
|
||||
self.configs = oven.bakeConfigs(self)
|
||||
|
||||
-- Now bake down all of the projects contained in the workspace, and
|
||||
-- store that for future reference
|
||||
|
||||
p.container.bakeChildren(self)
|
||||
|
||||
-- I now have enough information to assign unique object directories
|
||||
-- to each project configuration in the workspace.
|
||||
|
||||
oven.bakeObjDirs(self)
|
||||
|
||||
-- now we can post process the projects for 'buildoutputs' files
|
||||
-- that have the 'compilebuildoutputs' flag
|
||||
oven.addGeneratedFiles(self)
|
||||
end
|
||||
|
||||
|
||||
function oven.addGeneratedFiles(wks)
|
||||
|
||||
local function addGeneratedFile(cfg, source, filename)
|
||||
-- mark that we have generated files.
|
||||
cfg.project.hasGeneratedFiles = true
|
||||
|
||||
-- add generated file to the project.
|
||||
local files = cfg.project._.files
|
||||
local node = files[filename]
|
||||
if not node then
|
||||
node = p.fileconfig.new(filename, cfg.project)
|
||||
files[filename] = node
|
||||
table.insert(files, node)
|
||||
end
|
||||
|
||||
-- always overwrite the dependency information.
|
||||
node.dependsOn = source
|
||||
node.generated = true
|
||||
|
||||
-- add to config if not already added.
|
||||
if not p.fileconfig.getconfig(node, cfg) then
|
||||
p.fileconfig.addconfig(node, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
local function addFile(cfg, node)
|
||||
local filecfg = p.fileconfig.getconfig(node, cfg)
|
||||
if not filecfg or filecfg.flags.ExcludeFromBuild or not filecfg.compilebuildoutputs then
|
||||
return
|
||||
end
|
||||
|
||||
if p.fileconfig.hasCustomBuildRule(filecfg) then
|
||||
local buildoutputs = filecfg.buildoutputs
|
||||
if buildoutputs and #buildoutputs > 0 then
|
||||
for _, output in ipairs(buildoutputs) do
|
||||
if not path.islinkable(output) then
|
||||
addGeneratedFile(cfg, node, output)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
for prj in p.workspace.eachproject(wks) do
|
||||
local files = table.shallowcopy(prj._.files)
|
||||
for cfg in p.project.eachconfig(prj) do
|
||||
table.foreachi(files, function(node)
|
||||
addFile(cfg, node)
|
||||
end)
|
||||
end
|
||||
|
||||
-- generated files might screw up the object sequences.
|
||||
if prj.hasGeneratedFiles and p.project.isnative(prj) then
|
||||
oven.assignObjectSequences(prj)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function p.project.bake(self)
|
||||
verbosef(' Baking %s...', self.name)
|
||||
|
||||
self.solution = self.workspace
|
||||
self.global = self.workspace.global
|
||||
|
||||
local wks = self.workspace
|
||||
|
||||
-- Add filtering terms to the context to make it as specific as I can.
|
||||
-- Start with the same filtering that was applied at the workspace level.
|
||||
|
||||
context.copyFilters(self, wks)
|
||||
|
||||
-- Now filter on the current system and architecture, allowing the
|
||||
-- values that might already in the context to override my defaults.
|
||||
|
||||
self.system = self.system or os.target()
|
||||
context.addFilter(self, "system", os.getSystemTags(self.system))
|
||||
context.addFilter(self, "host", os.getSystemTags(os.host()))
|
||||
context.addFilter(self, "architecture", self.architecture)
|
||||
context.addFilter(self, "tags", self.tags)
|
||||
|
||||
-- The kind is a configuration level value, but if it has been set at the
|
||||
-- project level allow that to influence the other project-level results.
|
||||
|
||||
context.addFilter(self, "kind", self.kind)
|
||||
|
||||
-- Allow the project object to also be treated like a configuration
|
||||
|
||||
self.project = self
|
||||
|
||||
-- Populate the token expansion environment
|
||||
|
||||
self.environ = {
|
||||
wks = wks,
|
||||
sln = wks,
|
||||
prj = self,
|
||||
}
|
||||
|
||||
-- Go ahead and distill all of that down now; this is my new project object
|
||||
|
||||
context.compile(self)
|
||||
|
||||
p.container.bakeChildren(self)
|
||||
|
||||
-- Set the context's base directory to the project's file system
|
||||
-- location. Any path tokens which are expanded in non-path fields
|
||||
-- are made relative to this, ensuring a portable generated project.
|
||||
|
||||
self.location = self.location or self.basedir
|
||||
context.basedir(self, self.location)
|
||||
|
||||
-- This bit could use some work: create a canonical set of configurations
|
||||
-- for the project, along with a mapping from the workspace's configurations.
|
||||
-- This works, but it could probably be simplified.
|
||||
|
||||
local cfgs = table.fold(self.configurations or {}, self.platforms or {})
|
||||
oven.bubbleFields(self, self, cfgs)
|
||||
self._cfglist = oven.bakeConfigList(self, cfgs)
|
||||
|
||||
-- Don't allow a project-level system setting to influence the configurations
|
||||
|
||||
local projectSystem = self.system
|
||||
self.system = nil
|
||||
|
||||
-- Finally, step through the list of configurations I built above and
|
||||
-- bake all of those down into configuration contexts as well. Store
|
||||
-- the results with the project.
|
||||
|
||||
self.configs = {}
|
||||
|
||||
for _, pairing in ipairs(self._cfglist) do
|
||||
local buildcfg = pairing[1]
|
||||
local platform = pairing[2]
|
||||
local cfg = oven.bakeConfig(wks, self, buildcfg, platform)
|
||||
|
||||
if p.action.supportsconfig(p.action.current(), cfg) then
|
||||
self.configs[(buildcfg or "*") .. (platform or "")] = cfg
|
||||
end
|
||||
end
|
||||
|
||||
-- Process the sub-objects that are contained by this project. The
|
||||
-- configuration build stuff above really belongs in here now.
|
||||
|
||||
self._ = {}
|
||||
self._.files = oven.bakeFiles(self)
|
||||
|
||||
-- If this type of project generates object files, look for files that will
|
||||
-- generate object name collisions (i.e. src/hello.cpp and tests/hello.cpp
|
||||
-- both create hello.o) and assign unique sequence numbers to each. I need
|
||||
-- to do this up front to make sure the sequence numbers are the same for
|
||||
-- all the tools, even they reorder the source file list.
|
||||
|
||||
if p.project.isnative(self) then
|
||||
oven.assignObjectSequences(self)
|
||||
end
|
||||
|
||||
-- at the end, restore the system, so it's usable elsewhere.
|
||||
self.system = projectSystem
|
||||
end
|
||||
|
||||
|
||||
function p.rule.bake(self)
|
||||
-- Add filtering terms to the context and then compile the results. These
|
||||
-- terms describe the "operating environment"; only results contained by
|
||||
-- configuration blocks which match these terms will be returned.
|
||||
|
||||
addCommonContextFilters(self)
|
||||
|
||||
-- Populate the token expansion environment
|
||||
|
||||
self.environ = {
|
||||
rule = self,
|
||||
}
|
||||
|
||||
-- Go ahead and distill all of that down now; this is my new rule object
|
||||
|
||||
context.compile(self)
|
||||
|
||||
-- sort the propertydefinition table.
|
||||
table.sort(self.propertydefinition, function (a, b)
|
||||
return a.name < b.name
|
||||
end)
|
||||
|
||||
-- Set the context's base directory to the rule's file system
|
||||
-- location. Any path tokens which are expanded in non-path fields
|
||||
-- are made relative to this, ensuring a portable generated rule.
|
||||
|
||||
self.location = self.location or self.basedir
|
||||
context.basedir(self, self.location)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Assigns a unique objects directory to every configuration of every project
|
||||
-- in the workspace, taking any objdir settings into account, to ensure builds
|
||||
-- from different configurations won't step on each others' object files.
|
||||
-- The path is built from these choices, in order:
|
||||
--
|
||||
-- [1] -> the objects directory as set in the config
|
||||
-- [2] -> [1] + the platform name
|
||||
-- [3] -> [2] + the build configuration name
|
||||
-- [4] -> [3] + the project name
|
||||
--
|
||||
-- @param wks
|
||||
-- The workspace to process. The directories are modified inline.
|
||||
--
|
||||
|
||||
function oven.bakeObjDirs(wks)
|
||||
-- function to compute the four options for a specific configuration
|
||||
local function getobjdirs(cfg)
|
||||
-- the "!" prefix indicates the directory is not to be touched
|
||||
local objdir = cfg.objdir or "obj"
|
||||
local i = objdir:find("!", 1, true)
|
||||
if i then
|
||||
cfg.objdir = objdir:sub(1, i - 1) .. objdir:sub(i + 1)
|
||||
return nil
|
||||
end
|
||||
|
||||
local dirs = {}
|
||||
|
||||
local dir = path.getabsolute(path.join(cfg.project.location, objdir))
|
||||
table.insert(dirs, dir)
|
||||
|
||||
if cfg.platform then
|
||||
dir = path.join(dir, cfg.platform)
|
||||
table.insert(dirs, dir)
|
||||
end
|
||||
|
||||
dir = path.join(dir, cfg.buildcfg)
|
||||
table.insert(dirs, dir)
|
||||
|
||||
dir = path.join(dir, cfg.project.name)
|
||||
table.insert(dirs, dir)
|
||||
|
||||
return dirs
|
||||
end
|
||||
|
||||
-- walk all of the configs in the workspace, and count the number of
|
||||
-- times each obj dir gets used
|
||||
local counts = {}
|
||||
local configs = {}
|
||||
|
||||
for prj in p.workspace.eachproject(wks) do
|
||||
for cfg in p.project.eachconfig(prj) do
|
||||
-- get the dirs for this config, and associate them together,
|
||||
-- and increment a counter for each one discovered
|
||||
local dirs = getobjdirs(cfg)
|
||||
if dirs then
|
||||
configs[cfg] = dirs
|
||||
for _, dir in ipairs(dirs or {}) do
|
||||
counts[dir] = (counts[dir] or 0) + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- now walk the list again, and assign the first unique value
|
||||
for cfg, dirs in pairs(configs) do
|
||||
for _, dir in ipairs(dirs) do
|
||||
if counts[dir] == 1 then
|
||||
cfg.objdir = dir
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Create a list of workspace-level build configuration/platform pairs.
|
||||
--
|
||||
|
||||
function oven.bakeConfigs(wks)
|
||||
local buildcfgs = wks.configurations or {}
|
||||
local platforms = wks.platforms or {}
|
||||
|
||||
local configs = {}
|
||||
|
||||
local pairings = table.fold(buildcfgs, platforms)
|
||||
for _, pairing in ipairs(pairings) do
|
||||
local cfg = oven.bakeConfig(wks, nil, pairing[1], pairing[2])
|
||||
if p.action.supportsconfig(p.action.current(), cfg) then
|
||||
table.insert(configs, cfg)
|
||||
end
|
||||
end
|
||||
|
||||
return configs
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- It can be useful to state "use this map if this configuration is present".
|
||||
-- To allow this to happen, config maps that are specified within a project
|
||||
-- configuration are allowed to "bubble up" to the top level. Currently,
|
||||
-- maps are the only values that get this special behavior.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The project context information.
|
||||
-- @param cset
|
||||
-- The project's original configuration set, which contains the settings
|
||||
-- of all the project configurations.
|
||||
-- @param cfgs
|
||||
-- The list of the project's build cfg/platform pairs.
|
||||
--
|
||||
|
||||
function oven.bubbleFields(ctx, cset, cfgs)
|
||||
-- build a query filter that will match any configuration name,
|
||||
-- within the existing constraints of the project
|
||||
|
||||
local configurations = {}
|
||||
local platforms = {}
|
||||
|
||||
for _, cfg in ipairs(cfgs) do
|
||||
if cfg[1] then
|
||||
table.insert(configurations, cfg[1]:lower())
|
||||
end
|
||||
if cfg[2] then
|
||||
table.insert(platforms, cfg[2]:lower())
|
||||
end
|
||||
end
|
||||
|
||||
local terms = table.deepcopy(ctx.terms)
|
||||
terms.configurations = configurations
|
||||
terms.platforms = platforms
|
||||
|
||||
for key in pairs(oven.bubbledFields) do
|
||||
local field = p.field.get(key)
|
||||
if not field then
|
||||
ctx[key] = rawget(ctx, key)
|
||||
else
|
||||
local value = p.configset.fetch(cset, field, terms, ctx)
|
||||
if value then
|
||||
ctx[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Builds a list of build configuration/platform pairs for a project,
|
||||
-- along with a mapping between the workspace and project configurations.
|
||||
--
|
||||
-- @param ctx
|
||||
-- The project context information.
|
||||
-- @param cfgs
|
||||
-- The list of the project's build cfg/platform pairs.
|
||||
-- @return
|
||||
-- An array of the project's build configuration/platform pairs,
|
||||
-- based on any discovered mappings.
|
||||
--
|
||||
|
||||
function oven.bakeConfigList(ctx, cfgs)
|
||||
-- run them all through the project's config map
|
||||
for i, cfg in ipairs(cfgs) do
|
||||
cfgs[i] = p.project.mapconfig(ctx, cfg[1], cfg[2])
|
||||
end
|
||||
|
||||
-- walk through the result and remove any duplicates
|
||||
local buildcfgs = {}
|
||||
local platforms = {}
|
||||
|
||||
for _, pairing in ipairs(cfgs) do
|
||||
local buildcfg = pairing[1]
|
||||
local platform = pairing[2]
|
||||
|
||||
if not table.contains(buildcfgs, buildcfg) then
|
||||
table.insert(buildcfgs, buildcfg)
|
||||
end
|
||||
|
||||
if platform and not table.contains(platforms, platform) then
|
||||
table.insert(platforms, platform)
|
||||
end
|
||||
end
|
||||
|
||||
-- merge these de-duped lists back into pairs for the final result
|
||||
return table.fold(buildcfgs, platforms)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Flattens out the build settings for a particular build configuration and
|
||||
-- platform pairing, and returns the result.
|
||||
--
|
||||
-- @param wks
|
||||
-- The workpace which contains the configuration data.
|
||||
-- @param prj
|
||||
-- The project which contains the configuration data. Can be nil.
|
||||
-- @param buildcfg
|
||||
-- The target build configuration, a value from configurations().
|
||||
-- @param platform
|
||||
-- The target platform, a value from platforms().
|
||||
-- @param extraFilters
|
||||
-- Optional. Any extra filter terms to use when retrieving the data for
|
||||
-- this configuration
|
||||
---
|
||||
|
||||
function oven.bakeConfig(wks, prj, buildcfg, platform, extraFilters)
|
||||
|
||||
-- Set the default system and architecture values; if the platform's
|
||||
-- name matches a known system or architecture, use that as the default.
|
||||
-- More than a convenience; this is required to work properly with
|
||||
-- external Visual Studio project files.
|
||||
|
||||
local system = os.target()
|
||||
local architecture = nil
|
||||
local toolset = p.action.current().toolset
|
||||
|
||||
if platform then
|
||||
system = p.api.checkValue(p.fields.system, platform) or system
|
||||
architecture = p.api.checkValue(p.fields.architecture, platform) or architecture
|
||||
toolset = p.api.checkValue(p.fields.toolset, platform) or toolset
|
||||
end
|
||||
|
||||
-- Wrap the projects's configuration set (which contains all of the information
|
||||
-- provided by the project script) with a context object. The context handles
|
||||
-- the expansion of tokens, and caching of retrieved values. The environment
|
||||
-- values are used when expanding tokens.
|
||||
|
||||
local environ = {
|
||||
wks = wks,
|
||||
sln = wks,
|
||||
prj = prj,
|
||||
}
|
||||
|
||||
local ctx = context.new(prj or wks, environ)
|
||||
|
||||
ctx.project = prj
|
||||
ctx.workspace = wks
|
||||
ctx.solution = wks
|
||||
ctx.global = wks.global
|
||||
ctx.buildcfg = buildcfg
|
||||
ctx.platform = platform
|
||||
ctx.action = _ACTION
|
||||
|
||||
-- Allow the configuration information to be accessed by tokens contained
|
||||
-- within the configuration itself
|
||||
|
||||
environ.cfg = ctx
|
||||
|
||||
-- Add filtering terms to the context and then compile the results. These
|
||||
-- terms describe the "operating environment"; only results contained by
|
||||
-- configuration blocks which match these terms will be returned. Start
|
||||
-- by copying over the top-level environment from the workspace. Don't
|
||||
-- copy the project terms though, so configurations can override those.
|
||||
|
||||
context.copyFilters(ctx, wks)
|
||||
|
||||
context.addFilter(ctx, "configurations", buildcfg)
|
||||
context.addFilter(ctx, "platforms", platform)
|
||||
if prj then
|
||||
context.addFilter(ctx, "language", prj.language)
|
||||
end
|
||||
|
||||
-- allow the project script to override the default system
|
||||
ctx.system = ctx.system or system
|
||||
context.addFilter(ctx, "system", os.getSystemTags(ctx.system))
|
||||
context.addFilter(ctx, "host", os.getSystemTags(os.host()))
|
||||
|
||||
-- allow the project script to override the default architecture
|
||||
ctx.architecture = ctx.architecture or architecture
|
||||
context.addFilter(ctx, "architecture", ctx.architecture)
|
||||
|
||||
-- allow the project script to override the default toolset
|
||||
ctx.toolset = _OPTIONS.cc or ctx.toolset or toolset
|
||||
context.addFilter(ctx, "toolset", ctx.toolset)
|
||||
|
||||
-- if a kind is set, allow that to influence the configuration
|
||||
context.addFilter(ctx, "kind", ctx.kind)
|
||||
|
||||
-- if a sharedlibtype is set, allow that to influence the configuration
|
||||
context.addFilter(ctx, "sharedlibtype", ctx.sharedlibtype)
|
||||
|
||||
-- if tags are set, allow that to influence the configuration
|
||||
context.addFilter(ctx, "tags", ctx.tags)
|
||||
|
||||
-- if any extra filters were specified, can include them now
|
||||
if extraFilters then
|
||||
for k, v in pairs(extraFilters) do
|
||||
context.addFilter(ctx, k, v)
|
||||
end
|
||||
end
|
||||
|
||||
context.compile(ctx)
|
||||
|
||||
ctx.location = ctx.location or prj and prj.location
|
||||
context.basedir(ctx, ctx.location)
|
||||
|
||||
-- Fill in a few calculated for the configuration, including the long
|
||||
-- and short names and the build and link target.
|
||||
|
||||
oven.finishConfig(ctx)
|
||||
return ctx
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Create configuration objects for each file contained in the project. This
|
||||
-- collects and collates all of the values specified in the project scripts,
|
||||
-- and computes extra values like the relative path and object names.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project object being baked. The project
|
||||
-- @return
|
||||
-- A collection of file configurations, keyed by both the absolute file
|
||||
-- path and an alpha-sorted index.
|
||||
--
|
||||
|
||||
function oven.bakeFiles(prj)
|
||||
|
||||
local files = {}
|
||||
|
||||
-- Start by building a comprehensive list of all the files contained by the
|
||||
-- project. Some files may only be included in a subset of configurations so
|
||||
-- I need to look at them all.
|
||||
|
||||
for cfg in p.project.eachconfig(prj) do
|
||||
local function addFile(fname, i)
|
||||
|
||||
-- If this is the first time I've seen this file, start a new
|
||||
-- file configuration for it. Track both by key for quick lookups
|
||||
-- and indexed for ordered iteration.
|
||||
local fcfg = files[fname]
|
||||
if not fcfg then
|
||||
fcfg = p.fileconfig.new(fname, prj)
|
||||
fcfg.order = i
|
||||
files[fname] = fcfg
|
||||
table.insert(files, fcfg)
|
||||
end
|
||||
|
||||
p.fileconfig.addconfig(fcfg, cfg)
|
||||
end
|
||||
|
||||
table.foreachi(cfg.files, addFile)
|
||||
|
||||
-- If this project uses NuGet, we need to add the generated
|
||||
-- packages.config file to the project. Is there a better place to
|
||||
-- do this?
|
||||
|
||||
if #prj.nuget > 0 and (_ACTION < "vs2017" or p.project.iscpp(prj)) then
|
||||
addFile("packages.config")
|
||||
end
|
||||
end
|
||||
|
||||
-- Alpha sort the indices, so I will get consistent results in
|
||||
-- the exported project files.
|
||||
|
||||
table.sort(files, function(a,b)
|
||||
return a.vpath < b.vpath
|
||||
end)
|
||||
|
||||
return files
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Assign unique sequence numbers to any source code files that would generate
|
||||
-- conflicting object file names (i.e. src/hello.cpp and tests/hello.cpp both
|
||||
-- create hello.o).
|
||||
--
|
||||
-- a file list of: src/hello.cpp, tests/hello.cpp and src/hello1.cpp also generates
|
||||
-- conflicting object file names - hello1.o
|
||||
|
||||
function oven.uniqueSequence(f, cfg, seq, bases)
|
||||
while true do
|
||||
f.sequence = seq[cfg] or 0
|
||||
seq[cfg] = f.sequence + 1
|
||||
|
||||
if f.sequence == 0 then
|
||||
-- first time seeing this objname
|
||||
break
|
||||
end
|
||||
|
||||
-- getting here has changed our sequence number, but this new "basename"
|
||||
-- may still collide with files that actually end with this "sequence number"
|
||||
-- so we have to check the bases table now
|
||||
|
||||
-- objname changes with the sequence number on every loop
|
||||
local lowerobj = f.objname:lower()
|
||||
if not bases[lowerobj] then
|
||||
-- this is the first appearance of a file that produces this objname
|
||||
-- intialize the table for any future basename that matches our objname
|
||||
bases[lowerobj] = {}
|
||||
end
|
||||
|
||||
if not bases[lowerobj][cfg] then
|
||||
-- not a collision
|
||||
-- start a sequence for a future basename that matches our objname for this cfg
|
||||
bases[lowerobj][cfg] = 1
|
||||
break
|
||||
end
|
||||
-- else we have a objname collision, try the next sequence number
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function oven.assignObjectSequences(prj)
|
||||
|
||||
-- Iterate over the file configurations which were prepared and cached in
|
||||
-- project.bakeFiles(); find buildable files with common base file names.
|
||||
|
||||
local bases = {}
|
||||
table.foreachi(prj._.files, function(file)
|
||||
|
||||
-- Only consider sources that actually generate object files
|
||||
|
||||
if not path.isnativefile(file.abspath) then
|
||||
return
|
||||
end
|
||||
|
||||
-- For each base file name encountered, keep a count of the number of
|
||||
-- collisions that have occurred for each project configuration. Use
|
||||
-- this collision count to generate the unique object file names.
|
||||
|
||||
local lowerbase = file.basename:lower()
|
||||
if not bases[lowerbase] then
|
||||
bases[lowerbase] = {}
|
||||
end
|
||||
|
||||
local sequences = bases[lowerbase]
|
||||
|
||||
for cfg in p.project.eachconfig(prj) do
|
||||
local fcfg = p.fileconfig.getconfig(file, cfg)
|
||||
if fcfg ~= nil and not fcfg.flags.ExcludeFromBuild then
|
||||
oven.uniqueSequence(fcfg, cfg, sequences, bases)
|
||||
end
|
||||
end
|
||||
|
||||
-- Makefiles don't use per-configuration object names yet; keep
|
||||
-- this around until they do. At which point I might consider just
|
||||
-- storing the sequence number instead of the whole object name
|
||||
|
||||
oven.uniqueSequence(file, prj, sequences, bases)
|
||||
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Finish the baking process for a workspace or project level configurations.
|
||||
-- Doesn't bake per se, just fills in some calculated values.
|
||||
--
|
||||
|
||||
function oven.finishConfig(cfg)
|
||||
-- assign human-readable names
|
||||
cfg.longname = table.concat({ cfg.buildcfg, cfg.platform }, "|")
|
||||
cfg.shortname = table.concat({ cfg.buildcfg, cfg.platform }, " ")
|
||||
cfg.shortname = cfg.shortname:gsub(" ", "_"):lower()
|
||||
cfg.name = cfg.longname
|
||||
|
||||
-- compute build and link targets
|
||||
if cfg.project and cfg.kind then
|
||||
cfg.buildtarget = p.config.gettargetinfo(cfg)
|
||||
cfg.buildtarget.relpath = p.project.getrelative(cfg.project, cfg.buildtarget.abspath)
|
||||
|
||||
cfg.linktarget = p.config.getlinkinfo(cfg)
|
||||
cfg.linktarget.relpath = p.project.getrelative(cfg.project, cfg.linktarget.abspath)
|
||||
end
|
||||
end
|
||||
304
Src/external_dependencies/openmpt-trunk/include/premake/src/base/path.lua
vendored
Normal file
304
Src/external_dependencies/openmpt-trunk/include/premake/src/base/path.lua
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
--
|
||||
-- path.lua
|
||||
-- Path manipulation functions.
|
||||
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
--
|
||||
-- Appends a file extension to the path. Verifies that the extension
|
||||
-- isn't already present, and adjusts quotes as necessary.
|
||||
--
|
||||
|
||||
function path.appendExtension(p, ext)
|
||||
-- if the extension is nil or empty, do nothing
|
||||
if not ext or ext == "" then
|
||||
return p
|
||||
end
|
||||
|
||||
-- if the path ends with a quote, pull it off
|
||||
local endquote
|
||||
if p:endswith('"') then
|
||||
p = p:sub(1, -2)
|
||||
endquote = '"'
|
||||
end
|
||||
|
||||
-- add the extension if it isn't there already
|
||||
if not path.hasextension(p, ext) then
|
||||
p = p .. ext
|
||||
end
|
||||
|
||||
-- put the quote back if necessary
|
||||
if endquote then
|
||||
p = p .. endquote
|
||||
end
|
||||
|
||||
return p
|
||||
end
|
||||
|
||||
path.appendextension = path.appendExtension
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the filename portion of a path, without any extension.
|
||||
--
|
||||
|
||||
function path.getbasename(p)
|
||||
local name = path.getname(p)
|
||||
local i = name:findlast(".", true)
|
||||
if (i) then
|
||||
return name:sub(1, i - 1)
|
||||
else
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the directory portion of a path, or an empty string if
|
||||
-- the path does not include a directory.
|
||||
--
|
||||
|
||||
function path.getdirectory(p)
|
||||
local i = p:findlast("/", true)
|
||||
if (i) then
|
||||
if i > 1 then i = i - 1 end
|
||||
return p:sub(1, i)
|
||||
else
|
||||
return "."
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the drive letter, if a Windows path.
|
||||
--
|
||||
|
||||
function path.getdrive(p)
|
||||
local ch1 = p:sub(1,1)
|
||||
local ch2 = p:sub(2,2)
|
||||
if ch2 == ":" then
|
||||
return ch1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the file extension.
|
||||
--
|
||||
|
||||
function path.getextension(p)
|
||||
p = path.getname(p)
|
||||
local i = p:findlast(".", true)
|
||||
if (i) then
|
||||
return p:sub(i)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Remove extension from path.
|
||||
--
|
||||
|
||||
function path.removeextension(p)
|
||||
local i = p:findlast(".", true)
|
||||
if (i) then
|
||||
if i > 1 then i = i - 1 end
|
||||
return p:sub(1, i)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the filename portion of a path.
|
||||
--
|
||||
|
||||
function path.getname(p)
|
||||
local i = p:findlast("[/\\]")
|
||||
if (i) then
|
||||
return p:sub(i + 1)
|
||||
else
|
||||
return p
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename has a particular extension.
|
||||
--
|
||||
-- @param fname
|
||||
-- The file name to test.
|
||||
-- @param extensions
|
||||
-- The extension(s) to test. Maybe be a string or table.
|
||||
--
|
||||
|
||||
function path.hasextension(fname, extensions)
|
||||
local fext = path.getextension(fname):lower()
|
||||
if type(extensions) == "table" then
|
||||
for _, extension in pairs(extensions) do
|
||||
if fext == extension then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
else
|
||||
return (fext == extensions)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents various source languages.
|
||||
--
|
||||
|
||||
function path.isasmfile(fname)
|
||||
return path.hasextension(fname, { ".s" })
|
||||
end
|
||||
|
||||
function path.iscfile(fname)
|
||||
return path.hasextension(fname, { ".c" })
|
||||
or path.isasmfile(fname) -- is this really right?
|
||||
or path.isobjcfile(fname) -- there is code that depends on this behaviour, which would need to change
|
||||
end
|
||||
|
||||
function path.iscppfile(fname)
|
||||
return path.hasextension(fname, { ".cc", ".cpp", ".cxx", ".c++" })
|
||||
or path.isobjcppfile(fname) -- is this really right?
|
||||
or path.iscfile(fname)
|
||||
end
|
||||
|
||||
function path.isobjcfile(fname)
|
||||
return path.hasextension(fname, { ".m" })
|
||||
end
|
||||
|
||||
function path.isobjcppfile(fname)
|
||||
return path.hasextension(fname, { ".mm" })
|
||||
end
|
||||
|
||||
function path.iscppheader(fname)
|
||||
return path.hasextension(fname, { ".h", ".hh", ".hpp", ".hxx" })
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents a native language source file.
|
||||
-- These checks are used to prevent passing non-code files to the compiler
|
||||
-- in makefiles. It is not foolproof, but it has held up well. I'm open to
|
||||
-- better suggestions.
|
||||
--
|
||||
|
||||
function path.isnativefile(fname)
|
||||
return path.iscfile(fname)
|
||||
or path.iscppfile(fname)
|
||||
or path.isasmfile(fname)
|
||||
or path.isobjcfile(fname)
|
||||
or path.isobjcppfile(fname)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents an OS X framework.
|
||||
--
|
||||
|
||||
function path.isframework(fname)
|
||||
return path.hasextension(fname, ".framework")
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Is this a type of file that can be linked?
|
||||
---
|
||||
|
||||
function path.islinkable(fname)
|
||||
return path.hasextension(fname, { ".o", ".obj", ".a", ".lib", ".so" })
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents an object file.
|
||||
--
|
||||
|
||||
function path.isobjectfile(fname)
|
||||
return path.hasextension(fname, { ".o", ".obj" })
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents a Windows resource file. This check
|
||||
-- is used to prevent passing non-resources to the compiler in makefiles.
|
||||
--
|
||||
|
||||
function path.isresourcefile(fname)
|
||||
return path.hasextension(fname, ".rc")
|
||||
end
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents a Windows idl file.
|
||||
--
|
||||
|
||||
function path.isidlfile(fname)
|
||||
return path.hasextension(fname, ".idl")
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents a hlsl shader file.
|
||||
--
|
||||
|
||||
function path.ishlslfile(fname)
|
||||
return path.hasextension(fname, ".hlsl")
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Takes a path which is relative to one location and makes it relative
|
||||
-- to another location instead.
|
||||
--
|
||||
|
||||
function path.rebase(p, oldbase, newbase)
|
||||
p = path.getabsolute(path.join(oldbase, p))
|
||||
p = path.getrelative(newbase, p)
|
||||
return p
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Replace the file extension.
|
||||
--
|
||||
|
||||
function path.replaceextension(p, newext)
|
||||
local ext = path.getextension(p)
|
||||
|
||||
if not ext then
|
||||
return p
|
||||
end
|
||||
|
||||
if #newext > 0 and not newext:findlast(".", true) then
|
||||
newext = "."..newext
|
||||
end
|
||||
|
||||
return p:match("^(.*)"..ext.."$")..newext
|
||||
end
|
||||
|
||||
--
|
||||
-- Get the default seperator for path.translate
|
||||
--
|
||||
|
||||
function path.getDefaultSeparator()
|
||||
if os.istarget('windows') then
|
||||
return '\\'
|
||||
else
|
||||
return '/'
|
||||
end
|
||||
end
|
||||
432
Src/external_dependencies/openmpt-trunk/include/premake/src/base/premake.lua
vendored
Normal file
432
Src/external_dependencies/openmpt-trunk/include/premake/src/base/premake.lua
vendored
Normal file
@@ -0,0 +1,432 @@
|
||||
--
|
||||
-- premake.lua
|
||||
-- High-level helper functions for the project exporters.
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
|
||||
|
||||
|
||||
-- Store captured output text for later testing
|
||||
|
||||
local _captured
|
||||
|
||||
-- The string escaping function.
|
||||
|
||||
local _esc = function(v) return v end
|
||||
|
||||
-- The output settings and defaults
|
||||
|
||||
local _eol = "\n"
|
||||
local _indentString = "\t"
|
||||
local _indentLevel = 0
|
||||
|
||||
-- Set up the global configuration scope. There can be only one.
|
||||
|
||||
global("root")
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Capture and store everything sent through the output stream functions
|
||||
-- premake.w(), premake.x(), and premake.out(). Retrieve the captured
|
||||
-- text using the premake.captured() function.
|
||||
--
|
||||
-- @param fn
|
||||
-- A function to execute. Any output calls made during the execution
|
||||
-- of the function will be captured.
|
||||
-- @return
|
||||
-- The captured output.
|
||||
---
|
||||
|
||||
function premake.capture(fn)
|
||||
-- start a new capture without forgetting the old one
|
||||
local old = _captured
|
||||
_captured = buffered.new()
|
||||
|
||||
-- capture
|
||||
fn()
|
||||
|
||||
-- build the result
|
||||
local captured = p.captured()
|
||||
|
||||
-- free the capture buffer.
|
||||
buffered.close(_captured)
|
||||
|
||||
-- restore the old capture and done
|
||||
_captured = old
|
||||
return captured
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns the captured text and stops capturing.
|
||||
--
|
||||
|
||||
function premake.captured()
|
||||
if _captured then
|
||||
return buffered.tostring(_captured)
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Set the output stream end-of-line sequence.
|
||||
--
|
||||
-- @param s
|
||||
-- The string to use to mark line ends, or nil to keep the existing
|
||||
-- EOL sequence.
|
||||
-- @return
|
||||
-- The new EOL sequence.
|
||||
---
|
||||
|
||||
function premake.eol(s)
|
||||
_eol = s or _eol
|
||||
return _eol
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Handle escaping of strings for various outputs.
|
||||
--
|
||||
-- @param value
|
||||
-- If this is a string: escape it and return the new value. If it is an
|
||||
-- array, return a new array of escaped values.
|
||||
-- @return
|
||||
-- If the input was a single string, returns the escaped version. If it
|
||||
-- was an array, returns an corresponding array of escaped strings.
|
||||
---
|
||||
|
||||
function premake.esc(value)
|
||||
if type(value) == "table" then
|
||||
local result = {}
|
||||
local n = #value
|
||||
for i = 1, n do
|
||||
table.insert(result, p.esc(value[i]))
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
return _esc(value or "")
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Set a new string escaping function.
|
||||
--
|
||||
-- @param func
|
||||
-- The new escaping function, which should take a single string argument
|
||||
-- and return the escaped version of that string. If nil, uses a default
|
||||
-- no-op function.
|
||||
---
|
||||
|
||||
function premake.escaper(func)
|
||||
_esc = func
|
||||
if not _esc then
|
||||
_esc = function (value) return value end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns a boolean if the file was modified
|
||||
-- Open a file for output, and call a function to actually do the writing.
|
||||
-- Used by the actions to generate workspace and project files.
|
||||
--
|
||||
-- @param obj
|
||||
-- A workspace or project object; will be passed to the callback function.
|
||||
-- @param ext
|
||||
-- An optional extension for the generated file, with the leading dot.
|
||||
-- @param callback
|
||||
-- The function responsible for writing the file, should take a workspace
|
||||
-- or project as a parameters.
|
||||
--
|
||||
|
||||
function premake.generate(obj, ext, callback)
|
||||
local output = p.capture(function ()
|
||||
_indentLevel = 0
|
||||
callback(obj)
|
||||
_indentLevel = 0
|
||||
end)
|
||||
|
||||
local fn = p.filename(obj, ext)
|
||||
|
||||
-- make sure output folder exists.
|
||||
local dir = path.getdirectory(fn)
|
||||
local ok, err = os.mkdir(dir)
|
||||
if not ok then
|
||||
error(err, 0)
|
||||
end
|
||||
|
||||
local f, err = os.writefile_ifnotequal(output, fn);
|
||||
|
||||
if (f == 0) then
|
||||
return false -- file not modified
|
||||
elseif (f < 0) then
|
||||
error(err, 0)
|
||||
elseif (f > 0) then
|
||||
printf("Generated %s...", path.getrelative(os.getcwd(), fn))
|
||||
return true -- file modified
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Marks a file as modified without changing its contents
|
||||
--
|
||||
-- @param obj
|
||||
-- A workspace or project object; will be passed to the callback function.
|
||||
-- @param ext
|
||||
-- An optional extension for the generated file, with the leading dot.
|
||||
--
|
||||
|
||||
function premake.touch(obj, ext)
|
||||
local fn = premake.filename(obj, ext)
|
||||
|
||||
-- make sure output folder exists.
|
||||
local dir = path.getdirectory(fn)
|
||||
local ok, err = os.mkdir(dir)
|
||||
if not ok then
|
||||
error(err, 0)
|
||||
end
|
||||
|
||||
local f, err = os.touchfile(fn);
|
||||
|
||||
if (f == 0) then
|
||||
return false -- file marked as modified
|
||||
elseif (f < 0) then
|
||||
error(err, 0)
|
||||
elseif (f > 0) then
|
||||
return true -- file created
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Returns the full path a file generated from any of the project
|
||||
-- objects (project, workspace, rule).
|
||||
--
|
||||
-- @param obj
|
||||
-- The project object being generated.
|
||||
-- @param ext
|
||||
-- An optional extension for the generated file, with the leading dot.
|
||||
---
|
||||
|
||||
function premake.filename(obj, ext)
|
||||
local fname = obj.location or obj.basedir
|
||||
if ext and not ext:startswith(".") then
|
||||
fname = path.join(fname, ext)
|
||||
else
|
||||
fname = path.join(fname, obj.filename)
|
||||
if ext then
|
||||
fname = fname .. ext
|
||||
end
|
||||
end
|
||||
return path.getabsolute(fname)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Sets the output indentation parameters.
|
||||
--
|
||||
-- @param s
|
||||
-- The indentation string.
|
||||
-- @param i
|
||||
-- The new indentation level, or nil to reset to zero.
|
||||
---
|
||||
|
||||
function premake.indent(s, i)
|
||||
_indentString = s or "\t"
|
||||
_indentLevel = i or 0
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a simple, unformatted string to the output stream, with no indentation
|
||||
-- or end of line sequence.
|
||||
---
|
||||
|
||||
function premake.out(s)
|
||||
if not _captured then
|
||||
io.write(s)
|
||||
else
|
||||
buffered.write(_captured, s)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a simple, unformatted string to the output stream, with no indentation,
|
||||
-- and append the current EOL sequence.
|
||||
---
|
||||
|
||||
function premake.outln(s)
|
||||
p.out(s)
|
||||
p.out(_eol or "\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a formatted string to the exported file, after decreasing the
|
||||
-- indentation level by one.
|
||||
--
|
||||
-- @param i
|
||||
-- If set to a number, the indentation level will be decreased by
|
||||
-- this amount. If nil, the indentation level is decremented and
|
||||
-- no output is written. Otherwise, pass to premake.w() as the
|
||||
-- formatting string, followed by any additional arguments.
|
||||
---
|
||||
|
||||
function premake.pop(i, ...)
|
||||
if i == nil or type(i) == "number" then
|
||||
_indentLevel = _indentLevel - (i or 1)
|
||||
else
|
||||
_indentLevel = _indentLevel - 1
|
||||
p.w(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a formatted string to the exported file, and increase the
|
||||
-- indentation level by one.
|
||||
--
|
||||
-- @param i
|
||||
-- If set to a number, the indentation level will be increased by
|
||||
-- this amount. If nil, the indentation level is incremented and
|
||||
-- no output is written. Otherwise, pass to premake.w() as the
|
||||
-- formatting string, followed by any additional arguments.
|
||||
---
|
||||
|
||||
function premake.push(i, ...)
|
||||
if i == nil or type(i) == "number" then
|
||||
_indentLevel = _indentLevel + (i or 1)
|
||||
else
|
||||
p.w(i, ...)
|
||||
_indentLevel = _indentLevel + 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Wrap the provided value in double quotes if it contains spaces, or
|
||||
-- if it contains a shell variable of the form $(...).
|
||||
---
|
||||
|
||||
function premake.quoted(value)
|
||||
local q = value:find(" ", 1, true)
|
||||
if not q then
|
||||
q = value:find("$%(.-%)", 1)
|
||||
end
|
||||
if q then
|
||||
value = '"' .. value .. '"'
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Output a UTF-8 BOM to the exported file.
|
||||
--
|
||||
|
||||
function p.utf8()
|
||||
p.out('\239\187\191')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a formatted string to the exported file, at the current
|
||||
-- level of indentation, and appends an end of line sequence.
|
||||
-- This gets called quite a lot, hence the very short name.
|
||||
---
|
||||
|
||||
function premake.w(...)
|
||||
if select("#", ...) > 0 then
|
||||
p.outln(string.rep(_indentString or "\t", _indentLevel) .. string.format(...))
|
||||
else
|
||||
p.outln('');
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a formatted string to the exported file, after passing all
|
||||
-- arguments (except for the first, which is the formatting string)
|
||||
-- through premake.esc().
|
||||
---
|
||||
|
||||
function premake.x(msg, ...)
|
||||
local arg = {...}
|
||||
for i = 1, #arg do
|
||||
arg[i] = p.esc(arg[i])
|
||||
end
|
||||
p.w(msg, table.unpack(arg))
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a opening XML element for a UTF-8 encoded file. Used by
|
||||
-- several different files for different actions, so makes sense
|
||||
-- to have a common call for it.
|
||||
--
|
||||
-- @param upper
|
||||
-- If true, the encoding is written in uppercase.
|
||||
---
|
||||
|
||||
function premake.xmlUtf8(upper)
|
||||
local encoding = iif(upper, "UTF-8", "utf-8")
|
||||
p.w('<?xml version="1.0" encoding="%s"?>', encoding)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- These are the output shortcuts that I used before switching to the
|
||||
-- indentation-aware calls above. They are still in use all over the
|
||||
-- place, including lots of community code, so let's keep them around.
|
||||
--
|
||||
-- @param i
|
||||
-- This will either be a printf-style formatting string suitable
|
||||
-- for passing to string.format(), OR an integer number indicating
|
||||
-- the desired level of indentation. If the latter, the formatting
|
||||
-- string should be the next argument in the list.
|
||||
-- @param ...
|
||||
-- The values necessary to fill out the formatting string tokens.
|
||||
--
|
||||
|
||||
function _p(i, ...)
|
||||
if type(i) == "number" then
|
||||
_indentLevel = i
|
||||
p.w(...)
|
||||
else
|
||||
_indentLevel = 0
|
||||
p.w(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
function _x(i, ...)
|
||||
local arg = {...}
|
||||
for i = 2, #arg do
|
||||
arg[i] = p.esc(arg[i])
|
||||
end
|
||||
_p(i, table.unpack(arg))
|
||||
end
|
||||
563
Src/external_dependencies/openmpt-trunk/include/premake/src/base/project.lua
vendored
Normal file
563
Src/external_dependencies/openmpt-trunk/include/premake/src/base/project.lua
vendored
Normal file
@@ -0,0 +1,563 @@
|
||||
---
|
||||
-- project.lua
|
||||
-- Premake project object API
|
||||
-- Author Jason Perkins
|
||||
-- Copyright (c) 2011-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.project = p.api.container("project", p.workspace, { "config" })
|
||||
|
||||
local project = p.project
|
||||
local tree = p.tree
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Alias the old external() call to the new externalproject(), to distinguish
|
||||
-- between it and externalrule().
|
||||
---
|
||||
|
||||
external = externalproject
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new project container instance.
|
||||
---
|
||||
|
||||
function project.new(name)
|
||||
local prj = p.container.new(project, name)
|
||||
prj.uuid = os.uuid(name)
|
||||
|
||||
if p.api.scope.group then
|
||||
prj.group = p.api.scope.group.name
|
||||
else
|
||||
prj.group = ""
|
||||
end
|
||||
|
||||
return prj
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns an iterator function for the configuration objects contained by
|
||||
-- the project. Each configuration corresponds to a build configuration/
|
||||
-- platform pair (i.e. "Debug|x86") as specified in the workspace.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project object to query.
|
||||
-- @return
|
||||
-- An iterator function returning configuration objects.
|
||||
--
|
||||
|
||||
function project.eachconfig(prj)
|
||||
local configs = prj._cfglist
|
||||
local count = #configs
|
||||
|
||||
-- Once the configurations are mapped into the workspace I could get
|
||||
-- the same one multiple times. Make sure that doesn't happen.
|
||||
local seen = {}
|
||||
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= count then
|
||||
local cfg = project.getconfig(prj, configs[i][1], configs[i][2])
|
||||
if not seen[cfg] then
|
||||
seen[cfg] = true
|
||||
return cfg
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- When an exact match is not available (project.getconfig() returns nil), use
|
||||
-- this function to find the closest alternative.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project object to query.
|
||||
-- @param buildcfg
|
||||
-- The name of the build configuration on which to filter.
|
||||
-- @param platform
|
||||
-- Optional; the name of the platform on which to filter.
|
||||
-- @return
|
||||
-- A configuration object.
|
||||
--
|
||||
|
||||
function project.findClosestMatch(prj, buildcfg, platform)
|
||||
|
||||
-- One or both of buildcfg and platform do not match any of the project
|
||||
-- configurations, otherwise I would have had an exact match. Map them
|
||||
-- separately to apply any partial rules.
|
||||
|
||||
buildcfg = project.mapconfig(prj, buildcfg)[1]
|
||||
platform = project.mapconfig(prj, platform)[1]
|
||||
|
||||
-- Replace missing values with whatever is first in the list
|
||||
|
||||
if not table.contains(prj.configurations, buildcfg) then
|
||||
buildcfg = prj.configurations[1]
|
||||
end
|
||||
|
||||
if not table.contains(prj.platforms, platform) then
|
||||
platform = prj.platforms[1]
|
||||
end
|
||||
|
||||
-- Now I should have a workable pairing
|
||||
|
||||
return project.getconfig(prj, buildcfg, platform)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Retrieve the project's configuration information for a particular build
|
||||
-- configuration/platform pair.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project object to query.
|
||||
-- @param buildcfg
|
||||
-- The name of the build configuration on which to filter.
|
||||
-- @param platform
|
||||
-- Optional; the name of the platform on which to filter.
|
||||
-- @return
|
||||
-- A configuration object.
|
||||
|
||||
function project.getconfig(prj, buildcfg, platform)
|
||||
-- if no build configuration is specified, return the "root" project
|
||||
-- configurations, which includes all configuration values that
|
||||
-- weren't set with a specific configuration filter
|
||||
if not buildcfg then
|
||||
return prj
|
||||
end
|
||||
|
||||
-- apply any configuration mappings
|
||||
local pairing = project.mapconfig(prj, buildcfg, platform)
|
||||
buildcfg = pairing[1]
|
||||
platform = pairing[2]
|
||||
|
||||
-- look up and return the associated config
|
||||
local key = (buildcfg or "*") .. (platform or "")
|
||||
return prj.configs[key]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Returns a list of sibling projects on which the specified project depends.
|
||||
-- This is used to list dependencies within a workspace. Must consider all
|
||||
-- configurations because Visual Studio does not support per-config project
|
||||
-- dependencies.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project to query.
|
||||
-- @param mode
|
||||
-- if mode == 'linkOnly', returns only siblings which are linked against (links) and skips siblings which are not (dependson).
|
||||
-- if mode == 'dependOnly' returns only siblings which are depended on (dependson) and skips siblings which are not (links).
|
||||
-- @return
|
||||
-- A list of dependent projects, as an array of project objects.
|
||||
---
|
||||
|
||||
function project.getdependencies(prj, mode)
|
||||
if not prj.dependencies then
|
||||
prj.dependencies = {}
|
||||
end
|
||||
|
||||
local m = mode or 'all'
|
||||
local result = prj.dependencies[m]
|
||||
if result then
|
||||
return result
|
||||
end
|
||||
|
||||
local function add_to_project_list(cfg, depproj, result)
|
||||
local dep = p.workspace.findproject(cfg.workspace, depproj)
|
||||
if dep and not table.contains(result, dep) then
|
||||
table.insert(result, dep)
|
||||
end
|
||||
end
|
||||
|
||||
local linkOnly = m == 'linkOnly'
|
||||
local depsOnly = m == 'dependOnly'
|
||||
|
||||
result = {}
|
||||
for cfg in project.eachconfig(prj) do
|
||||
if not depsOnly then
|
||||
for _, link in ipairs(cfg.links) do
|
||||
if link ~= prj.name then
|
||||
add_to_project_list(cfg, link, result)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not linkOnly then
|
||||
for _, depproj in ipairs(cfg.dependson) do
|
||||
add_to_project_list(cfg, depproj, result)
|
||||
end
|
||||
end
|
||||
end
|
||||
prj.dependencies[m] = result
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Return the first configuration of a project, which is used in some
|
||||
-- actions to generate project-wide defaults.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project object to query.
|
||||
-- @return
|
||||
-- The first configuration in a project, as would be returned by
|
||||
-- eachconfig().
|
||||
--
|
||||
|
||||
function project.getfirstconfig(prj)
|
||||
local iter = project.eachconfig(prj)
|
||||
local first = iter()
|
||||
return first
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Return the relative path from the project to the specified file.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project object to query.
|
||||
-- @param filename
|
||||
-- The file path, or an array of file paths, to convert.
|
||||
-- @return
|
||||
-- The relative path, or array of paths, from the project to the file.
|
||||
--
|
||||
|
||||
function project.getrelative(prj, filename)
|
||||
if type(filename) == "table" then
|
||||
local result = {}
|
||||
for i, name in ipairs(filename) do
|
||||
result[i] = project.getrelative(prj, name)
|
||||
end
|
||||
return result
|
||||
else
|
||||
if filename then
|
||||
local result = filename
|
||||
if path.hasdeferredjoin(result) then
|
||||
result = path.resolvedeferredjoin(result)
|
||||
end
|
||||
return path.getrelative(prj.location, result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Create a tree from a project's list of source files.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project to query.
|
||||
-- @param sorter
|
||||
-- An optional comparator function for the sorting pass.
|
||||
-- @return
|
||||
-- A tree object containing the source file hierarchy. Leaf nodes,
|
||||
-- representing the individual files, are file configuration
|
||||
-- objects.
|
||||
--
|
||||
|
||||
function project.getsourcetree(prj, sorter)
|
||||
|
||||
if prj._.sourcetree then
|
||||
return prj._.sourcetree
|
||||
end
|
||||
|
||||
local tr = tree.new(prj.name)
|
||||
|
||||
table.foreachi(prj._.files, function(fcfg)
|
||||
-- if the file is a generated file, we add those in a second pass.
|
||||
if fcfg.generated then
|
||||
return;
|
||||
end
|
||||
|
||||
-- The tree represents the logical source code tree to be displayed
|
||||
-- in the IDE, not the physical organization of the file system. So
|
||||
-- virtual paths are used when adding nodes.
|
||||
|
||||
-- If the project script specifies a virtual path for a file, disable
|
||||
-- the logic that could trim out empty root nodes from that path. If
|
||||
-- the script writer wants an empty root node they should get it.
|
||||
|
||||
local flags
|
||||
if fcfg.vpath ~= fcfg.relpath then
|
||||
flags = { trim = false }
|
||||
end
|
||||
|
||||
-- Virtual paths can overlap, potentially putting files with the same
|
||||
-- name in the same folder, even though they have different paths on
|
||||
-- the underlying filesystem. The tree.add() call won't overwrite
|
||||
-- existing nodes, so provide the extra logic here. Start by getting
|
||||
-- the parent folder node, creating it if necessary.
|
||||
|
||||
local parent = tree.add(tr, path.getdirectory(fcfg.vpath), flags)
|
||||
local node = tree.insert(parent, tree.new(path.getname(fcfg.vpath)))
|
||||
|
||||
-- Pass through value fetches to the file configuration
|
||||
setmetatable(node, { __index = fcfg })
|
||||
end)
|
||||
|
||||
|
||||
table.foreachi(prj._.files, function(fcfg)
|
||||
-- if the file is not a generated file, we already added them
|
||||
if not fcfg.generated then
|
||||
return;
|
||||
end
|
||||
|
||||
local parent = tree.add(tr, path.getdirectory(fcfg.dependsOn.vpath))
|
||||
local node = tree.insert(parent, tree.new(path.getname(fcfg.vpath)))
|
||||
|
||||
-- Pass through value fetches to the file configuration
|
||||
setmetatable(node, { __index = fcfg })
|
||||
end)
|
||||
|
||||
tree.trimroot(tr)
|
||||
tree.sort(tr, sorter)
|
||||
|
||||
prj._.sourcetree = tr
|
||||
return tr
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Given a source file path, return a corresponding virtual path based on
|
||||
-- the vpath entries in the project. If no matching vpath entry is found,
|
||||
-- the original path is returned.
|
||||
--
|
||||
|
||||
function project.getvpath(prj, abspath)
|
||||
-- If there is no match, the result is the original filename
|
||||
local vpath = abspath
|
||||
|
||||
-- The file's name must be maintained in the resulting path; use these
|
||||
-- to make sure I don't cut off too much
|
||||
|
||||
local fname = path.getname(abspath)
|
||||
local max = abspath:len() - fname:len()
|
||||
|
||||
-- Look for matching patterns. Virtual paths are stored as an array
|
||||
-- for tables, each table continuing the path key, which looks up the
|
||||
-- array of paths with should match against that path.
|
||||
|
||||
for _, vpaths in ipairs(prj.vpaths) do
|
||||
for replacement, patterns in pairs(vpaths) do
|
||||
for _, pattern in ipairs(patterns) do
|
||||
local i = abspath:find(path.wildcards(pattern))
|
||||
if i == 1 then
|
||||
|
||||
-- Trim out the part of the name that matched the pattern; what's
|
||||
-- left is the part that gets appended to the replacement to make
|
||||
-- the virtual path. So a pattern like "src/**.h" matching the
|
||||
-- file src/include/hello.h, I want to trim out the src/ part,
|
||||
-- leaving include/hello.h.
|
||||
|
||||
-- Find out where the wildcard appears in the match. If there is
|
||||
-- no wildcard, the match includes the entire pattern
|
||||
|
||||
i = pattern:find("*", 1, true) or (pattern:len() + 1)
|
||||
|
||||
-- Trim, taking care to keep the actual file name intact.
|
||||
|
||||
local leaf
|
||||
if i < max then
|
||||
leaf = abspath:sub(i)
|
||||
else
|
||||
leaf = fname
|
||||
end
|
||||
|
||||
if leaf:startswith("/") then
|
||||
leaf = leaf:sub(2)
|
||||
end
|
||||
|
||||
-- check for (and remove) stars in the replacement pattern.
|
||||
-- If there are none, then trim all path info from the leaf
|
||||
-- and use just the filename in the replacement (stars should
|
||||
-- really only appear at the end; I'm cheating here)
|
||||
|
||||
local stem = ""
|
||||
if replacement:len() > 0 then
|
||||
stem, stars = replacement:gsub("%*", "")
|
||||
if stars == 0 then
|
||||
leaf = path.getname(leaf)
|
||||
end
|
||||
else
|
||||
leaf = path.getname(leaf)
|
||||
end
|
||||
|
||||
vpath = path.join(stem, leaf)
|
||||
return vpath
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return vpath
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determines if project contains a configuration meeting certain criteria.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project to query.
|
||||
-- @param func
|
||||
-- A test function. Takes a project configuration as an argument and
|
||||
-- returns a boolean result of the test.
|
||||
-- @return
|
||||
-- True if the test function returned true.
|
||||
--
|
||||
|
||||
function project.hasConfig(prj, func)
|
||||
for cfg in project.eachconfig(prj) do
|
||||
if func(cfg) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determines if a project contains a particular source code file.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project to query.
|
||||
-- @param filename
|
||||
-- The absolute path to the source code file being checked.
|
||||
-- @return
|
||||
-- True if the file belongs to the project, in any configuration.
|
||||
--
|
||||
|
||||
function project.hasfile(prj, filename)
|
||||
return (prj._.files[filename] ~= nil)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the project uses a .NET language.
|
||||
--
|
||||
|
||||
function project.isdotnet(prj)
|
||||
return
|
||||
p.languages.iscsharp(prj.language) or
|
||||
p.languages.isfsharp(prj.language)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the project uses a C# language.
|
||||
--
|
||||
|
||||
function project.iscsharp(prj)
|
||||
return p.languages.iscsharp(prj.language)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the project uses a F# language.
|
||||
--
|
||||
|
||||
function project.isfsharp(prj)
|
||||
return p.languages.isfsharp(prj.language)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the project uses a cpp language.
|
||||
--
|
||||
|
||||
function project.isc(prj)
|
||||
return p.languages.isc(prj.language)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the project uses a cpp language.
|
||||
--
|
||||
|
||||
function project.iscpp(prj)
|
||||
return p.languages.iscpp(prj.language)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the project has uses any 'native' languages.
|
||||
-- which is basically anything other then .net at this point.
|
||||
-- modules like the dlang should overload this to add 'project.isd(prj)' to it.
|
||||
--
|
||||
function project.isnative(prj)
|
||||
return project.isc(prj) or project.iscpp(prj)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Given a build config/platform pairing, applies any project configuration maps
|
||||
-- and returns a new (or the same) pairing.
|
||||
--
|
||||
-- TODO: I think this could be made much simpler by building a string pattern
|
||||
-- like :part1:part2: and then doing string comparisions, instead of trying to
|
||||
-- iterate over variable number of table elements.
|
||||
--
|
||||
|
||||
function project.mapconfig(prj, buildcfg, platform)
|
||||
local pairing = { buildcfg, platform }
|
||||
|
||||
local testpattern = function(pattern, pairing, i)
|
||||
local j = 1
|
||||
while i <= #pairing and j <= #pattern do
|
||||
local wd = path.wildcards(pattern[j])
|
||||
if pairing[i]:match(wd) ~= pairing[i] then
|
||||
return false
|
||||
end
|
||||
i = i + 1
|
||||
j = j + 1
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local maps = prj.configmap or {}
|
||||
for mi = 1, #maps do
|
||||
for pattern, replacements in pairs(maps[mi]) do
|
||||
if type(pattern) ~= "table" then
|
||||
pattern = { pattern }
|
||||
end
|
||||
|
||||
-- does this pattern match any part of the pair? If so,
|
||||
-- replace it with the corresponding values
|
||||
for i = 1, #pairing do
|
||||
if testpattern(pattern, pairing, i) then
|
||||
if #pattern == 1 and #replacements == 1 then
|
||||
pairing[i] = replacements[1]
|
||||
else
|
||||
pairing = { replacements[1], replacements[2] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return pairing
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Given a project, returns requested min and max system versions.
|
||||
--
|
||||
|
||||
function project.systemversion(prj)
|
||||
if prj.systemversion ~= nil then
|
||||
local values = string.explode(prj.systemversion, ":", true)
|
||||
return values[1], values[2]
|
||||
end
|
||||
end
|
||||
242
Src/external_dependencies/openmpt-trunk/include/premake/src/base/rule.lua
vendored
Normal file
242
Src/external_dependencies/openmpt-trunk/include/premake/src/base/rule.lua
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
---
|
||||
-- base/rule.lua
|
||||
-- Defines rule sets for generated custom rule files.
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.rule = p.api.container("rule", p.global)
|
||||
|
||||
local rule = p.rule
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new rule container instance.
|
||||
---
|
||||
|
||||
function rule.new(name)
|
||||
local self = p.container.new(rule, name)
|
||||
|
||||
-- create a variable setting function. Do a version with lowercased
|
||||
-- first letter(s) to match Premake's naming style for other calls
|
||||
|
||||
_G[name .. "Vars"] = function(vars)
|
||||
rule.setVars(self, vars)
|
||||
end
|
||||
|
||||
local lowerName = name:gsub("^%u+", string.lower)
|
||||
_G[lowerName .. "Vars"] = _G[name .. "Vars"]
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Enumerate the property definitions for a rule.
|
||||
---
|
||||
|
||||
function rule.eachProperty(self)
|
||||
local props = self.propertydefinition
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= #props then
|
||||
return props[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Find a property definition by its name.
|
||||
--
|
||||
-- @param name
|
||||
-- The property name.
|
||||
-- @returns
|
||||
-- The property definition if found, nil otherwise.
|
||||
---
|
||||
|
||||
function rule.getProperty(self, name)
|
||||
local props = self.propertydefinition
|
||||
for i = 1, #props do
|
||||
local prop = props[i]
|
||||
if prop.name == name then
|
||||
return prop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Find the field definition for one this rule's properties. This field
|
||||
-- can then be used with the api.* functions to manipulate the property's
|
||||
-- values in the current configuration scope.
|
||||
--
|
||||
-- @param prop
|
||||
-- The property definition.
|
||||
-- @return
|
||||
-- The field definition for the property; this will be created if it
|
||||
-- does not already exist.
|
||||
---
|
||||
|
||||
function rule.getPropertyField(self, prop)
|
||||
if prop._field then
|
||||
return prop._field
|
||||
end
|
||||
|
||||
local kind = prop.kind or "string"
|
||||
if kind == "list" then
|
||||
kind = "list:string"
|
||||
end
|
||||
|
||||
local fld = p.field.new {
|
||||
name = "_rule_" .. self.name .. "_" .. prop.name,
|
||||
scope = "config",
|
||||
kind = kind,
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
prop._field = fld
|
||||
return fld
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Set one or more rule variables in the current configuration scope.
|
||||
--
|
||||
-- @param vars
|
||||
-- A key-value list of variables to set and their corresponding values.
|
||||
---
|
||||
|
||||
function rule.setVars(self, vars)
|
||||
for key, value in pairs(vars) do
|
||||
local prop = rule.getProperty(self, key)
|
||||
if not prop then
|
||||
error (string.format("rule '%s' does not have property '%s'", self.name, key))
|
||||
end
|
||||
|
||||
local fld = rule.getPropertyField(self, prop)
|
||||
p.api.storeField(fld, value)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- prepare an environment with the rule properties as global tokens,
|
||||
-- according to the format specified.
|
||||
--
|
||||
-- @param environ
|
||||
-- The environment table to fill up
|
||||
-- @param format
|
||||
-- The formatting to be used, ie "[%s]".
|
||||
---
|
||||
function rule.createEnvironment(self, format)
|
||||
local environ = {}
|
||||
for _, def in ipairs(self.propertydefinition) do
|
||||
environ[def.name] = string.format(format, def.name)
|
||||
end
|
||||
return environ
|
||||
end
|
||||
|
||||
---
|
||||
-- prepare an table of pathVars with the rule properties as global tokens,
|
||||
-- according to the format specified.
|
||||
--
|
||||
-- @param pathVars
|
||||
-- The pathVars table to fill up
|
||||
-- @param format
|
||||
-- The formatting to be used, ie "%%(%s)".
|
||||
---
|
||||
|
||||
function rule.preparePathVars(self, pathVars, format)
|
||||
for _, def in ipairs(self.propertydefinition) do
|
||||
pathVars[def.name] = { absolute = true, token = string.format(format, def.name) }
|
||||
end
|
||||
end
|
||||
|
||||
function rule.createPathVars(self, format)
|
||||
local pathVars = {}
|
||||
rule.preparePathVars(self, pathVars, format)
|
||||
return pathVars
|
||||
end
|
||||
|
||||
function rule.prepareEnvironment(self, environ, cfg)
|
||||
local function path(cfg, value)
|
||||
cfg = cfg.project or cfg
|
||||
local dirs = path.translate(project.getrelative(cfg, value))
|
||||
|
||||
if type(dirs) == 'table' then
|
||||
dirs = table.filterempty(dirs)
|
||||
end
|
||||
|
||||
return dirs
|
||||
end
|
||||
|
||||
local function expandRuleString(prop, value)
|
||||
-- list
|
||||
if type(value) == "table" then
|
||||
if #value > 0 then
|
||||
local switch = prop.switch or ""
|
||||
if prop.separator then
|
||||
return switch .. table.concat(value, prop.separator)
|
||||
else
|
||||
return switch .. table.concat(value, " " .. switch)
|
||||
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
|
||||
|
||||
-- enum
|
||||
if prop.values then
|
||||
local switch = prop.switch or {}
|
||||
value = table.findKeyByValue(prop.values, value)
|
||||
if value == nil then
|
||||
return nil
|
||||
end
|
||||
return switch[value]
|
||||
end
|
||||
|
||||
-- primitive
|
||||
local switch = prop.switch or ""
|
||||
value = tostring(value)
|
||||
if #value > 0 then
|
||||
return switch .. value
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
for _, prop in ipairs(self.propertydefinition) do
|
||||
local fld = p.rule.getPropertyField(self, prop)
|
||||
local value = cfg[fld.name]
|
||||
if value ~= nil then
|
||||
|
||||
if fld.kind == "path" then
|
||||
value = path(cfg, value)
|
||||
elseif fld.kind == "list:path" then
|
||||
value = path(cfg, value)
|
||||
end
|
||||
|
||||
value = expandRuleString(prop, value)
|
||||
if value ~= nil and #value > 0 then
|
||||
environ[prop.name] = p.esc(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
209
Src/external_dependencies/openmpt-trunk/include/premake/src/base/semver.lua
vendored
Normal file
209
Src/external_dependencies/openmpt-trunk/include/premake/src/base/semver.lua
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
local semver = {
|
||||
_VERSION = '1.2.1',
|
||||
_DESCRIPTION = 'semver for Lua',
|
||||
_URL = 'https://github.com/kikito/semver.lua',
|
||||
_LICENSE = [[
|
||||
MIT LICENSE
|
||||
|
||||
Copyright (c) 2015 Enrique García Cota
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of tother software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and tother permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
}
|
||||
|
||||
local function checkPositiveInteger(number, name)
|
||||
assert(number >= 0, name .. ' must be a valid positive number')
|
||||
assert(math.floor(number) == number, name .. ' must be an integer')
|
||||
end
|
||||
|
||||
local function present(value)
|
||||
return value and value ~= ''
|
||||
end
|
||||
|
||||
-- splitByDot("a.bbc.d") == {"a", "bbc", "d"}
|
||||
local function splitByDot(str)
|
||||
str = str or ""
|
||||
local t, count = {}, 0
|
||||
str:gsub("([^%.]+)", function(c)
|
||||
count = count + 1
|
||||
t[count] = c
|
||||
end)
|
||||
return t
|
||||
end
|
||||
|
||||
local function parsePrereleaseAndBuildWithSign(str)
|
||||
local prereleaseWithSign, buildWithSign = str:match("^(-[^+]+)(+.+)$")
|
||||
if not (prereleaseWithSign and buildWithSign) then
|
||||
prereleaseWithSign = str:match("^(-.+)$")
|
||||
buildWithSign = str:match("^(+.+)$")
|
||||
end
|
||||
assert(prereleaseWithSign or buildWithSign, ("The parameter %q must begin with + or - to denote a prerelease or a build"):format(str))
|
||||
return prereleaseWithSign, buildWithSign
|
||||
end
|
||||
|
||||
local function parsePrerelease(prereleaseWithSign)
|
||||
if prereleaseWithSign then
|
||||
local prerelease = prereleaseWithSign:match("^-(%w[%.%w-]*)$")
|
||||
assert(prerelease, ("The prerelease %q is not a slash followed by alphanumerics, dots and slashes"):format(prereleaseWithSign))
|
||||
return prerelease
|
||||
end
|
||||
end
|
||||
|
||||
local function parseBuild(buildWithSign)
|
||||
if buildWithSign then
|
||||
local build = buildWithSign:match("^%+(%w[%.%w-]*)$")
|
||||
assert(build, ("The build %q is not a + sign followed by alphanumerics, dots and slashes"):format(buildWithSign))
|
||||
return build
|
||||
end
|
||||
end
|
||||
|
||||
local function parsePrereleaseAndBuild(str)
|
||||
if not present(str) then return nil, nil end
|
||||
|
||||
local prereleaseWithSign, buildWithSign = parsePrereleaseAndBuildWithSign(str)
|
||||
|
||||
local prerelease = parsePrerelease(prereleaseWithSign)
|
||||
local build = parseBuild(buildWithSign)
|
||||
|
||||
return prerelease, build
|
||||
end
|
||||
|
||||
local function parseVersion(str)
|
||||
local sMajor, sMinor, sPatch, sPrereleaseAndBuild = str:match("^(%d+)%.?(%d*)%.?(%d*)(.-)$")
|
||||
assert(type(sMajor) == 'string', ("Could not extract version number(s) from %q"):format(str))
|
||||
local major, minor, patch = tonumber(sMajor), tonumber(sMinor), tonumber(sPatch)
|
||||
local prerelease, build = parsePrereleaseAndBuild(sPrereleaseAndBuild)
|
||||
return major, minor, patch, prerelease, build
|
||||
end
|
||||
|
||||
|
||||
-- return 0 if a == b, -1 if a < b, and 1 if a > b
|
||||
local function compare(a,b)
|
||||
return a == b and 0 or a < b and -1 or 1
|
||||
end
|
||||
|
||||
local function compareIds(myId, otherId)
|
||||
if myId == otherId then return 0
|
||||
elseif not myId then return -1
|
||||
elseif not otherId then return 1
|
||||
end
|
||||
|
||||
local selfNumber, otherNumber = tonumber(myId), tonumber(otherId)
|
||||
|
||||
if selfNumber and otherNumber then -- numerical comparison
|
||||
return compare(selfNumber, otherNumber)
|
||||
-- numericals are always smaller than alphanums
|
||||
elseif selfNumber then
|
||||
return -1
|
||||
elseif otherNumber then
|
||||
return 1
|
||||
else
|
||||
return compare(myId, otherId) -- alphanumerical comparison
|
||||
end
|
||||
end
|
||||
|
||||
local function smallerIdList(myIds, otherIds)
|
||||
local myLength = #myIds
|
||||
local comparison
|
||||
|
||||
for i=1, myLength do
|
||||
comparison = compareIds(myIds[i], otherIds[i])
|
||||
if comparison ~= 0 then
|
||||
return comparison == -1
|
||||
end
|
||||
-- if comparison == 0, continue loop
|
||||
end
|
||||
|
||||
return myLength < #otherIds
|
||||
end
|
||||
|
||||
local function smallerPrerelease(mine, other)
|
||||
if mine == other or not mine then return false
|
||||
elseif not other then return true
|
||||
end
|
||||
|
||||
return smallerIdList(splitByDot(mine), splitByDot(other))
|
||||
end
|
||||
|
||||
local methods = {}
|
||||
|
||||
function methods:nextMajor()
|
||||
return semver(self.major + 1, 0, 0)
|
||||
end
|
||||
function methods:nextMinor()
|
||||
return semver(self.major, self.minor + 1, 0)
|
||||
end
|
||||
function methods:nextPatch()
|
||||
return semver(self.major, self.minor, self.patch + 1)
|
||||
end
|
||||
|
||||
local mt = { __index = methods }
|
||||
function mt:__eq(other)
|
||||
return self.major == other.major and
|
||||
self.minor == other.minor and
|
||||
self.patch == other.patch and
|
||||
self.prerelease == other.prerelease
|
||||
-- notice that build is ignored for precedence in semver 2.0.0
|
||||
end
|
||||
function mt:__lt(other)
|
||||
if self.major ~= other.major then return self.major < other.major end
|
||||
if self.minor ~= other.minor then return self.minor < other.minor end
|
||||
if self.patch ~= other.patch then return self.patch < other.patch end
|
||||
return smallerPrerelease(self.prerelease, other.prerelease)
|
||||
-- notice that build is ignored for precedence in semver 2.0.0
|
||||
end
|
||||
-- This works like the "pessimisstic operator" in Rubygems.
|
||||
-- if a and b are versions, a ^ b means "b is backwards-compatible with a"
|
||||
-- in other words, "it's safe to upgrade from a to b"
|
||||
function mt:__pow(other)
|
||||
if self.major == 0 then
|
||||
return self == other
|
||||
end
|
||||
return self.major == other.major and
|
||||
self.minor <= other.minor
|
||||
end
|
||||
function mt:__tostring()
|
||||
local buffer = { ("%d.%d.%d"):format(self.major, self.minor, self.patch) }
|
||||
if self.prerelease then table.insert(buffer, "-" .. self.prerelease) end
|
||||
if self.build then table.insert(buffer, "+" .. self.build) end
|
||||
return table.concat(buffer)
|
||||
end
|
||||
|
||||
local function new(major, minor, patch, prerelease, build)
|
||||
assert(major, "At least one parameter is needed")
|
||||
|
||||
if type(major) == 'string' then
|
||||
major,minor,patch,prerelease,build = parseVersion(major)
|
||||
end
|
||||
patch = patch or 0
|
||||
minor = minor or 0
|
||||
|
||||
checkPositiveInteger(major, "major")
|
||||
checkPositiveInteger(minor, "minor")
|
||||
checkPositiveInteger(patch, "patch")
|
||||
|
||||
local result = {major=major, minor=minor, patch=patch, prerelease=prerelease, build=build}
|
||||
return setmetatable(result, mt)
|
||||
end
|
||||
|
||||
setmetatable(semver, { __call = function(_, ...) return new(...) end })
|
||||
semver._VERSION= semver(semver._VERSION)
|
||||
|
||||
return semver
|
||||
103
Src/external_dependencies/openmpt-trunk/include/premake/src/base/string.lua
vendored
Normal file
103
Src/external_dependencies/openmpt-trunk/include/premake/src/base/string.lua
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
--
|
||||
-- string.lua
|
||||
-- Additions to Lua's built-in string functions.
|
||||
-- Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
--
|
||||
-- Capitalize the first letter of the string.
|
||||
--
|
||||
|
||||
function string.capitalized(self)
|
||||
return self:gsub("^%l", string.upper)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the string has a match for the plain specified pattern
|
||||
--
|
||||
|
||||
function string.contains(s, match)
|
||||
return string.find(s, match, 1, true) ~= nil
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns an array of strings, each of which is a substring of s
|
||||
-- formed by splitting on boundaries formed by `pattern`.
|
||||
--
|
||||
|
||||
function string.explode(s, pattern, plain, maxTokens)
|
||||
if (pattern == '') then return false end
|
||||
local pos = 0
|
||||
local arr = { }
|
||||
for st,sp in function() return s:find(pattern, pos, plain) end do
|
||||
table.insert(arr, s:sub(pos, st-1))
|
||||
pos = sp + 1
|
||||
if maxTokens ~= nil and maxTokens > 0 then
|
||||
maxTokens = maxTokens - 1
|
||||
if maxTokens == 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert(arr, s:sub(pos))
|
||||
return arr
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Find the last instance of a pattern in a string.
|
||||
--
|
||||
|
||||
function string.findlast(s, pattern, plain)
|
||||
local curr = 0
|
||||
repeat
|
||||
local next = s:find(pattern, curr + 1, plain)
|
||||
if (next) then curr = next end
|
||||
until (not next)
|
||||
if (curr > 0) then
|
||||
return curr
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns the number of lines of text contained by the string.
|
||||
--
|
||||
|
||||
function string.lines(s)
|
||||
local trailing, n = s:gsub('.-\n', '')
|
||||
if #trailing > 0 then
|
||||
n = n + 1
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Return a plural version of a string.
|
||||
---
|
||||
|
||||
function string:plural()
|
||||
if self:endswith("y") then
|
||||
return self:sub(1, #self - 1) .. "ies"
|
||||
else
|
||||
return self .. "s"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Returns the string escaped for Lua patterns.
|
||||
---
|
||||
|
||||
function string.escapepattern(s)
|
||||
return s:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%0")
|
||||
end
|
||||
602
Src/external_dependencies/openmpt-trunk/include/premake/src/base/table.lua
vendored
Normal file
602
Src/external_dependencies/openmpt-trunk/include/premake/src/base/table.lua
vendored
Normal file
@@ -0,0 +1,602 @@
|
||||
--
|
||||
-- table.lua
|
||||
-- Additions to Lua's built-in table functions.
|
||||
-- Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
--
|
||||
-- Make a copy of the indexed elements of the table.
|
||||
--
|
||||
|
||||
function table.arraycopy(object)
|
||||
local result = {}
|
||||
for i, value in ipairs(object) do
|
||||
result[i] = value
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the table contains the specified value.
|
||||
--
|
||||
|
||||
function table.contains(t, value)
|
||||
for _,v in pairs(t) do
|
||||
if (v == value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Make a shallow copy of a table
|
||||
--
|
||||
|
||||
function table.shallowcopy(object)
|
||||
local copy = {}
|
||||
for k, v in pairs(object) do
|
||||
copy[k] = v
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Make a complete copy of a table, including any child tables it contains.
|
||||
--
|
||||
|
||||
function table.deepcopy(object)
|
||||
-- keep track of already seen objects to avoid loops
|
||||
local seen = {}
|
||||
|
||||
local function copy(object)
|
||||
if type(object) ~= "table" then
|
||||
return object
|
||||
elseif seen[object] then
|
||||
return seen[object]
|
||||
end
|
||||
|
||||
local clone = {}
|
||||
seen[object] = clone
|
||||
for key, value in pairs(object) do
|
||||
clone[key] = copy(value)
|
||||
end
|
||||
|
||||
setmetatable(clone, getmetatable(object))
|
||||
return clone
|
||||
end
|
||||
|
||||
return copy(object)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Enumerates an array of objects and returns a new table containing
|
||||
-- only the value of one particular field.
|
||||
--
|
||||
|
||||
function table.extract(arr, fname)
|
||||
local result = { }
|
||||
for _,v in ipairs(arr) do
|
||||
table.insert(result, v[fname])
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Enumerates an array of objects and returns a new table containing
|
||||
-- only the values satisfying the given predicate.
|
||||
--
|
||||
|
||||
function table.filter(arr, fn)
|
||||
local result = { }
|
||||
table.foreachi(arr, function(val)
|
||||
if fn(val) then
|
||||
table.insert(result, val)
|
||||
end
|
||||
end)
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Flattens a hierarchy of tables into a single array containing all
|
||||
-- of the values.
|
||||
--
|
||||
|
||||
function table.flatten(arr)
|
||||
local result = {}
|
||||
|
||||
local function flatten(arr)
|
||||
local n = #arr
|
||||
for i = 1, n do
|
||||
local v = arr[i]
|
||||
if type(v) == "table" then
|
||||
flatten(v)
|
||||
elseif v then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
flatten(arr)
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Walk the elements of an array and call the specified function
|
||||
-- for each non-nil element. This works around a "feature" of the
|
||||
-- ipairs() function that stops iteration at the first nil.
|
||||
--
|
||||
-- @param arr
|
||||
-- The array to iterate.
|
||||
-- @param func
|
||||
-- The function to call. The value (not the index) will be passed
|
||||
-- as the only argument.
|
||||
--
|
||||
|
||||
function table.foreachi(arr, func)
|
||||
if arr then
|
||||
local n = #arr
|
||||
for i = 1, n do
|
||||
local v = arr[i]
|
||||
if v then
|
||||
func(v, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Merge two lists into an array of objects, containing pairs
|
||||
-- of values, one from each list.
|
||||
--
|
||||
|
||||
function table.fold(list1, list2)
|
||||
local result = {}
|
||||
for _, item1 in ipairs(list1 or {}) do
|
||||
if list2 and #list2 > 0 then
|
||||
for _, item2 in ipairs(list2) do
|
||||
table.insert(result, { item1, item2 })
|
||||
end
|
||||
else
|
||||
table.insert(result, { item1 })
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Merges an array of items into a string.
|
||||
--
|
||||
|
||||
function table.implode(arr, before, after, between)
|
||||
local result = ""
|
||||
for _,v in ipairs(arr) do
|
||||
if (result ~= "" and between) then
|
||||
result = result .. between
|
||||
end
|
||||
result = result .. before .. v .. after
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Looks for an object within an array. Returns its index if found,
|
||||
-- or nil if the object could not be found.
|
||||
--
|
||||
|
||||
function table.indexof(tbl, obj)
|
||||
for k, v in ipairs(tbl) do
|
||||
if v == obj then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Looks for an object within a table. Returns the key if found,
|
||||
-- or nil if the object could not be found.
|
||||
--
|
||||
|
||||
function table.findKeyByValue(tbl, obj)
|
||||
for k, v in pairs(tbl) do
|
||||
if v == obj then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Insert a new value into a table in the position after the specified
|
||||
-- existing value. If the specified value does not exist in the table,
|
||||
-- the new value is appended to the end of the table.
|
||||
--
|
||||
-- @param tbl
|
||||
-- The table in which to insert.
|
||||
-- @param after
|
||||
-- The existing value to insert after.
|
||||
-- @param value
|
||||
-- The new value to insert.
|
||||
--
|
||||
|
||||
function table.insertafter(tbl, after, value)
|
||||
local i = table.indexof(tbl, after)
|
||||
if i then
|
||||
table.insert(tbl, i + 1, value)
|
||||
else
|
||||
table.insert(tbl, value)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Inserts a value or array of values into a table. If the value is
|
||||
-- itself a table, its contents are enumerated and added instead. So
|
||||
-- these inputs give these outputs:
|
||||
--
|
||||
-- "x" -> { "x" }
|
||||
-- { "x", "y" } -> { "x", "y" }
|
||||
-- { "x", { "y" }} -> { "x", "y" }
|
||||
--
|
||||
|
||||
function table.insertflat(tbl, values)
|
||||
if values == nil then
|
||||
return
|
||||
elseif type(values) == "table" then
|
||||
for _, value in ipairs(values) do
|
||||
table.insertflat(tbl, value)
|
||||
end
|
||||
else
|
||||
table.insert(tbl, values)
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Inserts a value into a table as both a list item and a key-value pair.
|
||||
-- Useful for set operations. Returns false if the value already exists, true otherwise.
|
||||
--
|
||||
|
||||
function table.insertkeyed(tbl, pos, value)
|
||||
if value == nil then
|
||||
value = pos
|
||||
pos = #tbl + 1
|
||||
end
|
||||
|
||||
if tbl[value] ~= nil then
|
||||
return false
|
||||
end
|
||||
|
||||
table.insert(tbl, pos, value)
|
||||
tbl[value] = value
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Inserts a value into a table in sorted order. Assumes that the
|
||||
-- table is already sorted according to the sort function. If fn is
|
||||
-- nil, the table is sorted according to the < operator.
|
||||
--
|
||||
|
||||
function table.insertsorted(tbl, value, fn)
|
||||
if value == nil then
|
||||
return
|
||||
else
|
||||
fn = fn or function(a, b) return a < b end
|
||||
|
||||
local minindex = 1
|
||||
local maxindex = #tbl + 1
|
||||
while minindex < maxindex do
|
||||
local index = minindex + ((maxindex - minindex) >> 1)
|
||||
local test = tbl[index]
|
||||
if fn(value, test) then
|
||||
maxindex = index
|
||||
else
|
||||
minindex = index + 1
|
||||
if not fn(test, value) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(tbl, minindex, value)
|
||||
end
|
||||
|
||||
return tbl
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the table is empty, and contains no indexed or keyed values.
|
||||
--
|
||||
|
||||
function table.isempty(t)
|
||||
return next(t) == nil
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Adds the values from one array to the end of another and
|
||||
-- returns the result.
|
||||
--
|
||||
|
||||
function table.join(...)
|
||||
local result = { }
|
||||
local arg = {...}
|
||||
for _,t in ipairs(arg) do
|
||||
if type(t) == "table" then
|
||||
for _,v in ipairs(t) do
|
||||
table.insert(result, v)
|
||||
end
|
||||
else
|
||||
table.insert(result, t)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Return a list of all keys used in a table.
|
||||
--
|
||||
|
||||
function table.keys(tbl)
|
||||
local keys = {}
|
||||
for k, _ in pairs(tbl) do
|
||||
table.insert(keys, k)
|
||||
end
|
||||
return keys
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Adds the key-value associations from one table into another
|
||||
-- and returns the resulting merged table.
|
||||
--
|
||||
|
||||
function table.merge(...)
|
||||
local result = {}
|
||||
local arg = {...}
|
||||
for _,t in ipairs(arg) do
|
||||
|
||||
if type(t) == "table" then
|
||||
for k,v in pairs(t) do
|
||||
if type(result[k]) == "table" and type(v) == "table" then
|
||||
result[k] = table.merge(result[k], v)
|
||||
else
|
||||
result[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
error("invalid value")
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Replace all instances of `value` with `replacement` in an array. Array
|
||||
-- elements are modified in place.
|
||||
--
|
||||
-- @param value
|
||||
-- The value to be replaced.
|
||||
-- @param replacement
|
||||
-- The new value.
|
||||
---
|
||||
|
||||
function table.replace(self, value, replacement)
|
||||
for i = 1, #self do
|
||||
if self[i] == value then
|
||||
self[i] = replacement
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Translates the values contained in array, using the specified
|
||||
-- translation table, and returns the results in a new array.
|
||||
--
|
||||
|
||||
function table.translate(arr, translation)
|
||||
if not translation then return {} end
|
||||
|
||||
local result = {}
|
||||
for i = 1, #arr do
|
||||
local tvalue
|
||||
if type(translation) == "function" then
|
||||
tvalue = translation(arr[i])
|
||||
else
|
||||
tvalue = translation[arr[i]]
|
||||
end
|
||||
if (tvalue) then
|
||||
table.insert(result, tvalue)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Dumps a table to a string
|
||||
--
|
||||
function table.tostring(tab, recurse, indent)
|
||||
local res = ''
|
||||
|
||||
if not indent then
|
||||
indent = 0
|
||||
end
|
||||
|
||||
local format_value = function(k, v, i)
|
||||
formatting = string.rep("\t", i)
|
||||
|
||||
if k then
|
||||
if type(k) == "table" then
|
||||
k = '[table]'
|
||||
end
|
||||
formatting = formatting .. k .. ": "
|
||||
end
|
||||
|
||||
if not v then
|
||||
return formatting .. '(nil)'
|
||||
elseif type(v) == "table" then
|
||||
if recurse and recurse > 0 then
|
||||
return formatting .. '\n' .. table.tostring(v, recurse-1, i+1)
|
||||
else
|
||||
return formatting .. "<table>"
|
||||
end
|
||||
elseif type(v) == "function" then
|
||||
return formatting .. tostring(v)
|
||||
elseif type(v) == "userdata" then
|
||||
return formatting .. "<userdata>"
|
||||
elseif type(v) == "boolean" then
|
||||
if v then
|
||||
return formatting .. 'true'
|
||||
else
|
||||
return formatting .. 'false'
|
||||
end
|
||||
else
|
||||
return formatting .. v
|
||||
end
|
||||
end
|
||||
|
||||
if type(tab) == "table" then
|
||||
local first = true
|
||||
|
||||
-- add the meta table.
|
||||
local mt = getmetatable(tab)
|
||||
if mt then
|
||||
res = res .. format_value('__mt', mt, indent)
|
||||
first = false
|
||||
end
|
||||
|
||||
-- add all values.
|
||||
for k, v in pairs(tab) do
|
||||
if not first then
|
||||
res = res .. '\n'
|
||||
end
|
||||
|
||||
res = res .. format_value(k, v, indent)
|
||||
first = false
|
||||
end
|
||||
else
|
||||
res = res .. format_value(nil, tab, indent)
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns a copy of a list with all duplicate elements removed.
|
||||
--
|
||||
function table.unique(tab)
|
||||
local elems = { }
|
||||
local result = { }
|
||||
table.foreachi(tab, function(elem)
|
||||
if not elems[elem] then
|
||||
table.insert(result, elem)
|
||||
elems[elem] = true
|
||||
end
|
||||
end)
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
--
|
||||
-- Filters a table for empty entries. primarly useful for lists of string.
|
||||
--
|
||||
function table.filterempty(dirs)
|
||||
return table.translate(dirs, function(val)
|
||||
if val and #val > 0 then
|
||||
return val
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Compares two tables.
|
||||
--
|
||||
function table.equals(a, b)
|
||||
for k, v in pairs(a) do
|
||||
if b[k] ~= v then
|
||||
return false
|
||||
end
|
||||
end
|
||||
for k, v in pairs(b) do
|
||||
if a[k] ~= v then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Enumerate a table sorted by its keys.
|
||||
--
|
||||
function spairs(t)
|
||||
-- collect the keys
|
||||
local keys = {}
|
||||
for k in pairs(t) do
|
||||
table.insert(keys, k)
|
||||
end
|
||||
table.sort(keys)
|
||||
|
||||
-- return the iterator function
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
if keys[i] then
|
||||
return keys[i], t[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Intersect two arrays and return a new array
|
||||
--
|
||||
function table.intersect(a, b)
|
||||
local result = {}
|
||||
for _, v in ipairs(b) do
|
||||
if table.indexof(a, v) then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--
|
||||
-- The difference of A and B is the set containing those elements that are in A but not in B
|
||||
--
|
||||
function table.difference(a, b)
|
||||
local result = {}
|
||||
for _, v in ipairs(a) do
|
||||
if not table.indexof(b, v) then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
45
Src/external_dependencies/openmpt-trunk/include/premake/src/base/term.lua
vendored
Normal file
45
Src/external_dependencies/openmpt-trunk/include/premake/src/base/term.lua
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
--
|
||||
-- term.lua
|
||||
-- Additions to the 'term' namespace.
|
||||
-- Copyright (c) 2017 Blizzard Entertainment and the Premake project
|
||||
--
|
||||
|
||||
-- default colors.
|
||||
term.black = 0
|
||||
term.blue = 1
|
||||
term.green = 2
|
||||
term.cyan = 3
|
||||
term.red = 4
|
||||
term.purple = 5
|
||||
term.brown = 6
|
||||
term.lightGray = 7
|
||||
term.gray = 8
|
||||
term.lightBlue = 9
|
||||
term.lightGreen = 10
|
||||
term.lightCyan = 11
|
||||
term.lightRed = 12
|
||||
term.magenta = 13
|
||||
term.yellow = 14
|
||||
term.white = 15
|
||||
|
||||
-- colors for specific purpose.
|
||||
term.warningColor = term.magenta
|
||||
term.errorColor = term.lightRed
|
||||
term.infoColor = term.lightCyan
|
||||
|
||||
-- color stack implementation.
|
||||
term._colorStack = {}
|
||||
|
||||
function term.pushColor(color)
|
||||
local old = term.getTextColor()
|
||||
table.insert(term._colorStack, old)
|
||||
|
||||
term.setTextColor(color)
|
||||
end
|
||||
|
||||
function term.popColor()
|
||||
if #term._colorStack > 0 then
|
||||
local color = table.remove(term._colorStack)
|
||||
term.setTextColor(color)
|
||||
end
|
||||
end
|
||||
61
Src/external_dependencies/openmpt-trunk/include/premake/src/base/tools.lua
vendored
Normal file
61
Src/external_dependencies/openmpt-trunk/include/premake/src/base/tools.lua
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
-- tools.lua
|
||||
-- Work with Premake's collection of tool adapters.
|
||||
-- Author Jason Perkins
|
||||
-- Copyright (c) 2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.tools = {}
|
||||
|
||||
|
||||
---
|
||||
-- Given a toolset identifier (e.g. "gcc" or "gcc-4.8") returns the
|
||||
-- corresponding tool adapter and the version, if one was provided.
|
||||
--
|
||||
-- @param identifier
|
||||
-- A toolset identifier composed of two parts: the toolset name,
|
||||
-- which should match of the name of the adapter object ("gcc",
|
||||
-- "clang", etc.) in the p.tools namespace, and and optional
|
||||
-- version number, separated by a dash.
|
||||
--
|
||||
-- To make things more intuitive for Visual Studio users, supports
|
||||
-- identifiers like "v100" to represent the v100 Microsoft platform
|
||||
-- toolset.
|
||||
-- @return
|
||||
-- If successful, returns the toolset adapter object. If a version
|
||||
-- was specified as part of the identifier, that is returned as a
|
||||
-- second return value. If no corresponding tool adapter exists,
|
||||
-- returns nil.
|
||||
---
|
||||
|
||||
function p.tools.normalize(identifier)
|
||||
if identifier:startswith("v") then -- TODO: this should be deprecated?
|
||||
identifier = 'msc-' .. identifier
|
||||
end
|
||||
|
||||
local parts = identifier:explode("-", true, 1)
|
||||
if parts[2] == nil then
|
||||
return parts[1]
|
||||
end
|
||||
|
||||
-- 'msc-100' is accepted, but the code expects 'v100'
|
||||
if parts[1] == "msc" and tonumber(parts[2]:sub(1,3)) ~= nil then
|
||||
parts[2] = "v" .. parts[2]
|
||||
end
|
||||
|
||||
-- perform case-correction of the LLVM toolset
|
||||
if parts[2]:startswith("llvm-vs") then
|
||||
parts[2] = "LLVM-" .. parts[2]:sub(6)
|
||||
end
|
||||
|
||||
return parts[1] .. '-' .. parts[2]
|
||||
end
|
||||
|
||||
|
||||
function p.tools.canonical(identifier)
|
||||
identifier = p.tools.normalize(identifier)
|
||||
|
||||
local parts = identifier:explode("-", true, 1)
|
||||
return p.tools[parts[1]], parts[2]
|
||||
end
|
||||
329
Src/external_dependencies/openmpt-trunk/include/premake/src/base/tree.lua
vendored
Normal file
329
Src/external_dependencies/openmpt-trunk/include/premake/src/base/tree.lua
vendored
Normal file
@@ -0,0 +1,329 @@
|
||||
--
|
||||
-- tree.lua
|
||||
-- Functions for working with the source code tree.
|
||||
-- Copyright (c) 2009-2013 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
p.tree = {}
|
||||
local tree = p.tree
|
||||
|
||||
|
||||
--
|
||||
-- Create a new tree.
|
||||
--
|
||||
-- @param n
|
||||
-- The name of the tree, applied to the root node (optional).
|
||||
--
|
||||
|
||||
function tree.new(n)
|
||||
local t = {
|
||||
name = n,
|
||||
children = {}
|
||||
}
|
||||
return t
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Add a new node to the tree, or returns the current node if it already exists.
|
||||
--
|
||||
-- @param tr
|
||||
-- The tree to contain the new node.
|
||||
-- @param p
|
||||
-- The path of the new node.
|
||||
-- @param extraFields
|
||||
-- A table containing key-value pairs to be added to any new nodes.
|
||||
-- @returns
|
||||
-- The new tree node.
|
||||
--
|
||||
|
||||
function tree.add(tr, p, extraFields)
|
||||
-- Special case "." refers to the current node
|
||||
if p == "." or p == "/" then
|
||||
return tr
|
||||
end
|
||||
|
||||
-- Look for the immediate parent for this new node, creating it if necessary.
|
||||
-- Recurses to create as much of the tree as necessary.
|
||||
local parentnode = tree.add(tr, path.getdirectory(p), extraFields)
|
||||
|
||||
-- Create the child if necessary
|
||||
local childname = path.getname(p)
|
||||
local childnode = parentnode.children[childname]
|
||||
if not childnode or childnode.path ~= p then
|
||||
childnode = tree.insert(parentnode, tree.new(childname))
|
||||
childnode.path = p
|
||||
if extraFields then
|
||||
for k,v in pairs(extraFields) do
|
||||
childnode[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return childnode
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Insert one tree into another.
|
||||
--
|
||||
-- @param parent
|
||||
-- The parent tree, to contain the child.
|
||||
-- @param child
|
||||
-- The child tree, to be inserted.
|
||||
--
|
||||
|
||||
function tree.insert(parent, child)
|
||||
table.insert(parent.children, child)
|
||||
if child.name then
|
||||
parent.children[child.name] = child
|
||||
end
|
||||
child.parent = parent
|
||||
return child
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Gets the node's relative path from it's parent. If the parent does not have
|
||||
-- a path set (it is the root or other container node) returns the full node path.
|
||||
--
|
||||
-- @param node
|
||||
-- The node to query.
|
||||
--
|
||||
|
||||
function tree.getlocalpath(node)
|
||||
if node.parent.path then
|
||||
return node.name
|
||||
elseif node.cfg then
|
||||
return node.cfg.name
|
||||
else
|
||||
return node.path
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determines if the tree contains any branch nodes, or only leaves.
|
||||
--
|
||||
-- @param tr
|
||||
-- The root node of the tree to query.
|
||||
-- @return
|
||||
-- True if a node below the root contains children, false otherwise.
|
||||
--
|
||||
|
||||
function tree.hasbranches(tr)
|
||||
local n = #tr.children
|
||||
if n > 0 then
|
||||
for i = 1, n do
|
||||
if #tr.children[i].children > 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Determines if one node is a parent if another.
|
||||
--
|
||||
-- @param n
|
||||
-- The node being tested for parentage.
|
||||
-- @param child
|
||||
-- The child node being testing against.
|
||||
-- @return
|
||||
-- True if n is a parent of child.
|
||||
--
|
||||
|
||||
function tree.isparent(n, child)
|
||||
local p = child.parent
|
||||
while p do
|
||||
if p == n then
|
||||
return true
|
||||
end
|
||||
p = p.parent
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Remove a node from a tree.
|
||||
--
|
||||
-- @param node
|
||||
-- The node to remove.
|
||||
--
|
||||
|
||||
function tree.remove(node)
|
||||
local children = node.parent.children
|
||||
for i = 1, #children do
|
||||
if children[i] == node then
|
||||
table.remove(children, i)
|
||||
end
|
||||
end
|
||||
node.children = {}
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Sort the nodes of a tree in-place.
|
||||
--
|
||||
-- @param tr
|
||||
-- The tree to sort.
|
||||
-- @param fn
|
||||
-- An optional comparator function.
|
||||
--
|
||||
|
||||
function tree.sort(tr, fn)
|
||||
if not fn then
|
||||
fn = function(a,b) return a.name < b.name end
|
||||
end
|
||||
tree.traverse(tr, {
|
||||
onnode = function(node)
|
||||
table.sort(node.children, fn)
|
||||
end
|
||||
}, true)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Traverse a tree.
|
||||
--
|
||||
-- @param t
|
||||
-- The tree to traverse.
|
||||
-- @param fn
|
||||
-- A collection of callback functions, which may contain any or all of the
|
||||
-- following entries. Entries are called in this order.
|
||||
--
|
||||
-- onnode - called on each node encountered
|
||||
-- onbranchenter - called on branches, before processing children
|
||||
-- onbranch - called only on branch nodes
|
||||
-- onleaf - called only on leaf nodes
|
||||
-- onbranchexit - called on branches, after processing children
|
||||
--
|
||||
-- Callbacks receive two arguments: the node being processed, and the
|
||||
-- current traversal depth.
|
||||
--
|
||||
-- @param includeroot
|
||||
-- True to include the root node in the traversal, otherwise it will be skipped.
|
||||
-- @param initialdepth
|
||||
-- An optional starting value for the traversal depth; defaults to zero.
|
||||
--
|
||||
|
||||
function tree.traverse(t, fn, includeroot, initialdepth)
|
||||
|
||||
-- forward declare my handlers, which call each other
|
||||
local donode, dochildren
|
||||
|
||||
-- process an individual node
|
||||
donode = function(node, fn, depth)
|
||||
if node.isremoved then
|
||||
return
|
||||
end
|
||||
|
||||
if fn.onnode then
|
||||
fn.onnode(node, depth)
|
||||
end
|
||||
|
||||
if #node.children > 0 then
|
||||
if fn.onbranchenter then
|
||||
fn.onbranchenter(node, depth)
|
||||
end
|
||||
if fn.onbranch then
|
||||
fn.onbranch(node, depth)
|
||||
end
|
||||
dochildren(node, fn, depth + 1)
|
||||
if fn.onbranchexit then
|
||||
fn.onbranchexit(node, depth)
|
||||
end
|
||||
else
|
||||
if fn.onleaf then
|
||||
fn.onleaf(node, depth)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- this goofy iterator allows nodes to be removed during the traversal
|
||||
dochildren = function(parent, fn, depth)
|
||||
local i = 1
|
||||
while i <= #parent.children do
|
||||
local node = parent.children[i]
|
||||
donode(node, fn, depth)
|
||||
if node == parent.children[i] then
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- set a default initial traversal depth, if one wasn't set
|
||||
if not initialdepth then
|
||||
initialdepth = 0
|
||||
end
|
||||
|
||||
if includeroot then
|
||||
donode(t, fn, initialdepth)
|
||||
else
|
||||
dochildren(t, fn, initialdepth)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Starting at the top of the tree, remove nodes that contain only a single
|
||||
-- item until I hit a node that has multiple items. This is used to remove
|
||||
-- superfluous folders from the top of the source tree.
|
||||
--
|
||||
|
||||
function tree.trimroot(tr)
|
||||
local trimmed
|
||||
|
||||
-- start by removing single-children folders from the top of the tree
|
||||
while #tr.children == 1 do
|
||||
local node = tr.children[1]
|
||||
|
||||
-- if this node has no children (it is the last node in the tree) I'm done
|
||||
if #node.children == 0 or node.trim == false then
|
||||
break
|
||||
end
|
||||
|
||||
-- remove this node from the tree, and move its children up a level
|
||||
trimmed = true
|
||||
local numChildren = #node.children
|
||||
for i = 1, numChildren do
|
||||
local child = node.children[i]
|
||||
child.parent = node.parent
|
||||
tr.children[i] = child
|
||||
end
|
||||
end
|
||||
|
||||
-- found the top, now remove any single-children ".." folders from here
|
||||
local dotdot
|
||||
local count = #tr.children
|
||||
repeat
|
||||
dotdot = false
|
||||
for i = 1, count do
|
||||
local node = tr.children[i]
|
||||
if node.name == ".." and #node.children == 1 then
|
||||
local child = node.children[1]
|
||||
child.parent = node.parent
|
||||
tr.children[i] = child
|
||||
trimmed = true
|
||||
dotdot = true
|
||||
end
|
||||
end
|
||||
until not dotdot
|
||||
|
||||
-- if nodes were removed, adjust the paths on all remaining nodes
|
||||
if trimmed then
|
||||
tree.traverse(tr, {
|
||||
onnode = function(node)
|
||||
if node.parent.path then
|
||||
node.path = path.join(node.parent.path, node.name)
|
||||
else
|
||||
node.path = node.name
|
||||
end
|
||||
end
|
||||
}, false)
|
||||
end
|
||||
end
|
||||
239
Src/external_dependencies/openmpt-trunk/include/premake/src/base/validation.lua
vendored
Normal file
239
Src/external_dependencies/openmpt-trunk/include/premake/src/base/validation.lua
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
---
|
||||
-- base/validation.lua
|
||||
--
|
||||
-- Verify the contents of the project object before handing them off to
|
||||
-- the action/exporter.
|
||||
--
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.validation = {}
|
||||
local m = p.validation
|
||||
|
||||
m.elements = {}
|
||||
|
||||
|
||||
---
|
||||
-- Validate the global container and all of its contents.
|
||||
---
|
||||
|
||||
m.elements.global = function(glb)
|
||||
return {
|
||||
}
|
||||
end
|
||||
|
||||
function p.global.validate(self)
|
||||
p.callArray(m.elements.global, self)
|
||||
p.container.validateChildren(self)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Validate a workspace and its projects.
|
||||
---
|
||||
|
||||
m.elements.workspace = function(wks)
|
||||
return {
|
||||
m.workspaceHasConfigs,
|
||||
m.uniqueProjectIds,
|
||||
}
|
||||
end
|
||||
|
||||
function p.workspace.validate(self)
|
||||
p.callArray(m.elements.workspace, self)
|
||||
p.container.validateChildren(self)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Validate a project and its configurations.
|
||||
---
|
||||
|
||||
m.elements.project = function(prj)
|
||||
return {
|
||||
m.projectHasLanguage,
|
||||
m.actionSupportsLanguage,
|
||||
m.actionSupportsKind,
|
||||
m.projectRulesExist,
|
||||
m.projectValuesInScope,
|
||||
}
|
||||
end
|
||||
|
||||
function p.project.validate(self)
|
||||
p.callArray(m.elements.project, self)
|
||||
for cfg in p.project.eachconfig(self) do
|
||||
p.config.validate(cfg)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Validate a project configuration.
|
||||
---
|
||||
|
||||
m.elements.config = function(cfg)
|
||||
return {
|
||||
m.configHasKind,
|
||||
m.configSupportsKind,
|
||||
m.configValuesInScope,
|
||||
}
|
||||
end
|
||||
|
||||
function p.config.validate(self)
|
||||
p.callArray(m.elements.config, self)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Validate a rule.
|
||||
---
|
||||
|
||||
m.elements.rule = function(rule)
|
||||
return {
|
||||
-- TODO: fill this in
|
||||
}
|
||||
end
|
||||
|
||||
function p.rule.validate(self)
|
||||
p.callArray(m.elements.rule, self)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Check the values stored in a configuration for values that might have
|
||||
-- been set out of scope.
|
||||
--
|
||||
-- @param container
|
||||
-- The container being validated; will only check fields which are
|
||||
-- scoped to this container's class hierarchy.
|
||||
-- @param expectedScope
|
||||
-- The expected scope of values in this object, i.e. "project", "config".
|
||||
-- Values that appear unexpectedly get checked to be sure they match up
|
||||
-- with the values in the expected scope, and an error is raised if they
|
||||
-- are not the same.
|
||||
---
|
||||
|
||||
function p.config.validateScopes(self, container, expected)
|
||||
for f in p.field.each() do
|
||||
-- If this field scoped to the target container class? If not
|
||||
-- I can skip over it (config scope applies to everything).
|
||||
local scope
|
||||
for i = 1, #f.scopes do
|
||||
if f.scopes[i] == "config" or p.container.classIsA(container.class, f.scopes[i]) then
|
||||
scope = f.scopes[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local okay = (not scope or scope == "config")
|
||||
|
||||
-- Skip over fields that are at or below my expected scope.
|
||||
okay = okay or scope == expected
|
||||
|
||||
-- Skip over fields that bubble up to their parent containers anyway;
|
||||
-- these can't be out of scope for that reason
|
||||
okay = okay or p.oven.bubbledFields[f.name]
|
||||
|
||||
-- this one needs to checked
|
||||
okay = okay or p.field.compare(f, self[scope][f.name], self[f.name])
|
||||
|
||||
-- found a problem?
|
||||
if not okay then
|
||||
local key = "validate." .. f.name
|
||||
p.warnOnce(key, "'%s' on %s '%s' differs from %s '%s'; may be set out of scope", f.name, expected, self.name, scope, self[scope].name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
--
|
||||
-- Handlers for individual checks
|
||||
--
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
function m.actionSupportsKind(prj)
|
||||
if not p.action.supports(prj.kind) then
|
||||
p.warn("Unsupported kind '%s' used for project '%s'", prj.kind, prj.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.actionSupportsLanguage(prj)
|
||||
if not p.action.supports(prj.language) then
|
||||
p.warn("Unsupported language '%s' used for project '%s'", prj.language, prj.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.configHasKind(cfg)
|
||||
if not cfg.kind then
|
||||
p.error("Project '%s' needs a kind in configuration '%s'", cfg.project.name, cfg.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.configSupportsKind(cfg)
|
||||
if not p.action.supports(cfg.kind) then
|
||||
p.warn("Unsupported kind '%s' used in configuration '%s'", cfg.kind, cfg.name)
|
||||
end
|
||||
|
||||
-- makefile configuration can only appear in C++ projects; this is the
|
||||
-- default now, so should only be a problem if overridden.
|
||||
if (cfg.kind == p.MAKEFILE or cfg.kind == p.NONE) and p.project.isdotnet(cfg.project) then
|
||||
p.error("Project '%s' uses '%s' kind in configuration '%s'; language must not be C#", cfg.project.name, cfg.kind, cfg.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.configValuesInScope(cfg)
|
||||
p.config.validateScopes(cfg, cfg.project, "config")
|
||||
end
|
||||
|
||||
|
||||
function m.projectHasLanguage(prj)
|
||||
if not prj.language then
|
||||
p.error("project '%s' does not have a language", prj.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.projectRulesExist(prj)
|
||||
for i = 1, #prj.rules do
|
||||
local rule = prj.rules[i]
|
||||
if not p.global.getRule(rule) then
|
||||
p.error("project '%s' uses missing rule '%s'", prj.name, rule)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.projectValuesInScope(prj)
|
||||
p.config.validateScopes(prj, prj, "project")
|
||||
end
|
||||
|
||||
|
||||
function m.uniqueProjectIds(wks)
|
||||
local uuids = {}
|
||||
for prj in p.workspace.eachproject(wks) do
|
||||
if uuids[prj.uuid] then
|
||||
p.error("projects '%s' and '%s' have the same UUID", uuids[prj.uuid], prj.name)
|
||||
end
|
||||
uuids[prj.uuid] = prj.name
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.workspaceHasConfigs(wks)
|
||||
if not wks.configurations or #wks.configurations == 0 then
|
||||
p.error("workspace '%s' does not contain any configurations", wks.name)
|
||||
end
|
||||
end
|
||||
202
Src/external_dependencies/openmpt-trunk/include/premake/src/base/workspace.lua
vendored
Normal file
202
Src/external_dependencies/openmpt-trunk/include/premake/src/base/workspace.lua
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
---
|
||||
-- workspace.lua
|
||||
-- Work with the list of workspaces loaded from the script.
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.workspace = p.api.container("workspace", p.global)
|
||||
|
||||
local workspace = p.workspace
|
||||
|
||||
|
||||
---
|
||||
-- Switch this container's name from "solution" to "workspace"
|
||||
--
|
||||
-- We changed these names on 30 Jul 2015. While it might be nice to leave
|
||||
-- `solution()` around for Visual Studio folks and everyone still used to the
|
||||
-- old system, it would be good to eventually deprecate and remove all of
|
||||
-- the other, more internal uses of "solution" and "sln". Probably including
|
||||
-- all uses of container class aliases, since we probably aren't going to
|
||||
-- need those again (right?).
|
||||
---
|
||||
|
||||
p.solution = workspace
|
||||
workspace.alias = "solution"
|
||||
|
||||
p.alias(_G, "workspace", "solution")
|
||||
p.alias(_G, "externalworkspace", "externalsolution")
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new workspace container instance.
|
||||
---
|
||||
|
||||
function workspace.new(name)
|
||||
local wks = p.container.new(workspace, name)
|
||||
return wks
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Iterate over the configurations of a workspace.
|
||||
--
|
||||
-- @return
|
||||
-- A configuration iteration function.
|
||||
--
|
||||
|
||||
function workspace.eachconfig(self)
|
||||
self = p.oven.bakeWorkspace(self)
|
||||
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
if i > #self.configs then
|
||||
return nil
|
||||
else
|
||||
return self.configs[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Iterate over the projects of a workspace.
|
||||
--
|
||||
-- @return
|
||||
-- An iterator function, returning project configurations.
|
||||
--
|
||||
|
||||
function workspace.eachproject(self)
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= #self.projects then
|
||||
return p.workspace.getproject(self, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Locate a project by name, case insensitive.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the projec to find.
|
||||
-- @return
|
||||
-- The project object, or nil if a matching project could not be found.
|
||||
--
|
||||
|
||||
function workspace.findproject(self, name)
|
||||
name = name:lower()
|
||||
for _, prj in ipairs(self.projects) do
|
||||
if name == prj.name:lower() then
|
||||
return prj
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the tree of project groups.
|
||||
--
|
||||
-- @return
|
||||
-- The tree of project groups defined for the workspace.
|
||||
--
|
||||
|
||||
function workspace.grouptree(self)
|
||||
-- check for a previously cached tree
|
||||
if self.grouptree then
|
||||
return self.grouptree
|
||||
end
|
||||
|
||||
-- build the tree of groups
|
||||
|
||||
local tr = p.tree.new()
|
||||
for prj in workspace.eachproject(self) do
|
||||
local prjpath = path.join(prj.group, prj.name)
|
||||
local node = p.tree.add(tr, prjpath)
|
||||
node.project = prj
|
||||
end
|
||||
|
||||
-- assign UUIDs to each node in the tree
|
||||
p.tree.traverse(tr, {
|
||||
onbranch = function(node)
|
||||
node.uuid = os.uuid("group:" .. node.path)
|
||||
end
|
||||
})
|
||||
|
||||
-- sort by uuid for determinism.
|
||||
p.tree.sort(tr, function(a,b)
|
||||
return a.name < b.name
|
||||
end)
|
||||
|
||||
self.grouptree = tr
|
||||
return tr
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the project configuration at a particular index.
|
||||
--
|
||||
-- @param idx
|
||||
-- An index into the array of projects.
|
||||
-- @return
|
||||
-- The project configuration at the given index.
|
||||
--
|
||||
|
||||
function workspace.getproject(self, idx)
|
||||
self = p.oven.bakeWorkspace(self)
|
||||
return self.projects[idx]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Determines if the workspace contains a project that meets certain criteria.
|
||||
--
|
||||
-- @param func
|
||||
-- A test function. Receives a project as its only argument and returns a
|
||||
-- boolean indicating whether it meets to matching criteria.
|
||||
-- @return
|
||||
-- True if the test function returned true.
|
||||
---
|
||||
|
||||
function workspace.hasProject(self, func)
|
||||
return p.container.hasChild(self, p.project, func)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Return the relative path from the solution to the specified file.
|
||||
--
|
||||
-- @param self
|
||||
-- The workspace object to query.
|
||||
-- @param filename
|
||||
-- The file path, or an array of file paths, to convert.
|
||||
-- @return
|
||||
-- The relative path, or array of paths, from the workspace to the file.
|
||||
--
|
||||
|
||||
function workspace.getrelative(self, filename)
|
||||
if type(filename) == "table" then
|
||||
local result = {}
|
||||
for i, name in ipairs(filename) do
|
||||
if name and #name > 0 then
|
||||
table.insert(result, workspace.getrelative(self, name))
|
||||
end
|
||||
end
|
||||
return result
|
||||
else
|
||||
if filename then
|
||||
local result = filename
|
||||
if path.hasdeferredjoin(result) then
|
||||
result = path.resolvedeferredjoin(result)
|
||||
end
|
||||
return path.getrelative(self.location, result)
|
||||
end
|
||||
end
|
||||
end
|
||||
125
Src/external_dependencies/openmpt-trunk/include/premake/src/host/buffered_io.c
vendored
Normal file
125
Src/external_dependencies/openmpt-trunk/include/premake/src/host/buffered_io.c
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* \file buffered_io.c
|
||||
* \brief provide buffered io.
|
||||
* \author Copyright (c) 2014
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
#include "buffered_io.h"
|
||||
|
||||
void buffer_init(Buffer* b)
|
||||
{
|
||||
b->capacity = 0;
|
||||
b->length = 0;
|
||||
b->data = NULL;
|
||||
}
|
||||
|
||||
void buffer_destroy(Buffer* b)
|
||||
{
|
||||
free(b->data);
|
||||
b->capacity = 0;
|
||||
b->length = 0;
|
||||
b->data = NULL;
|
||||
}
|
||||
|
||||
void buffer_puts(Buffer* b, const void* ptr, size_t len)
|
||||
{
|
||||
char* data;
|
||||
|
||||
size_t required = b->length + len;
|
||||
if (required > b->capacity)
|
||||
{
|
||||
size_t cap = b->capacity;
|
||||
while (required > cap)
|
||||
{
|
||||
cap = (cap * 3) / 2;
|
||||
if (cap <= 65536)
|
||||
cap = 65536;
|
||||
}
|
||||
|
||||
data = (char*)calloc(cap, 1);
|
||||
if (b->length > 0)
|
||||
{
|
||||
memcpy(data, b->data, b->length);
|
||||
free(b->data);
|
||||
}
|
||||
b->data = data;
|
||||
b->capacity = cap;
|
||||
}
|
||||
|
||||
memcpy(b->data + b->length, ptr, len);
|
||||
b->length += len;
|
||||
}
|
||||
|
||||
void buffer_printf(Buffer* b, const char *fmt, ...)
|
||||
{
|
||||
char text[2048];
|
||||
int len;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
len = vsnprintf(text, sizeof(text) - 1, fmt, args);
|
||||
va_end(args);
|
||||
buffer_puts(b, text, len);
|
||||
}
|
||||
|
||||
// -- Lua wrappers ----------------------------------------
|
||||
|
||||
int buffered_new(lua_State* L)
|
||||
{
|
||||
Buffer* b = (Buffer*)malloc(sizeof(Buffer));
|
||||
buffer_init(b);
|
||||
lua_pushlightuserdata(L, b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int buffered_write(lua_State* L)
|
||||
{
|
||||
size_t len;
|
||||
const char *s = luaL_checklstring(L, 2, &len);
|
||||
Buffer* b = (Buffer*)lua_touserdata(L, 1);
|
||||
|
||||
buffer_puts(b, s, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buffered_writeln(lua_State* L)
|
||||
{
|
||||
size_t len;
|
||||
const char *s = luaL_optlstring(L, 2, NULL, &len);
|
||||
Buffer* b = (Buffer*)lua_touserdata(L, 1);
|
||||
|
||||
if (s != NULL)
|
||||
buffer_puts(b, s, len);
|
||||
buffer_puts(b, "\r\n", 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buffered_close(lua_State* L)
|
||||
{
|
||||
Buffer* b = (Buffer*)lua_touserdata(L, 1);
|
||||
buffer_destroy(b);
|
||||
free(b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buffered_tostring(lua_State* L)
|
||||
{
|
||||
Buffer* b = (Buffer*)lua_touserdata(L, 1);
|
||||
size_t len = b->length;
|
||||
|
||||
// trim string for _eol of line at the end.
|
||||
if (len > 0 && b->data[len-1] == '\n')
|
||||
--len;
|
||||
if (len > 0 && b->data[len-1] == '\r')
|
||||
--len;
|
||||
|
||||
if (len > 0)
|
||||
// push data into a string.
|
||||
lua_pushlstring(L, b->data, len);
|
||||
else
|
||||
lua_pushstring(L, "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
24
Src/external_dependencies/openmpt-trunk/include/premake/src/host/buffered_io.h
vendored
Normal file
24
Src/external_dependencies/openmpt-trunk/include/premake/src/host/buffered_io.h
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* \file buffered_io.h
|
||||
* \brief provide buffered io.
|
||||
* \author Copyright (c) 2014
|
||||
*/
|
||||
#ifndef buffered_io_h
|
||||
#define buffered_io_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct struct_Buffer
|
||||
{
|
||||
size_t capacity;
|
||||
size_t length;
|
||||
char* data;
|
||||
} Buffer;
|
||||
|
||||
void buffer_init(Buffer* b);
|
||||
void buffer_destroy(Buffer* b);
|
||||
|
||||
void buffer_puts(Buffer* b, const void* ptr, size_t len);
|
||||
void buffer_printf(Buffer* b, const char* s, ...);
|
||||
|
||||
#endif
|
||||
310
Src/external_dependencies/openmpt-trunk/include/premake/src/host/criteria_matches.c
vendored
Normal file
310
Src/external_dependencies/openmpt-trunk/include/premake/src/host/criteria_matches.c
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* \file criteria_matches.c
|
||||
* \brief Determine if this criteria is met by the provided filter terms.
|
||||
* \author Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
struct Word {
|
||||
const char* word;
|
||||
const char* prefix;
|
||||
int matchesFiles;
|
||||
int assertion;
|
||||
int wildcard;
|
||||
};
|
||||
|
||||
struct Pattern {
|
||||
int matchesFiles;
|
||||
int n;
|
||||
struct Word* word;
|
||||
};
|
||||
|
||||
struct Patterns {
|
||||
int prefixed;
|
||||
int filePatterns;
|
||||
int n;
|
||||
struct Pattern* pattern;
|
||||
};
|
||||
|
||||
|
||||
static int criteria_compilePattern(lua_State* L, struct Pattern* pattern);
|
||||
|
||||
|
||||
int criteria_compile(lua_State* L)
|
||||
{
|
||||
struct Patterns* patterns;
|
||||
int i, n;
|
||||
|
||||
/* create a Patterns object and userdata; holds a list of Pattern items */
|
||||
patterns = (struct Patterns*)lua_newuserdata(L, sizeof(struct Patterns));
|
||||
patterns->prefixed = 0;
|
||||
patterns->filePatterns = 0;
|
||||
|
||||
if (luaL_newmetatable(L, "premake.criteria")) {
|
||||
lua_pushstring(L, "__gc");
|
||||
lua_pushcfunction(L, criteria_delete);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
/* create array to hold the incoming list of patterns */
|
||||
n = (int)lua_rawlen(L, 1);
|
||||
patterns->n = n;
|
||||
patterns->pattern = (struct Pattern*)malloc(sizeof(struct Pattern) * n);
|
||||
|
||||
/* create a new pattern object for each incoming pattern */
|
||||
for (i = 0; i < n; ++i) {
|
||||
struct Pattern* pattern = &patterns->pattern[i];
|
||||
|
||||
lua_rawgeti(L, 1, i + 1);
|
||||
criteria_compilePattern(L, pattern);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (pattern->n > 0 && pattern->word[0].prefix != NULL) {
|
||||
patterns->prefixed = 1;
|
||||
}
|
||||
|
||||
if (pattern->matchesFiles) {
|
||||
++patterns->filePatterns;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int criteria_compilePattern(lua_State* L, struct Pattern* pattern)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
/* create array to hold the incoming list of words */
|
||||
n = (int)lua_rawlen(L, -1);
|
||||
pattern->n = n;
|
||||
pattern->word = (struct Word*)malloc(sizeof(struct Word) * n);
|
||||
pattern->matchesFiles = 0;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
struct Word* word = &pattern->word[i];
|
||||
word->matchesFiles = 0;
|
||||
|
||||
lua_rawgeti(L, -1, i + 1);
|
||||
|
||||
lua_rawgeti(L, -1, 1);
|
||||
word->word = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 2);
|
||||
word->prefix = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 3);
|
||||
word->assertion = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 4);
|
||||
word->wildcard = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (word->prefix && strcmp(word->prefix, "files") == 0) {
|
||||
word->matchesFiles = 1;
|
||||
pattern->matchesFiles = 1;
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int criteria_delete(lua_State* L)
|
||||
{
|
||||
int i, n;
|
||||
struct Patterns* patterns = (struct Patterns*)lua_touserdata(L, 1);
|
||||
|
||||
n = patterns->n;
|
||||
for (i = 0; i < n; ++i) {
|
||||
free(patterns->pattern[i].word);
|
||||
}
|
||||
free(patterns->pattern);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int match(lua_State* L, const char* value, struct Word* word)
|
||||
{
|
||||
if (word->wildcard) {
|
||||
/* use string.match() to compare */
|
||||
const char* result;
|
||||
int matched = 0;
|
||||
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_pushvalue(L, 4);
|
||||
lua_pushstring(L, value);
|
||||
lua_pushstring(L, word->word);
|
||||
lua_call(L, 2, 1);
|
||||
|
||||
if (lua_isstring(L, -1)) {
|
||||
result = lua_tostring(L, -1);
|
||||
matched = (strcmp(value, result) == 0);
|
||||
}
|
||||
|
||||
lua_settop(L, top);
|
||||
return matched;
|
||||
}
|
||||
else {
|
||||
return (strcmp(value, word->word) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Compares the value on the top of the stack to the specified word.
|
||||
*/
|
||||
|
||||
static int testValue(lua_State* L, struct Word* word)
|
||||
{
|
||||
const char* value;
|
||||
size_t i, n;
|
||||
int result;
|
||||
|
||||
if (lua_istable(L, -1)) {
|
||||
n = lua_rawlen(L, -1);
|
||||
for (i = 1; i <= n; ++i) {
|
||||
lua_rawgeti(L, -1, i);
|
||||
result = testValue(L, word);
|
||||
lua_pop(L, 1);
|
||||
if (result) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = lua_tostring(L, -1);
|
||||
if (value) {
|
||||
return match(L, value, word);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int testWithPrefix(lua_State* L, struct Word* word, const char* filename, int* fileMatched)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (word->matchesFiles && !filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushstring(L, word->prefix);
|
||||
lua_rawget(L, 2);
|
||||
result = testValue(L, word);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (word->matchesFiles && result == word->assertion) {
|
||||
(*fileMatched) = 1;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return word->assertion;
|
||||
}
|
||||
|
||||
return (!word->assertion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int testNoPrefix(lua_State* L, struct Word* word, const char* filename, int* fileMatched)
|
||||
{
|
||||
if (filename && word->assertion && match(L, filename, word)) {
|
||||
(*fileMatched) = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2)) {
|
||||
if (testValue(L, word)) {
|
||||
lua_pop(L, 2);
|
||||
return word->assertion;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return (!word->assertion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int criteria_matches(lua_State* L)
|
||||
{
|
||||
/* stack [1] = criteria */
|
||||
/* stack [2] = context */
|
||||
|
||||
struct Patterns* patterns;
|
||||
const char* filename;
|
||||
int i, j, fileMatched;
|
||||
int matched = 1;
|
||||
|
||||
/* filename = context.files */
|
||||
lua_pushstring(L, "files");
|
||||
lua_rawget(L, 2);
|
||||
filename = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
/* fetch the patterns to be tested */
|
||||
lua_pushstring(L, "data");
|
||||
lua_rawget(L, 1);
|
||||
patterns = (struct Patterns*)lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
/* if a file is being matched, the pattern must be able to match it */
|
||||
if (patterns->prefixed && filename != NULL && patterns->filePatterns == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Cache string.match on the stack (at index 4) to save time in matches() later */
|
||||
|
||||
lua_getglobal(L, "string");
|
||||
lua_getfield(L, -1, "match");
|
||||
|
||||
/* if there is no file to consider, consider it matched */
|
||||
fileMatched = (filename == NULL);
|
||||
|
||||
/* all patterns must match to pass */
|
||||
for (i = 0; matched && i < patterns->n; ++i) {
|
||||
struct Pattern* pattern = &patterns->pattern[i];
|
||||
|
||||
/* only one word needs to match for the pattern to pass */
|
||||
matched = 0;
|
||||
|
||||
for (j = 0; !matched && j < pattern->n; ++j) {
|
||||
struct Word* word = &pattern->word[j];
|
||||
if (word->prefix) {
|
||||
matched = testWithPrefix(L, word, filename, &fileMatched);
|
||||
}
|
||||
else {
|
||||
matched = testNoPrefix(L, word, filename, &fileMatched);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if a file name was provided in the context, it must be matched */
|
||||
if (filename && !fileMatched) {
|
||||
matched = 0;
|
||||
}
|
||||
|
||||
lua_pushboolean(L, matched);
|
||||
return 1;
|
||||
}
|
||||
207
Src/external_dependencies/openmpt-trunk/include/premake/src/host/curl_utils.c
vendored
Normal file
207
Src/external_dependencies/openmpt-trunk/include/premake/src/host/curl_utils.c
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* \file curl_utils.c
|
||||
* \brief curl utilities for the http library.
|
||||
* \author Copyright (c) 2017 Tom van Dijck, João Matos and the Premake project
|
||||
*/
|
||||
#ifdef PREMAKE_CURL
|
||||
|
||||
#include "curl_utils.h"
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
|
||||
int curlProgressCallback(curl_state* state, double dltotal, double dlnow, double ultotal, double ulnow)
|
||||
{
|
||||
lua_State* L = state->L;
|
||||
|
||||
(void)ultotal;
|
||||
(void)ulnow;
|
||||
|
||||
if (dltotal == 0) return 0;
|
||||
|
||||
/* retrieve the lua progress callback we saved before */
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, state->RefIndex);
|
||||
lua_pushnumber(L, (lua_Number)dltotal);
|
||||
lua_pushnumber(L, (lua_Number)dlnow);
|
||||
int ret = premake_pcall(L, 2, LUA_MULTRET);
|
||||
if (ret != LUA_OK) {
|
||||
printLastError(L);
|
||||
return -1; // abort download
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
size_t curlWriteCallback(char *ptr, size_t size, size_t nmemb, curl_state* state)
|
||||
{
|
||||
size_t length = size * nmemb;
|
||||
buffer_puts(&state->S, ptr, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static void curl_init()
|
||||
{
|
||||
static int initializedHTTP = 0;
|
||||
|
||||
if (initializedHTTP)
|
||||
return;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
atexit(curl_global_cleanup);
|
||||
initializedHTTP = 1;
|
||||
}
|
||||
|
||||
|
||||
static void get_headers(lua_State* L, int headersIndex, struct curl_slist** headers)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, headersIndex) != 0)
|
||||
{
|
||||
const char *item = luaL_checkstring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
*headers = curl_slist_append(*headers, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CURL* curlRequest(lua_State* L, curl_state* state, int optionsIndex, int progressFnIndex, int headersIndex)
|
||||
{
|
||||
char agent[1024];
|
||||
CURL* curl;
|
||||
|
||||
state->L = 0;
|
||||
state->RefIndex = 0;
|
||||
state->errorBuffer[0] = '\0';
|
||||
state->headers = NULL;
|
||||
buffer_init(&state->S);
|
||||
|
||||
curl_init();
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl)
|
||||
return NULL;
|
||||
|
||||
strcpy(agent, "Premake/");
|
||||
strcat(agent, PREMAKE_VERSION);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, luaL_checkstring(L, 1));
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->errorBuffer);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, agent);
|
||||
|
||||
// check if the --insecure option was specified on the commandline.
|
||||
lua_getglobal(L, "_OPTIONS");
|
||||
lua_pushstring(L, "insecure");
|
||||
lua_gettable(L, -2);
|
||||
if (!lua_isnil(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
|
||||
// apply all other options.
|
||||
if (optionsIndex && lua_istable(L, optionsIndex))
|
||||
{
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, optionsIndex) != 0)
|
||||
{
|
||||
const char* key = luaL_checkstring(L, -2);
|
||||
|
||||
if (!strcmp(key, "headers") && lua_istable(L, -1))
|
||||
{
|
||||
get_headers(L, lua_gettop(L), &state->headers);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
||||
}
|
||||
else if (!strcmp(key, "progress") && lua_isfunction(L, -1))
|
||||
{
|
||||
state->L = L;
|
||||
lua_pushvalue(L, -1);
|
||||
state->RefIndex = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else if (!strcmp(key, "userpwd") && lua_isstring(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, luaL_checkstring(L, -1));
|
||||
}
|
||||
else if (!strcmp(key, "username") && lua_isstring(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, luaL_checkstring(L, -1));
|
||||
}
|
||||
else if (!strcmp(key, "password") && lua_isstring(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, luaL_checkstring(L, -1));
|
||||
}
|
||||
else if (!strcmp(key, "timeout") && lua_isnumber(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)luaL_checknumber(L, -1));
|
||||
}
|
||||
else if (!strcmp(key, "timeoutms") && lua_isnumber(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, (long)luaL_checknumber(L, -1));
|
||||
}
|
||||
else if (!strcmp(key, "sslverifyhost") && lua_isnumber(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long)luaL_checknumber(L, -1));
|
||||
}
|
||||
else if (!strcmp(key, "sslverifypeer") && lua_isnumber(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long)luaL_checknumber(L, -1));
|
||||
}
|
||||
else if (!strcmp(key, "proxyurl") && lua_isstring(L, -1))
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, luaL_checkstring(L, -1));
|
||||
}
|
||||
|
||||
// pop the value, leave the key for lua_next
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (progressFnIndex && lua_type(L, progressFnIndex) == LUA_TFUNCTION)
|
||||
{
|
||||
state->L = L;
|
||||
lua_pushvalue(L, progressFnIndex);
|
||||
state->RefIndex = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
if (headersIndex && lua_istable(L, headersIndex))
|
||||
{
|
||||
get_headers(L, headersIndex, &state->headers);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
||||
}
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, state);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteCallback);
|
||||
|
||||
if (state->L != 0)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, state);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curlProgressCallback);
|
||||
}
|
||||
|
||||
// clear error buffer.
|
||||
state->errorBuffer[0] = 0;
|
||||
|
||||
return curl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void curlCleanup(CURL* curl, curl_state* state)
|
||||
{
|
||||
if (state->headers)
|
||||
{
|
||||
curl_slist_free_all(state->headers);
|
||||
state->headers = 0;
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
36
Src/external_dependencies/openmpt-trunk/include/premake/src/host/curl_utils.h
vendored
Normal file
36
Src/external_dependencies/openmpt-trunk/include/premake/src/host/curl_utils.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* \file curl_utils.h
|
||||
* \brief curl utilities for the http library.
|
||||
* \author Copyright (c) 2017 Tom van Dijck, João Matos and the Premake project
|
||||
*/
|
||||
#ifndef curl_utils_h
|
||||
#define curl_utils_h
|
||||
|
||||
#ifdef PREMAKE_CURL
|
||||
|
||||
#include "buffered_io.h"
|
||||
#include "lua.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use curl functions only */
|
||||
#include <curl/curl.h>
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lua_State* L;
|
||||
int RefIndex;
|
||||
Buffer S;
|
||||
char errorBuffer[256];
|
||||
struct curl_slist* headers;
|
||||
} curl_state;
|
||||
|
||||
int curlProgressCallback(curl_state* state, double dltotal, double dlnow, double ultotal, double ulnow);
|
||||
size_t curlWriteCallback(char *ptr, size_t size, size_t nmemb, curl_state* state);
|
||||
|
||||
CURL* curlRequest(lua_State* L, curl_state* state, int optionsIndex, int progressFnIndex, int headersIndex);
|
||||
void curlCleanup(CURL* curl, curl_state* state);
|
||||
|
||||
|
||||
#endif // PREMAKE_CURL
|
||||
|
||||
#endif // curl_utils_h
|
||||
47
Src/external_dependencies/openmpt-trunk/include/premake/src/host/debug_prompt.c
vendored
Normal file
47
Src/external_dependencies/openmpt-trunk/include/premake/src/host/debug_prompt.c
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* \file debug_prompt.c
|
||||
* \brief Display a prompt and enter interactive REPL mode.
|
||||
* \author Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
/* Build on the REPL built into Lua already */
|
||||
#define main lua_main
|
||||
#include "lua.c"
|
||||
|
||||
|
||||
/* Based on dotty() in lua.c */
|
||||
int debug_prompt(lua_State* L)
|
||||
{
|
||||
int status;
|
||||
|
||||
const char* oldProgName = progname;
|
||||
progname = NULL;
|
||||
|
||||
while ((status = loadline(L)) != -1) {
|
||||
if (status == 0) {
|
||||
status = docall(L, 0, 0);
|
||||
}
|
||||
|
||||
report(L, status);
|
||||
|
||||
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
|
||||
lua_getglobal(L, "print");
|
||||
lua_insert(L, 1);
|
||||
if (lua_pcall(L, lua_gettop(L) - 1, 0, 0) != 0) {
|
||||
l_message(progname, lua_pushfstring(L,
|
||||
"error calling " LUA_QL("print") " (%s)",
|
||||
lua_tostring(L, -1))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lua_settop(L, 0); /* clear stack */
|
||||
fputs("\n", stdout);
|
||||
fflush(stdout);
|
||||
progname = oldProgName;
|
||||
return 0;
|
||||
}
|
||||
|
||||
76
Src/external_dependencies/openmpt-trunk/include/premake/src/host/http_download.c
vendored
Normal file
76
Src/external_dependencies/openmpt-trunk/include/premake/src/host/http_download.c
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* \file http_download.c
|
||||
* \brief HTTP download support using libcurl.
|
||||
* \author Copyright (c) 2017 Blizzard Entertainment, João Matos and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "curl_utils.h"
|
||||
|
||||
#ifdef PREMAKE_CURL
|
||||
|
||||
static size_t curl_file_cb(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
return fwrite(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
int http_download(lua_State* L)
|
||||
{
|
||||
curl_state state;
|
||||
CURL* curl;
|
||||
CURLcode code = CURLE_FAILED_INIT;
|
||||
long responseCode = 0;
|
||||
|
||||
FILE* fp;
|
||||
const char* file = luaL_checkstring(L, 2);
|
||||
|
||||
fp = fopen(file, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
lua_pushstring(L, "Unable to open file.");
|
||||
lua_pushnumber(L, -1);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (lua_istable(L, 3))
|
||||
{
|
||||
// http.download(source, destination, { options })
|
||||
curl = curlRequest(L, &state, /*optionsIndex=*/3, /*progressFnIndex=*/0, /*headersIndex=*/0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// backward compatible function signature
|
||||
// http.download(source, destination, progressFunction, { headers })
|
||||
curl = curlRequest(L, &state, /*optionsIndex=*/0, /*progressFnIndex=*/3, /*headersIndex=*/4);
|
||||
}
|
||||
|
||||
if (curl)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_file_cb);
|
||||
|
||||
code = curl_easy_perform(curl);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
curlCleanup(curl, &state);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
char errorBuf[1024];
|
||||
snprintf(errorBuf, sizeof(errorBuf) - 1, "%s\n%s\n", curl_easy_strerror(code), state.errorBuffer);
|
||||
lua_pushstring(L, errorBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, "OK");
|
||||
}
|
||||
|
||||
buffer_destroy(&state.S);
|
||||
lua_pushnumber(L, (lua_Number)responseCode);
|
||||
return 2;
|
||||
}
|
||||
|
||||
#endif
|
||||
59
Src/external_dependencies/openmpt-trunk/include/premake/src/host/http_get.c
vendored
Normal file
59
Src/external_dependencies/openmpt-trunk/include/premake/src/host/http_get.c
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* \file http_get.c
|
||||
* \brief HTTP get request support using libcurl.
|
||||
* \author Copyright (c) 2017 Blizzard Entertainment, João Matos and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "curl_utils.h"
|
||||
|
||||
#ifdef PREMAKE_CURL
|
||||
|
||||
int http_get(lua_State* L)
|
||||
{
|
||||
curl_state state;
|
||||
CURL* curl;
|
||||
CURLcode code = CURLE_FAILED_INIT;
|
||||
long responseCode = 0;
|
||||
|
||||
if (lua_istable(L, 2))
|
||||
{
|
||||
// http.get(source, { options })
|
||||
curl = curlRequest(L, &state, /*optionsIndex=*/2, /*progressFnIndex=*/0, /*headersIndex=*/0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// backward compatible function signature
|
||||
// http.get(source, progressFunction, { headers })
|
||||
curl = curlRequest(L, &state, /*optionsIndex=*/0, /*progressFnIndex=*/2, /*headersIndex=*/3);
|
||||
}
|
||||
|
||||
if (curl)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
||||
|
||||
code = curl_easy_perform(curl);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
curlCleanup(curl, &state);
|
||||
}
|
||||
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
char errorBuf[1024];
|
||||
|
||||
lua_pushnil(L);
|
||||
snprintf(errorBuf, sizeof(errorBuf) - 1, "%s\n%s\n", curl_easy_strerror(code), state.errorBuffer);
|
||||
lua_pushstring(L, errorBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushlstring(L, state.S.data, state.S.length);
|
||||
lua_pushstring(L, "OK");
|
||||
}
|
||||
|
||||
buffer_destroy(&state.S);
|
||||
lua_pushnumber(L, (lua_Number)responseCode);
|
||||
return 3;
|
||||
}
|
||||
|
||||
#endif
|
||||
57
Src/external_dependencies/openmpt-trunk/include/premake/src/host/http_post.c
vendored
Normal file
57
Src/external_dependencies/openmpt-trunk/include/premake/src/host/http_post.c
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* \file http_post.c
|
||||
* \brief HTTP post request support using libcurl.
|
||||
* \author Copyright (c) 2017 Blizzard Entertainment, João Matos and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "curl_utils.h"
|
||||
|
||||
#ifdef PREMAKE_CURL
|
||||
|
||||
int http_post(lua_State* L)
|
||||
{
|
||||
curl_state state;
|
||||
CURL* curl;
|
||||
CURLcode code = CURLE_FAILED_INIT;
|
||||
long responseCode = 0;
|
||||
|
||||
// http.post(source, postdata, { options })
|
||||
curl = curlRequest(L, &state, /*optionsIndex=*/3, /*progressFnIndex=*/0, /*headersIndex=*/0);
|
||||
if (curl)
|
||||
{
|
||||
size_t dataSize;
|
||||
const char* data = luaL_checklstring(L, 2, &dataSize);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
||||
if (data && dataSize > 0)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)dataSize);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
||||
}
|
||||
|
||||
code = curl_easy_perform(curl);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
curlCleanup(curl, &state);
|
||||
}
|
||||
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
char errorBuf[1024];
|
||||
|
||||
lua_pushnil(L);
|
||||
snprintf(errorBuf, sizeof(errorBuf) - 1, "%s\n%s\n", curl_easy_strerror(code), state.errorBuffer);
|
||||
lua_pushstring(L, errorBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushlstring(L, state.S.data, state.S.length);
|
||||
lua_pushstring(L, "OK");
|
||||
}
|
||||
|
||||
buffer_destroy(&state.S);
|
||||
lua_pushnumber(L, (lua_Number)responseCode);
|
||||
return 3;
|
||||
}
|
||||
|
||||
#endif
|
||||
177
Src/external_dependencies/openmpt-trunk/include/premake/src/host/lua_auxlib.c
vendored
Normal file
177
Src/external_dependencies/openmpt-trunk/include/premake/src/host/lua_auxlib.c
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* \file lua_auxlib.c
|
||||
* \brief Modifications and extensions to Lua's library functions.
|
||||
* \author Copyright (c) 2014-2017 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
static int chunk_wrapper(lua_State* L);
|
||||
|
||||
|
||||
|
||||
/* Pull in Lua's aux lib implementation, but rename luaL_loadfilex() so I
|
||||
* can replace it with my own implementation. */
|
||||
|
||||
#define luaL_loadfilex original_luaL_loadfilex
|
||||
#include "lauxlib.c"
|
||||
#undef luaL_loadfilex
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extend the default implementation of luaL_loadfile() to call my chunk
|
||||
* wrapper, above, before executing any scripts loaded from a file.
|
||||
*/
|
||||
LUALIB_API int luaL_loadfilex (lua_State* L, const char* filename, const char* mode)
|
||||
{
|
||||
const char* script_dir;
|
||||
const char* test_name;
|
||||
|
||||
int bottom = lua_gettop(L);
|
||||
int z = !OKAY;
|
||||
|
||||
/* If filename starts with "$/" then we want to load the version that
|
||||
* was embedded into the executable and skip the local file system */
|
||||
if (filename[0] == '$') {
|
||||
z = premake_load_embedded_script(L, filename + 2); /* Skip over leading "$/" */
|
||||
if (z != OKAY) {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the currently running script was embedded, try to load this file
|
||||
* as it if were embedded too. */
|
||||
if (z != OKAY) {
|
||||
lua_getglobal(L, "_SCRIPT_DIR");
|
||||
script_dir = lua_tostring(L, -1);
|
||||
|
||||
if (script_dir && script_dir[0] == '$') {
|
||||
/* Call `path.getabsolute(filename, _SCRIPT_DIR)` to resolve any
|
||||
* "../" sequences in the filename */
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushstring(L, filename);
|
||||
lua_pushvalue(L, -3);
|
||||
lua_call(L, 2, 1);
|
||||
test_name = lua_tostring(L, -1);
|
||||
|
||||
/* if successful, filename and chunk will be on top of stack */
|
||||
z = premake_load_embedded_script(L, test_name + 2); /* Skip over leading "$/" */
|
||||
|
||||
/* remove test_name */
|
||||
lua_remove(L, bottom + 1);
|
||||
}
|
||||
|
||||
/* remove _SCRIPT_DIR */
|
||||
lua_remove(L, bottom);
|
||||
}
|
||||
|
||||
/* Try to locate the script on the filesystem */
|
||||
if (z != OKAY) {
|
||||
lua_pushcfunction(L, os_locate);
|
||||
lua_pushstring(L, filename);
|
||||
lua_call(L, 1, 1);
|
||||
|
||||
test_name = lua_tostring(L, -1);
|
||||
|
||||
if (test_name) {
|
||||
z = original_luaL_loadfilex(L, test_name, mode);
|
||||
}
|
||||
|
||||
/* If the file exists but errors, pass that through */
|
||||
if (test_name && z != OKAY && z != LUA_ERRFILE) {
|
||||
return z;
|
||||
}
|
||||
|
||||
/* If the file didn't exist, remove the result and the test
|
||||
* name from the stack before checking embedded scripts */
|
||||
if (z != OKAY) {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to load from embedded scripts */
|
||||
if (z != OKAY) {
|
||||
z = premake_load_embedded_script(L, filename);
|
||||
}
|
||||
|
||||
/* Either way I should have ended up with the file name followed by the
|
||||
* script chunk on the stack. Turn these into a closure that will call my
|
||||
* wrapper below when the loaded script needs to be executed. */
|
||||
if (z == OKAY) {
|
||||
lua_pushcclosure(L, chunk_wrapper, 2);
|
||||
}
|
||||
else if (z == LUA_ERRFILE) {
|
||||
lua_pushfstring(L, "cannot open %s: No such file or directory", filename);
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Execute a chunk of code previously loaded by my customized version of
|
||||
* luaL_loadfile(), below. Sets the _SCRIPT global variable to the absolute
|
||||
* path of the loaded chunk, and makes its enclosing directory current so
|
||||
* that relative path references to other files or scripts can be used.
|
||||
*/
|
||||
|
||||
static int chunk_wrapper(lua_State* L)
|
||||
{
|
||||
char cwd[PATH_MAX];
|
||||
const char* filename;
|
||||
char* ptr;
|
||||
int i, args;
|
||||
|
||||
args = lua_gettop(L);
|
||||
|
||||
/* Remember the current _SCRIPT and working directory so I can
|
||||
* restore them after this new chunk has been run. */
|
||||
|
||||
do_getcwd(cwd, PATH_MAX);
|
||||
lua_getglobal(L, "_SCRIPT");
|
||||
lua_getglobal(L, "_SCRIPT_DIR");
|
||||
|
||||
/* Set the new _SCRIPT variable */
|
||||
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
lua_setglobal(L, "_SCRIPT");
|
||||
|
||||
/* And the new _SCRIPT_DIR variable (const cheating) */
|
||||
|
||||
filename = lua_tostring(L, lua_upvalueindex(1));
|
||||
ptr = strrchr(filename, '/');
|
||||
if (ptr) *ptr = '\0';
|
||||
lua_pushlstring(L, filename, strlen(filename));
|
||||
lua_setglobal(L, "_SCRIPT_DIR");
|
||||
|
||||
/* And make that the CWD (and fix the const cheat) */
|
||||
|
||||
if (filename[0] != '$') {
|
||||
do_chdir(L, filename);
|
||||
}
|
||||
if (ptr) *ptr = '/';
|
||||
|
||||
/* Move the function's arguments to the top of the stack and
|
||||
* execute the function created by luaL_loadfile() */
|
||||
|
||||
lua_pushvalue(L, lua_upvalueindex(2));
|
||||
for (i = 1; i <= args; ++i) {
|
||||
lua_pushvalue(L, i);
|
||||
}
|
||||
|
||||
lua_call(L, args, LUA_MULTRET);
|
||||
|
||||
/* Finally, restore the previous _SCRIPT variable and working directory
|
||||
* before returning control to the previously executing script. */
|
||||
|
||||
do_chdir(L, cwd);
|
||||
lua_pushvalue(L, args + 1);
|
||||
lua_setglobal(L, "_SCRIPT");
|
||||
lua_pushvalue(L, args + 2);
|
||||
lua_setglobal(L, "_SCRIPT_DIR");
|
||||
|
||||
return lua_gettop(L) - args - 2;
|
||||
}
|
||||
147
Src/external_dependencies/openmpt-trunk/include/premake/src/host/lua_shimtable.h
vendored
Normal file
147
Src/external_dependencies/openmpt-trunk/include/premake/src/host/lua_shimtable.h
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* \file lua_shimtable.h
|
||||
* \brief Lua shim for premake binary modules.
|
||||
* \author Copyright (c) 2017 Tom van Dijck and the Premake project
|
||||
*/
|
||||
#ifndef HEADER_lua_shimtable_H
|
||||
#define HEADER_lua_shimtable_H
|
||||
|
||||
#include "luashim.h"
|
||||
|
||||
static LuaFunctionTable_t s_shimTable = {
|
||||
&luaL_register,
|
||||
&lua_newstate,
|
||||
&lua_close,
|
||||
&lua_newthread,
|
||||
&lua_atpanic,
|
||||
&lua_version,
|
||||
&lua_absindex,
|
||||
&lua_gettop,
|
||||
&lua_settop,
|
||||
&lua_pushvalue,
|
||||
&lua_rotate,
|
||||
&lua_copy,
|
||||
&lua_checkstack,
|
||||
&lua_xmove,
|
||||
&lua_isnumber,
|
||||
&lua_isstring,
|
||||
&lua_iscfunction,
|
||||
&lua_isinteger,
|
||||
&lua_isuserdata,
|
||||
&lua_type,
|
||||
&lua_typename,
|
||||
&lua_tonumberx,
|
||||
&lua_tointegerx,
|
||||
&lua_toboolean,
|
||||
&lua_tolstring,
|
||||
&lua_rawlen,
|
||||
&lua_tocfunction,
|
||||
&lua_touserdata,
|
||||
&lua_tothread,
|
||||
&lua_topointer,
|
||||
&lua_arith,
|
||||
&lua_rawequal,
|
||||
&lua_compare,
|
||||
&lua_pushnil,
|
||||
&lua_pushnumber,
|
||||
&lua_pushinteger,
|
||||
&lua_pushlstring,
|
||||
&lua_pushstring,
|
||||
&lua_pushvfstring,
|
||||
&lua_pushcclosure,
|
||||
&lua_pushboolean,
|
||||
&lua_pushlightuserdata,
|
||||
&lua_pushthread,
|
||||
&lua_getglobal,
|
||||
&lua_gettable,
|
||||
&lua_getfield,
|
||||
&lua_geti,
|
||||
&lua_rawget,
|
||||
&lua_rawgeti,
|
||||
&lua_rawgetp,
|
||||
&lua_createtable,
|
||||
&lua_newuserdata,
|
||||
&lua_getmetatable,
|
||||
&lua_getuservalue,
|
||||
&lua_setglobal,
|
||||
&lua_settable,
|
||||
&lua_setfield,
|
||||
&lua_seti,
|
||||
&lua_rawset,
|
||||
&lua_rawseti,
|
||||
&lua_rawsetp,
|
||||
&lua_setmetatable,
|
||||
&lua_setuservalue,
|
||||
&lua_callk,
|
||||
&lua_pcallk,
|
||||
&lua_load,
|
||||
&lua_dump,
|
||||
&lua_yieldk,
|
||||
&lua_resume,
|
||||
&lua_status,
|
||||
&lua_isyieldable,
|
||||
&lua_gc,
|
||||
&lua_error,
|
||||
&lua_next,
|
||||
&lua_concat,
|
||||
&lua_len,
|
||||
&lua_stringtonumber,
|
||||
&lua_getallocf,
|
||||
&lua_setallocf,
|
||||
&lua_getstack,
|
||||
&lua_getinfo,
|
||||
&lua_getlocal,
|
||||
&lua_setlocal,
|
||||
&lua_getupvalue,
|
||||
&lua_setupvalue,
|
||||
&lua_upvalueid,
|
||||
&lua_upvaluejoin,
|
||||
&lua_sethook,
|
||||
&lua_gethook,
|
||||
&lua_gethookmask,
|
||||
&lua_gethookcount,
|
||||
&luaL_checkversion_,
|
||||
&luaL_getmetafield,
|
||||
&luaL_callmeta,
|
||||
&luaL_tolstring,
|
||||
&luaL_argerror,
|
||||
&luaL_checklstring,
|
||||
&luaL_optlstring,
|
||||
&luaL_checknumber,
|
||||
&luaL_optnumber,
|
||||
&luaL_checkinteger,
|
||||
&luaL_optinteger,
|
||||
&luaL_checkstack,
|
||||
&luaL_checktype,
|
||||
&luaL_checkany,
|
||||
&luaL_newmetatable,
|
||||
&luaL_setmetatable,
|
||||
&luaL_testudata,
|
||||
&luaL_checkudata,
|
||||
&luaL_where,
|
||||
&luaL_checkoption,
|
||||
&luaL_fileresult,
|
||||
&luaL_execresult,
|
||||
&luaL_ref,
|
||||
&luaL_unref,
|
||||
&luaL_loadfilex,
|
||||
&luaL_loadbufferx,
|
||||
&luaL_loadstring,
|
||||
&luaL_newstate,
|
||||
&luaL_len,
|
||||
&luaL_gsub,
|
||||
&luaL_setfuncs,
|
||||
&luaL_getsubtable,
|
||||
&luaL_traceback,
|
||||
&luaL_requiref,
|
||||
&luaL_buffinit,
|
||||
&luaL_prepbuffsize,
|
||||
&luaL_addlstring,
|
||||
&luaL_addstring,
|
||||
&luaL_addvalue,
|
||||
&luaL_pushresult,
|
||||
&luaL_pushresultsize,
|
||||
&luaL_buffinitsize,
|
||||
};
|
||||
|
||||
#endif
|
||||
50
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_chdir.c
vendored
Normal file
50
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_chdir.c
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* \file os_chdir.c
|
||||
* \brief Change the current working directory.
|
||||
* \author Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int do_chdir(lua_State* L, const char* path)
|
||||
{
|
||||
int z;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_buffer[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_buffer, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
z = SetCurrentDirectoryW(wide_buffer);
|
||||
#else
|
||||
(void)(L); /* warning: unused parameter */
|
||||
|
||||
z = !chdir(path);
|
||||
#endif
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int os_chdir(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
|
||||
int z = do_chdir(L, path);
|
||||
if (!z)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unable to switch to directory '%s'", path);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
46
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_chmod.c
vendored
Normal file
46
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_chmod.c
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* \file os_chmod.c
|
||||
* \brief Change file permissions
|
||||
* \author Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
int os_chmod(lua_State* L)
|
||||
{
|
||||
int rv;
|
||||
char* endPtr;
|
||||
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
const char* modeStr = luaL_checkstring(L, 2);
|
||||
|
||||
int mode = (int)strtol(modeStr, &endPtr, 8);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
/* DOS-mode permissions only support the low word */
|
||||
mode = mode & 0x0000ffff;
|
||||
rv = _chmod(path, mode);
|
||||
#else
|
||||
rv = chmod(path, mode);
|
||||
#endif
|
||||
|
||||
if (rv != 0)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unable to set mode %o on '%s', errno %d : %s", mode, path, errno, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
132
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_comparefiles.c
vendored
Normal file
132
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_comparefiles.c
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* \file os_comparefiles.c
|
||||
* \brief Check if two files are identical.
|
||||
* \author Copyright (c) 2015 Jérôme "Lynix" Leclercq and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
|
||||
int os_comparefiles(lua_State* L)
|
||||
{
|
||||
FILE* firstFile;
|
||||
FILE* secondFile;
|
||||
size_t firstSize;
|
||||
size_t secondSize;
|
||||
size_t count;
|
||||
size_t read;
|
||||
char firstBuffer[4096];
|
||||
char secondBuffer[4096];
|
||||
const char* firstPath = luaL_checkstring(L, 1);
|
||||
const char* secondPath = luaL_checkstring(L, 2);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_firstPath[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, firstPath, -1, wide_firstPath, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "unable to encode first path");
|
||||
return 2;
|
||||
}
|
||||
|
||||
wchar_t wide_secondPath[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, secondPath, -1, wide_secondPath, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "unable to encode second path");
|
||||
return 2;
|
||||
}
|
||||
|
||||
firstFile = _wfopen(wide_firstPath, L"rb");
|
||||
secondFile = _wfopen(wide_secondPath, L"rb");
|
||||
#else
|
||||
firstFile = fopen(firstPath, "rb");
|
||||
secondFile = fopen(secondPath, "rb");
|
||||
#endif
|
||||
|
||||
if (!firstFile)
|
||||
{
|
||||
if (secondFile)
|
||||
fclose(secondFile);
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "failed to open first file");
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
if (!secondFile)
|
||||
{
|
||||
fclose(firstFile);
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "failed to open second file");
|
||||
return 2;
|
||||
}
|
||||
|
||||
// check sizes.
|
||||
fseek(firstFile, 0, SEEK_END);
|
||||
firstSize = ftell(firstFile);
|
||||
fseek(firstFile, 0, SEEK_SET);
|
||||
|
||||
fseek(secondFile, 0, SEEK_END);
|
||||
secondSize = ftell(secondFile);
|
||||
fseek(secondFile, 0, SEEK_SET);
|
||||
|
||||
if (firstSize != secondSize)
|
||||
{
|
||||
fclose(firstFile);
|
||||
fclose(secondFile);
|
||||
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// compare file content
|
||||
while (firstSize > 0)
|
||||
{
|
||||
count = firstSize > 4096 ? 4096 : firstSize;
|
||||
|
||||
read = fread(firstBuffer, 1, count, firstFile);
|
||||
if (read != count)
|
||||
{
|
||||
fclose(firstFile);
|
||||
fclose(secondFile);
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "failed to read first file content");
|
||||
return 2;
|
||||
}
|
||||
|
||||
read = fread(secondBuffer, 1, count, secondFile);
|
||||
if (read != count)
|
||||
{
|
||||
fclose(firstFile);
|
||||
fclose(secondFile);
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "failed to read second file content");
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (memcmp(firstBuffer, secondBuffer, count) != 0)
|
||||
{
|
||||
fclose(firstFile);
|
||||
fclose(secondFile);
|
||||
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
firstSize -= count;
|
||||
}
|
||||
|
||||
// File content match
|
||||
fclose(firstFile);
|
||||
fclose(secondFile);
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
56
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_compile.c
vendored
Normal file
56
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_compile.c
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* \file os_compile.c
|
||||
* \brief Compile lua source.
|
||||
* \author Copyright (c) 2002-2012 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "lundump.h"
|
||||
#include "lstate.h"
|
||||
|
||||
extern int original_luaL_loadfilex(lua_State* L, const char* filename, const char* mode);
|
||||
|
||||
static int writer(lua_State* L, const void* p, size_t size, void* u)
|
||||
{
|
||||
UNUSED(L);
|
||||
return (fwrite(p, size, 1, (FILE*)u) != 1) && (size != 0);
|
||||
}
|
||||
|
||||
int os_compile(lua_State* L)
|
||||
{
|
||||
const char* input = luaL_checkstring(L, 1);
|
||||
const char* output = luaL_checkstring(L, 2);
|
||||
lua_State* P = luaL_newstate();
|
||||
|
||||
if (original_luaL_loadfilex(P, input, NULL) != LUA_OK)
|
||||
{
|
||||
const char* msg = lua_tostring(P, -1);
|
||||
if (msg == NULL)
|
||||
msg = "(error with no message)";
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "Unable to compile '%s': %s", input, msg);
|
||||
|
||||
lua_close(P);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE* outputFile = (output == NULL) ? stdout : fopen(output, "wb");
|
||||
if (outputFile == NULL)
|
||||
{
|
||||
lua_close(P);
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unable to write to '%s'", output);
|
||||
return 2;
|
||||
}
|
||||
|
||||
lua_dump(P, writer, outputFile, FALSE);
|
||||
fclose(outputFile);
|
||||
|
||||
lua_close(P);
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
60
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_copyfile.c
vendored
Normal file
60
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_copyfile.c
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* \file os_copyfile.c
|
||||
* \brief Copy a file from one location to another.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
|
||||
int os_copyfile(lua_State* L)
|
||||
{
|
||||
int z;
|
||||
const char* src = luaL_checkstring(L, 1);
|
||||
const char* dst = luaL_checkstring(L, 2);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_src[PATH_MAX];
|
||||
wchar_t wide_dst[PATH_MAX];
|
||||
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, src, -1, wide_src, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode source path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, dst, -1, wide_dst, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode source path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
z = CopyFileW(wide_src, wide_dst, FALSE);
|
||||
#else
|
||||
lua_pushfstring(L, "cp \"%s\" \"%s\"", src, dst);
|
||||
z = (system(lua_tostring(L, -1)) == 0);
|
||||
#endif
|
||||
|
||||
if (!z)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t buf[256];
|
||||
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
|
||||
|
||||
char bufA[256];
|
||||
WideCharToMultiByte(CP_UTF8, 0, buf, 256, bufA, 256, 0, 0);
|
||||
|
||||
lua_pushfstring(L, "unable to copy file to '%s', reason: '%s'", dst, bufA);
|
||||
#else
|
||||
lua_pushfstring(L, "unable to copy file to '%s'", dst);
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
144
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getWindowsRegistry.c
vendored
Normal file
144
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getWindowsRegistry.c
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* \file os_reg.c
|
||||
* \brief Returns true if the given file exists on the file system.
|
||||
* \author Copyright (c) 2002-2016 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
typedef struct RegKeyInfo
|
||||
{
|
||||
HKEY key;
|
||||
HKEY subkey;
|
||||
char * value;
|
||||
} RegKeyInfo;
|
||||
|
||||
HKEY getRegistryKey(const char **path)
|
||||
{
|
||||
if (_strnicmp(*path, "HKCU:", 5) == 0) {
|
||||
*path += 5;
|
||||
return HKEY_CURRENT_USER;
|
||||
}
|
||||
if (_strnicmp(*path, "HKLM:", 5) == 0) {
|
||||
*path += 5;
|
||||
return HKEY_LOCAL_MACHINE;
|
||||
}
|
||||
if (_strnicmp(*path, "HKCR:", 5) == 0) {
|
||||
*path += 5;
|
||||
return HKEY_CLASSES_ROOT;
|
||||
}
|
||||
if (_strnicmp(*path, "HKU:", 4) == 0) {
|
||||
*path += 4;
|
||||
return HKEY_USERS;
|
||||
}
|
||||
if (_strnicmp(*path, "HKCC:", 5) == 0) {
|
||||
*path += 5;
|
||||
return HKEY_CURRENT_CONFIG;
|
||||
}
|
||||
|
||||
// unsupported or invalid key prefix
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HKEY getSubkey(HKEY key, const char **path)
|
||||
{
|
||||
HKEY subkey;
|
||||
size_t length;
|
||||
char *subpath;
|
||||
const char *value;
|
||||
char hasValue;
|
||||
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
// skip the initial path separator
|
||||
if ((*path)[0] == '\\')
|
||||
(*path)++;
|
||||
|
||||
// make a copy of the subkey path that excludes the value name (if present)
|
||||
value = strrchr(*path, '\\');
|
||||
hasValue = value ? value[1] : 0;
|
||||
if (hasValue) {
|
||||
length = (size_t)(value - *path);
|
||||
subpath = (char *)malloc(length + 1);
|
||||
strncpy(subpath, *path, length);
|
||||
subpath[length] = 0;
|
||||
}
|
||||
// no value separator means we should check the default value
|
||||
else {
|
||||
subpath = (char *)*path;
|
||||
length = strlen(subpath);
|
||||
}
|
||||
|
||||
// open the key for reading
|
||||
if (RegOpenKeyExA(key, subpath, 0, KEY_READ, &subkey) != ERROR_SUCCESS)
|
||||
subkey = NULL;
|
||||
|
||||
// free the subpath if one was allocated
|
||||
if (hasValue)
|
||||
free(subpath);
|
||||
|
||||
*path += length;
|
||||
return subkey;
|
||||
}
|
||||
|
||||
static char * getValue(HKEY key, const char * name)
|
||||
{
|
||||
DWORD length;
|
||||
char * value;
|
||||
|
||||
if (key == NULL || name == NULL)
|
||||
return NULL;
|
||||
|
||||
// skip the initial path separator
|
||||
if (name[0] == '\\')
|
||||
name++;
|
||||
|
||||
// query length of value
|
||||
if (RegQueryValueExA(key, name, NULL, NULL, NULL, &length) != ERROR_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
// allocate room for the value and fetch it
|
||||
value = (char *)malloc((size_t)length + 1);
|
||||
if (RegQueryValueExA(key, name, NULL, NULL, (LPBYTE)value, &length) != ERROR_SUCCESS) {
|
||||
free(value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value[length] = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void fetchKeyInfo(struct RegKeyInfo *info, const char *path)
|
||||
{
|
||||
info->key = getRegistryKey(&path);
|
||||
info->subkey = getSubkey(info->key, &path);
|
||||
info->value = getValue(info->subkey, path);
|
||||
}
|
||||
|
||||
static void releaseKeyInfo(struct RegKeyInfo *info)
|
||||
{
|
||||
free(info->value);
|
||||
RegCloseKey(info->subkey);
|
||||
}
|
||||
|
||||
int os_getWindowsRegistry(lua_State *L)
|
||||
{
|
||||
RegKeyInfo info;
|
||||
fetchKeyInfo(&info, luaL_checkstring(L, 1));
|
||||
lua_pushstring(L, info.value);
|
||||
releaseKeyInfo(&info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int os_getWindowsRegistry(lua_State *L)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
40
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getcwd.c
vendored
Normal file
40
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getcwd.c
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* \file os_getcwd.c
|
||||
* \brief Retrieve the current working directory.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
int os_getcwd(lua_State* L)
|
||||
{
|
||||
char buffer[0x4000];
|
||||
if (do_getcwd(buffer, 0x4000)) {
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int do_getcwd(char* buffer, size_t size)
|
||||
{
|
||||
int result;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wbuffer[PATH_MAX];
|
||||
|
||||
result = (GetCurrentDirectoryW(PATH_MAX, wbuffer) != 0);
|
||||
if (result) {
|
||||
WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, (int)size, NULL, NULL);
|
||||
|
||||
do_translate(buffer, '/');
|
||||
}
|
||||
#else
|
||||
result = (getcwd(buffer, size) != 0);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
38
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getpass.c
vendored
Normal file
38
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getpass.c
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* \file os_getpass.c
|
||||
* \brief Prompt and retrieve a password from the user.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int os_getpass(lua_State* L)
|
||||
{
|
||||
const char* prompt = luaL_checkstring(L, 1);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD read_chars, mode, written_chars;
|
||||
char buffer[1024];
|
||||
const char* newline = "\n";
|
||||
|
||||
WriteConsoleA(hstdout, prompt, (DWORD)strlen(prompt), &written_chars, NULL);
|
||||
|
||||
GetConsoleMode(hstdin, &mode);
|
||||
SetConsoleMode(hstdin, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||
ReadConsoleA(hstdin, buffer, sizeof (buffer), &read_chars, NULL);
|
||||
SetConsoleMode(hstdin, mode);
|
||||
|
||||
WriteConsoleA(hstdout, newline, (DWORD)strlen(newline), &written_chars, NULL);
|
||||
|
||||
buffer[strcspn(buffer, "\r\n")] = '\0';
|
||||
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
#else
|
||||
lua_pushstring(L, getpass(prompt));
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
332
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getversion.c
vendored
Normal file
332
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_getversion.c
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* \file os_getversioninfo.c
|
||||
* \brief Retrieve operating system version information.
|
||||
* \author Copyright (c) 2011-2012 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
struct OsVersionInfo
|
||||
{
|
||||
int majorversion;
|
||||
int minorversion;
|
||||
int revision;
|
||||
const char* description;
|
||||
int isalloc;
|
||||
};
|
||||
|
||||
static int getversion(struct OsVersionInfo* info);
|
||||
|
||||
int os_getversion(lua_State* L)
|
||||
{
|
||||
struct OsVersionInfo info = {0, 0, 0, NULL, 0};
|
||||
if (!getversion(&info))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L, "majorversion");
|
||||
lua_pushnumber(L, (lua_Number)info.majorversion);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "minorversion");
|
||||
lua_pushnumber(L, (lua_Number)info.minorversion);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "revision");
|
||||
lua_pushnumber(L, (lua_Number)info.revision);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "description");
|
||||
lua_pushstring(L, info.description);
|
||||
lua_settable(L, -3);
|
||||
|
||||
if (info.isalloc) {
|
||||
free((void*)info.description);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "version.lib")
|
||||
#endif
|
||||
|
||||
int getKernelVersion(struct OsVersionInfo* info)
|
||||
{
|
||||
DWORD size = GetFileVersionInfoSizeA("kernel32.dll", NULL);
|
||||
if (size > 0)
|
||||
{
|
||||
void* data = malloc(size);
|
||||
if (GetFileVersionInfoA("kernel32.dll", 0, size, data))
|
||||
{
|
||||
void* fixedInfoPtr;
|
||||
UINT fixedInfoSize;
|
||||
if (VerQueryValueA(data, "\\", &fixedInfoPtr, &fixedInfoSize))
|
||||
{
|
||||
VS_FIXEDFILEINFO* fileInfo = (VS_FIXEDFILEINFO*)fixedInfoPtr;
|
||||
info->majorversion = HIWORD(fileInfo->dwProductVersionMS);
|
||||
info->minorversion = LOWORD(fileInfo->dwProductVersionMS);
|
||||
info->revision = HIWORD(fileInfo->dwProductVersionLS);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int getversion(struct OsVersionInfo* info)
|
||||
{
|
||||
HKEY key;
|
||||
info->description = "Windows";
|
||||
|
||||
// First get a friendly product name from the registry.
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &key) == ERROR_SUCCESS)
|
||||
{
|
||||
char value[512];
|
||||
DWORD value_length = sizeof(value);
|
||||
DWORD type;
|
||||
RegQueryValueExA(key, "productName", NULL, &type, (LPBYTE)value, &value_length);
|
||||
RegCloseKey(key);
|
||||
if (type == REG_SZ)
|
||||
{
|
||||
info->description = strdup(value);
|
||||
info->isalloc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// See if we can get a product version number from kernel32.dll
|
||||
return getKernelVersion(info);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int getversion(struct OsVersionInfo* info)
|
||||
{
|
||||
const char * propertyListFilePath = "/System/Library/CoreServices/SystemVersion.plist";
|
||||
Boolean fallback = TRUE;
|
||||
|
||||
info->description = "Mac OS";
|
||||
info->majorversion = 10;
|
||||
|
||||
if (access (propertyListFilePath, R_OK) == 0)
|
||||
{
|
||||
CFPropertyListFormat format;
|
||||
CFErrorRef errorDescriptor = NULL;
|
||||
CFStringRef stringRef = NULL;
|
||||
CFURLRef urlRef = NULL;
|
||||
CFReadStreamRef streamRef = NULL;
|
||||
CFPropertyListRef propertyListRef = NULL;
|
||||
CFTypeID typeId = 0;
|
||||
Boolean result = FALSE;
|
||||
|
||||
stringRef = CFStringCreateWithCStringNoCopy(
|
||||
kCFAllocatorDefault,
|
||||
propertyListFilePath,
|
||||
kCFStringEncodingASCII,
|
||||
kCFAllocatorNull);
|
||||
if (stringRef == NULL)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
};
|
||||
|
||||
urlRef = CFURLCreateWithFileSystemPath(
|
||||
kCFAllocatorDefault,
|
||||
stringRef,
|
||||
kCFURLPOSIXPathStyle,
|
||||
false);
|
||||
if (urlRef == NULL)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
streamRef = CFReadStreamCreateWithFile(
|
||||
kCFAllocatorDefault,
|
||||
urlRef);
|
||||
if (streamRef == NULL)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
result = CFReadStreamOpen (streamRef);
|
||||
|
||||
if (result == FALSE)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
propertyListRef = CFPropertyListCreateWithStream(
|
||||
kCFAllocatorDefault,
|
||||
streamRef,
|
||||
0,
|
||||
kCFPropertyListImmutable,
|
||||
&format,
|
||||
&errorDescriptor);
|
||||
|
||||
CFReadStreamClose (streamRef);
|
||||
|
||||
if (!(propertyListRef && CFPropertyListIsValid(propertyListRef, format)) || errorDescriptor)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
typeId = CFGetTypeID(propertyListRef);
|
||||
if (typeId == CFDictionaryGetTypeID())
|
||||
{
|
||||
const CFDictionaryRef dictionaryRef = (const CFDictionaryRef)propertyListRef;
|
||||
char versionString[128];
|
||||
CFStringRef stringValueRef = NULL;
|
||||
if (CFDictionaryGetValueIfPresent(dictionaryRef, CFSTR("ProductVersion"), (const void **)(&stringValueRef)))
|
||||
{
|
||||
CFStringGetCString(stringValueRef, &versionString[0], (CFIndex)sizeof (versionString), kCFStringEncodingASCII);
|
||||
sscanf (versionString, "%d.%d.%d", &info->majorversion, &info->minorversion, &info->revision);
|
||||
|
||||
fallback = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
getversion_macosx_cleanup:
|
||||
|
||||
if (propertyListRef) CFRelease (propertyListRef);
|
||||
if (streamRef) CFRelease (streamRef);
|
||||
if (urlRef) CFRelease (urlRef);
|
||||
if (stringRef) CFRelease (stringRef);
|
||||
}
|
||||
|
||||
if (fallback == TRUE)
|
||||
{
|
||||
int mib[] = { CTL_KERN, KERN_OSRELEASE };
|
||||
size_t len;
|
||||
sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0);
|
||||
|
||||
char kernel_version[len];
|
||||
sysctl(mib, sizeof(mib) / sizeof(mib[0]), kernel_version, &len, NULL, 0);
|
||||
|
||||
int kern_major;
|
||||
int kern_minor;
|
||||
sscanf(kernel_version, "%d.%d.%*d", &kern_major, &kern_minor);
|
||||
|
||||
info->minorversion = kern_major - 4;
|
||||
info->revision = kern_minor;
|
||||
}
|
||||
|
||||
if (info->majorversion == 10)
|
||||
{
|
||||
switch (info->minorversion)
|
||||
{
|
||||
case 4:
|
||||
info->description = "Mac OS X Tiger";
|
||||
break;
|
||||
case 5:
|
||||
info->description = "Mac OS X Leopard";
|
||||
break;
|
||||
case 6:
|
||||
info->description = "Mac OS X Snow Leopard";
|
||||
break;
|
||||
case 7:
|
||||
info->description = "OS X Lion";
|
||||
break;
|
||||
case 8:
|
||||
info->description = "OS X Mountain Lion";
|
||||
break;
|
||||
case 9:
|
||||
info->description = "OS X Mavericks";
|
||||
case 10:
|
||||
info->description = "OS X Yosemite";
|
||||
case 11:
|
||||
info->description = "OS X El Capitan";
|
||||
break;
|
||||
case 12:
|
||||
info->description = "macOS Sierra";
|
||||
break;
|
||||
case 13:
|
||||
info->description = "macOS High Sierra";
|
||||
break;
|
||||
case 14:
|
||||
info->description = "macOS Mojave";
|
||||
break;
|
||||
case 15:
|
||||
info->description = "macOS Catalina";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#elif defined(PLATFORM_BSD) || defined(PLATFORM_LINUX) || defined(PLATFORM_SOLARIS) || defined(PLATFORM_HURD) || defined(PLATFORM_HAIKU)
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
int getversion(struct OsVersionInfo* info)
|
||||
{
|
||||
struct utsname u;
|
||||
char* ver;
|
||||
|
||||
info->majorversion = 0;
|
||||
info->minorversion = 0;
|
||||
info->revision = 0;
|
||||
|
||||
if (uname(&u))
|
||||
{
|
||||
// error
|
||||
info->description = PLATFORM_STRING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __GLIBC__
|
||||
// When using glibc, info->description gets set to u.sysname,
|
||||
// but it isn't passed out of this function, so we need to copy
|
||||
// the string.
|
||||
info->description = malloc(strlen(u.sysname) + 1);
|
||||
strcpy((char*)info->description, u.sysname);
|
||||
info->isalloc = 1;
|
||||
#else
|
||||
info->description = u.sysname;
|
||||
#endif
|
||||
|
||||
if ((ver = strtok(u.release, ".-")) != NULL)
|
||||
{
|
||||
info->majorversion = atoi(ver);
|
||||
// continue parsing from the previous position
|
||||
if ((ver = strtok(NULL, ".-")) != NULL)
|
||||
{
|
||||
info->minorversion = atoi(ver);
|
||||
if ((ver = strtok(NULL, ".-")) != NULL)
|
||||
info->revision = atoi(ver);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#else
|
||||
|
||||
int getversion(struct OsVersionInfo* info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
13
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_host.c
vendored
Normal file
13
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_host.c
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* \file os_host.c
|
||||
* \brief Get the current host OS we're executing on.
|
||||
* \author Copyright (c) 2014-2017 Tom van Dijck, Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
int os_host(lua_State* L)
|
||||
{
|
||||
lua_pushstring(L, PLATFORM_STRING);
|
||||
return 1;
|
||||
}
|
||||
30
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_is64bit.c
vendored
Normal file
30
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_is64bit.c
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* \file os_is64bit.c
|
||||
* \brief Native code-side checking for a 64-bit architecture.
|
||||
* \author Copyright (c) 2011 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
int os_is64bit(lua_State* L)
|
||||
{
|
||||
// If this code returns true, then the platform is 64-bit. If it
|
||||
// returns false, the platform might still be 64-bit, but more
|
||||
// checking will need to be done on the Lua side of things.
|
||||
#if PLATFORM_WINDOWS
|
||||
typedef BOOL (WINAPI* WowFuncSig)(HANDLE, PBOOL);
|
||||
WowFuncSig func = (WowFuncSig)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
|
||||
if (func)
|
||||
{
|
||||
BOOL isWow = FALSE;
|
||||
if (func(GetCurrentProcess(), &isWow))
|
||||
{
|
||||
lua_pushboolean(L, isWow);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
56
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_isdir.c
vendored
Normal file
56
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_isdir.c
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* \file os_isdir.c
|
||||
* \brief Returns true if the specified directory exists.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include "premake.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
int os_isdir(lua_State* L)
|
||||
{
|
||||
struct stat buf;
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
#ifdef _WIN32
|
||||
DWORD attr;
|
||||
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode path");
|
||||
return lua_error(L);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* empty path is equivalent to ".", must be true */
|
||||
if (strlen(path) == 0)
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
// Use Windows-specific GetFileAttributes since it deals with symbolic links.
|
||||
else if ((attr = GetFileAttributesW(wide_path)) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
int isdir = (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
lua_pushboolean(L, isdir);
|
||||
}
|
||||
#endif
|
||||
else if (stat(path, &buf) == 0)
|
||||
{
|
||||
int isdir = (buf.st_mode & S_IFDIR) != 0;
|
||||
lua_pushboolean(L, isdir);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
48
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_isfile.c
vendored
Normal file
48
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_isfile.c
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* \file os_isfile.c
|
||||
* \brief Returns true if the given file exists on the file system.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int os_isfile(lua_State* L)
|
||||
{
|
||||
const char* filename = luaL_checkstring(L, 1);
|
||||
lua_pushboolean(L, do_isfile(L, filename));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int do_isfile(lua_State* L, const char* filename)
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
DWORD attrib;
|
||||
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, wide_path, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode filepath");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
attrib = GetFileAttributesW(wide_path);
|
||||
if (attrib != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
return (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
}
|
||||
#else
|
||||
struct stat buf;
|
||||
|
||||
(void)(L); /* warning: unused parameter */
|
||||
|
||||
if (stat(filename, &buf) == 0)
|
||||
{
|
||||
return ((buf.st_mode & S_IFDIR) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_islink.c
vendored
Normal file
43
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_islink.c
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* \file os_islink.c
|
||||
* \brief Returns true if the given path is a symbolic link or reparse point.
|
||||
* \author Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int os_islink(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
{
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
DWORD attr;
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
attr = GetFileAttributesW(wide_path);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES) {
|
||||
lua_pushboolean(L, (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
struct stat buf;
|
||||
if (lstat(path, &buf) == 0) {
|
||||
lua_pushboolean(L, S_ISLNK(buf.st_mode));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
252
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_listWindowsRegistry.c
vendored
Normal file
252
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_listWindowsRegistry.c
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
/**
|
||||
* \file os_reg.c
|
||||
* \brief Returns true if the given file exists on the file system.
|
||||
* \author Copyright (c) 2002-2016 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
typedef struct RegNodeInfo
|
||||
{
|
||||
const char * name;
|
||||
const char * value;
|
||||
DWORD valueSize;
|
||||
DWORD type;
|
||||
} RegNodeInfo;
|
||||
|
||||
typedef void (*ListCallback)(const RegNodeInfo * info, void * user);
|
||||
extern HKEY getRegistryKey(const char** path);
|
||||
|
||||
static const char* getTypeString(DWORD type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case REG_NONE: return "REG_NONE";
|
||||
case REG_SZ: return "REG_SZ";
|
||||
case REG_EXPAND_SZ: return "REG_EXPAND_SZ";
|
||||
case REG_BINARY: return "REG_BINARY";
|
||||
case REG_DWORD: return "REG_DWORD";
|
||||
case REG_DWORD_BIG_ENDIAN: return "REG_DWORD_BIG_ENDIAN";
|
||||
case REG_LINK: return "REG_LINK";
|
||||
case REG_MULTI_SZ: return "REG_MULTI_SZ";
|
||||
case REG_RESOURCE_LIST: return "REG_RESOURCE_LIST";
|
||||
case REG_FULL_RESOURCE_DESCRIPTOR: return "REG_FULL_RESOURCE_DESCRIPTOR";
|
||||
case REG_RESOURCE_REQUIREMENTS_LIST: return "REG_RESOURCE_REQUIREMENTS_LIST";
|
||||
case REG_QWORD: return "REG_QWORD";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static HKEY openKey(const char *path)
|
||||
{
|
||||
HKEY key, subkey;
|
||||
|
||||
// check string
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
|
||||
// get HKEY
|
||||
key = getRegistryKey(&path);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
// skip the initial path separator
|
||||
if (path[0] == '\\')
|
||||
path++;
|
||||
|
||||
// open the key for reading
|
||||
if (RegOpenKeyExA(key, path, 0, KEY_READ, &subkey) != ERROR_SUCCESS)
|
||||
subkey = NULL;
|
||||
|
||||
return subkey;
|
||||
}
|
||||
|
||||
static int listNodes(HKEY key, ListCallback callback, void * user)
|
||||
{
|
||||
RegNodeInfo node;
|
||||
DWORD maxSubkeyLength;
|
||||
DWORD maxValueLength;
|
||||
DWORD maxNameLength;
|
||||
DWORD numSubkeys;
|
||||
DWORD numValues;
|
||||
DWORD length;
|
||||
DWORD index;
|
||||
char* name;
|
||||
char* value;
|
||||
int ok;
|
||||
|
||||
if (key == NULL || callback == NULL)
|
||||
return 0;
|
||||
|
||||
// Initialize node structure
|
||||
node.value = NULL;
|
||||
node.valueSize = 0;
|
||||
node.type = REG_NONE;
|
||||
|
||||
// Fetch info about key content
|
||||
if (RegQueryInfoKeyA(key, NULL, NULL, NULL, &numSubkeys, &maxSubkeyLength, NULL, &numValues, &maxNameLength, &maxValueLength, NULL, NULL) != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
// Allocate name and value buffers
|
||||
if (maxSubkeyLength > maxNameLength)
|
||||
maxNameLength = maxSubkeyLength;
|
||||
|
||||
maxNameLength++;
|
||||
maxValueLength++;
|
||||
name = (char*)malloc((size_t)maxNameLength);
|
||||
value = (char*)malloc((size_t)maxValueLength + 1);
|
||||
|
||||
// Iterate over subkeys
|
||||
ok = 1;
|
||||
node.name = name;
|
||||
for (index = 0; index < numSubkeys; index++) {
|
||||
length = maxNameLength;
|
||||
if (RegEnumKeyExA(key, index, name, &length, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
callback(&node, user);
|
||||
}
|
||||
|
||||
// Iterate over values
|
||||
if (ok) {
|
||||
node.value = value;
|
||||
for (index = 0; index < numValues; index++) {
|
||||
length = maxNameLength;
|
||||
node.valueSize = maxValueLength;
|
||||
if (RegEnumValueA(key, index, name, &length, NULL, &node.type, (LPBYTE)value, &node.valueSize) != ERROR_SUCCESS) {
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Ensure proper termination of strings (two terminators for the REG_MULTI_SZ)
|
||||
value[node.valueSize] = '\0';
|
||||
value[node.valueSize + 1] = '\0';
|
||||
callback(&node, user);
|
||||
}
|
||||
}
|
||||
|
||||
// Free buffers
|
||||
free(name);
|
||||
free(value);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void listCallback(const RegNodeInfo* info, void* user)
|
||||
{
|
||||
lua_State* L = (lua_State*)user;
|
||||
const char* typeString;
|
||||
|
||||
// Insert key into the result table (keys are represented as empty tables)
|
||||
if (info->value == NULL) {
|
||||
lua_createtable(L, 0, 0);
|
||||
lua_setfield(L, -2, info->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// Values are represented as tables containing "type" and "value" records
|
||||
typeString = getTypeString(info->type);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushstring(L, typeString ? typeString : "Unknown");
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
switch (info->type)
|
||||
{
|
||||
// Binary encoded values -> size defined string
|
||||
case REG_NONE:
|
||||
case REG_BINARY:
|
||||
case REG_RESOURCE_LIST:
|
||||
case REG_FULL_RESOURCE_DESCRIPTOR:
|
||||
case REG_RESOURCE_REQUIREMENTS_LIST: {
|
||||
lua_pushlstring(L, info->value, info->valueSize);
|
||||
break;
|
||||
}
|
||||
|
||||
// String encoded values -> zero terminated string
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ:
|
||||
case REG_LINK: {
|
||||
lua_pushstring(L, info->value);
|
||||
break;
|
||||
}
|
||||
|
||||
// Numbers
|
||||
case REG_DWORD: {
|
||||
lua_pushinteger(L, *(DWORD32*)info->value);
|
||||
break;
|
||||
}
|
||||
|
||||
case REG_DWORD_BIG_ENDIAN: {
|
||||
lua_pushinteger(L, (info->value[3] << 0) | (info->value[2] << 8) | (info->value[1] << 16) | (info->value[0] << 24));
|
||||
break;
|
||||
}
|
||||
|
||||
case REG_QWORD: {
|
||||
lua_pushinteger(L, *(DWORD64*)info->value);
|
||||
break;
|
||||
}
|
||||
|
||||
// Multiple strings
|
||||
case REG_MULTI_SZ: {
|
||||
DWORD i, j, k;
|
||||
|
||||
lua_newtable(L);
|
||||
for (i = j = 0, k = 1; i < info->valueSize; i++)
|
||||
{
|
||||
if (info->value[i] != 0)
|
||||
continue;
|
||||
|
||||
if (i == j)
|
||||
break;
|
||||
|
||||
lua_pushlstring(L, &info->value[j], i - j);
|
||||
lua_rawseti(L, -2, k);
|
||||
j = i + 1;
|
||||
k++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Unknown field -> nil
|
||||
default: {
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lua_setfield(L, -2, "value");
|
||||
|
||||
// Complete the value subtable
|
||||
lua_setfield(L, -2, info->name);
|
||||
}
|
||||
|
||||
int os_listWindowsRegistry(lua_State* L)
|
||||
{
|
||||
HKEY key = openKey(luaL_checkstring(L, 1));
|
||||
if (key == NULL) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
if (!listNodes(key, listCallback, (void *)L)) {
|
||||
// Discard table in case of fault and push nil instead
|
||||
lua_pop(L, 1);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int os_listWindowsRegistry(lua_State* L)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
68
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_locate.c
vendored
Normal file
68
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_locate.c
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* \file os_locate.c
|
||||
* \brief Locates files along the standard built-in search paths.
|
||||
* \author Copyright (c) 2014-2015 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int do_locate(lua_State* L, const char* filename, const char* path)
|
||||
{
|
||||
if (do_pathsearch(L, filename, path)) {
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int os_locate(lua_State* L)
|
||||
{
|
||||
const char* path;
|
||||
int i;
|
||||
int nArgs = lua_gettop(L);
|
||||
|
||||
/* Fetch premake.path */
|
||||
lua_getglobal(L, "premake");
|
||||
lua_getfield(L, -1, "path");
|
||||
path = lua_tostring(L, -1);
|
||||
|
||||
for (i = 1; i <= nArgs; ++i) {
|
||||
const char* name = lua_tostring(L, i);
|
||||
|
||||
/* Direct path to an embedded file? */
|
||||
if (name[0] == '$' && name[1] == '/' && premake_find_embedded_script(name + 2)) {
|
||||
lua_pushvalue(L, i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Direct path to file? Return as absolute path */
|
||||
if (do_isfile(L, name)) {
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushvalue(L, i);
|
||||
lua_call(L, 1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do_locate(arg[i], premake.path) */
|
||||
if (do_locate(L, name, path)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* embedded in the executable? */
|
||||
if (premake_find_embedded_script(name)) {
|
||||
lua_pushstring(L, "$/");
|
||||
lua_pushvalue(L, i);
|
||||
lua_concat(L, 2);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
207
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_match.c
vendored
Normal file
207
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_match.c
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* \file os_match.c
|
||||
* \brief Match files and directories.
|
||||
* \author Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
typedef struct struct_MatchInfo
|
||||
{
|
||||
HANDLE handle;
|
||||
int is_first;
|
||||
WIN32_FIND_DATAW entry;
|
||||
} MatchInfo;
|
||||
|
||||
int os_matchstart(lua_State* L)
|
||||
{
|
||||
const char* mask = luaL_checkstring(L, 1);
|
||||
MatchInfo* m;
|
||||
|
||||
wchar_t wide_mask[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, mask, -1, wide_mask, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode mask");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
m = (MatchInfo*)malloc(sizeof(MatchInfo));
|
||||
|
||||
m->handle = FindFirstFileW(wide_mask, &m->entry);
|
||||
m->is_first = 1;
|
||||
lua_pushlightuserdata(L, m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int os_matchdone(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
if (m->handle != INVALID_HANDLE_VALUE)
|
||||
FindClose(m->handle);
|
||||
free(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int os_matchname(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
|
||||
char filename[PATH_MAX];
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, m->entry.cFileName, -1, filename, PATH_MAX, NULL, NULL) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to decode filename");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
lua_pushstring(L, filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int os_matchisfile(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
lua_pushboolean(L, (m->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int os_matchnext(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
if (m->handle == INVALID_HANDLE_VALUE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (m) /* loop forever */
|
||||
{
|
||||
if (m->is_first)
|
||||
m->is_first = 0;
|
||||
else
|
||||
{
|
||||
if (!FindNextFileW(m->handle, &m->entry))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wcscmp(m->entry.cFileName, L".") != 0 && wcscmp(m->entry.cFileName, L"..") != 0)
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fnmatch.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef struct struct_MatchInfo
|
||||
{
|
||||
DIR* handle;
|
||||
struct dirent* entry;
|
||||
char* path;
|
||||
char* mask;
|
||||
} MatchInfo;
|
||||
|
||||
int os_matchstart(lua_State* L)
|
||||
{
|
||||
const char* split;
|
||||
const char* mask = luaL_checkstring(L, 1);
|
||||
MatchInfo* m = (MatchInfo*)malloc(sizeof(MatchInfo));
|
||||
|
||||
/* split the mask into path and filename components */
|
||||
split = strrchr(mask, '/');
|
||||
if (split)
|
||||
{
|
||||
m->path = (char*)malloc(split - mask + 1);
|
||||
strncpy(m->path, mask, split - mask);
|
||||
m->path[split - mask] = '\0';
|
||||
m->mask = (char*)malloc(mask + strlen(mask) - split);
|
||||
strcpy(m->mask, split + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->path = (char*)malloc(2);
|
||||
strcpy(m->path, ".");
|
||||
m->mask = (char*)malloc(strlen(mask)+1);
|
||||
strcpy(m->mask, mask);
|
||||
}
|
||||
|
||||
m->handle = opendir(m->path);
|
||||
lua_pushlightuserdata(L, m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int os_matchdone(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
if (m->handle != NULL)
|
||||
closedir(m->handle);
|
||||
free(m->path);
|
||||
free(m->mask);
|
||||
free(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int os_matchname(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
lua_pushstring(L, m->entry->d_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int os_matchisfile(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
#if defined(_DIRENT_HAVE_D_TYPE)
|
||||
// Dirent marks symlinks as DT_LNK, not (DT_LNK|DT_DIR). The fallback handles symlinks using stat.
|
||||
if (m->entry->d_type == DT_DIR)
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const char* fname;
|
||||
lua_pushfstring(L, "%s/%s", m->path, m->entry->d_name);
|
||||
fname = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushboolean(L, do_isfile(L, fname));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int os_matchnext(lua_State* L)
|
||||
{
|
||||
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
|
||||
if (m->handle == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
m->entry = readdir(m->handle);
|
||||
while (m->entry != NULL)
|
||||
{
|
||||
const char* name = m->entry->d_name;
|
||||
if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0)
|
||||
{
|
||||
if (fnmatch(m->mask, name, 0) == 0)
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
m->entry = readdir(m->handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
78
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_mkdir.c
vendored
Normal file
78
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_mkdir.c
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* \file os_mkdir.c
|
||||
* \brief Create a subdirectory.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include <direct.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
int do_mkdir(const char* path)
|
||||
{
|
||||
struct stat sb;
|
||||
char sub_path[1024];
|
||||
int i, length;
|
||||
|
||||
// if it already exists, return.
|
||||
if (stat(path, &sb) == 0)
|
||||
return 1;
|
||||
|
||||
// find the parent folder name.
|
||||
length = (int)strlen(path);
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (path[i] == '/' || path[i] == '\\')
|
||||
break;
|
||||
}
|
||||
|
||||
// if we found one, create it.
|
||||
if (i > 0)
|
||||
{
|
||||
memcpy(sub_path, path, i);
|
||||
sub_path[i] = '\0';
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
if (sub_path[i - 1] == ':')
|
||||
{
|
||||
sub_path[i + 0] = '/';
|
||||
sub_path[i + 1] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!do_mkdir(sub_path))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now finally create the actual folder we want.
|
||||
#if PLATFORM_WINDOWS
|
||||
return _mkdir(path) == 0;
|
||||
#else
|
||||
return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int os_mkdir(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
|
||||
int z = do_mkdir(path);
|
||||
if (!z)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unable to create directory '%s'", path);
|
||||
return 2;
|
||||
}
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
93
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_pathsearch.c
vendored
Normal file
93
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_pathsearch.c
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* \file os_pathsearch.c
|
||||
* \brief Locates a file, given a set of search paths.
|
||||
* \author Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
*
|
||||
* \note This function is required by the bootstrapping code; it must be
|
||||
* implemented here in the host and not scripted.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int do_pathsearch(lua_State* L, const char* filename, const char* path)
|
||||
{
|
||||
do
|
||||
{
|
||||
const char* split;
|
||||
|
||||
/* look for the closest path separator ; or : */
|
||||
/* can't use : on windows because it breaks on C:\path */
|
||||
const char* semi = strchr(path, ';');
|
||||
#if !defined(PLATFORM_WINDOWS)
|
||||
const char* full = strchr(path, ':');
|
||||
#else
|
||||
const char* full = NULL;
|
||||
#endif
|
||||
|
||||
if (!semi)
|
||||
{
|
||||
split = full;
|
||||
}
|
||||
else if (!full)
|
||||
{
|
||||
split = semi;
|
||||
}
|
||||
else
|
||||
{
|
||||
split = (semi < full) ? semi : full;
|
||||
}
|
||||
|
||||
/* push this piece of the full search string onto the stack */
|
||||
if (split)
|
||||
{
|
||||
lua_pushlstring(L, path, split - path);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, path);
|
||||
}
|
||||
|
||||
/* keep an extra copy around, so I can return it if I have a match */
|
||||
lua_pushvalue(L, -1);
|
||||
|
||||
/* append the filename to make the full test path */
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 3);
|
||||
|
||||
/* test it - if it exists, return the absolute path */
|
||||
if (do_isfile(L, lua_tostring(L, -1)))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_call(L, 1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* no match, set up the next try */
|
||||
lua_pop(L, 2);
|
||||
path = (split) ? split + 1 : NULL;
|
||||
}
|
||||
while (path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int os_pathsearch(lua_State* L)
|
||||
{
|
||||
int i;
|
||||
|
||||
const char* filename = luaL_checkstring(L, 1);
|
||||
for (i = 2; i <= lua_gettop(L); ++i)
|
||||
{
|
||||
if (lua_isnil(L, i)) continue;
|
||||
if (do_pathsearch(L, filename, luaL_checkstring(L, i))) return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
37
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_realpath.c
vendored
Normal file
37
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_realpath.c
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* \file os_realpath.c
|
||||
* \brief Return the canonical absolute version of a given path.
|
||||
* \author Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
int os_realpath(lua_State* L)
|
||||
{
|
||||
char result[PATH_MAX];
|
||||
int ok;
|
||||
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
|
||||
#if PLATFORM_POSIX
|
||||
ok = (realpath(path, result) != NULL);
|
||||
#elif PLATFORM_WINDOWS
|
||||
ok = (_fullpath(result, path, PATH_MAX) != NULL);
|
||||
#else
|
||||
do_getabsolute(result, path, NULL);
|
||||
ok = 1;
|
||||
#endif
|
||||
|
||||
if (!ok) {
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unable to fetch real path of '%s', errno %d : %s", path, errno, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
|
||||
lua_pushstring(L, result);
|
||||
return 1;
|
||||
}
|
||||
51
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_remove.c
vendored
Normal file
51
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_remove.c
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* \file os_remove.c
|
||||
* \brief Remove a file on Windows.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
int os_remove(lua_State* L)
|
||||
{
|
||||
const char* filename = luaL_checkstring(L, 1);
|
||||
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, wide_path, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
if (DeleteFileW(wide_path))
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
|
||||
char unicodeErr[512];
|
||||
|
||||
LPWSTR messageBuffer = NULL;
|
||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &messageBuffer, 0, NULL) != 0)
|
||||
{
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, messageBuffer, -1, unicodeErr, sizeof(unicodeErr), NULL, NULL) == 0)
|
||||
strcpy(unicodeErr, "failed to translate error message");
|
||||
|
||||
LocalFree(messageBuffer);
|
||||
}
|
||||
else
|
||||
strcpy(unicodeErr, "failed to get error message");
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "%s: %s", filename, unicodeErr);
|
||||
lua_pushinteger(L, err);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
59
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_rename.c
vendored
Normal file
59
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_rename.c
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* \file os_rename.c
|
||||
* \brief Rename a path on Windows.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
int os_rename(lua_State* L)
|
||||
{
|
||||
const char *fromname = luaL_checkstring(L, 1);
|
||||
const char *toname = luaL_checkstring(L, 2);
|
||||
|
||||
wchar_t wide_frompath[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, fromname, -1, wide_frompath, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode source path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
wchar_t wide_topath[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, toname, -1, wide_topath, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode dest path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
if (MoveFileExW(wide_frompath, wide_topath, MOVEFILE_COPY_ALLOWED))
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
|
||||
char unicodeErr[512];
|
||||
|
||||
LPWSTR messageBuffer = NULL;
|
||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &messageBuffer, 0, NULL) != 0)
|
||||
{
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, messageBuffer, -1, unicodeErr, sizeof(unicodeErr), NULL, NULL) == 0)
|
||||
strcpy(unicodeErr, "failed to translate error message");
|
||||
|
||||
LocalFree(messageBuffer);
|
||||
}
|
||||
else
|
||||
strcpy(unicodeErr, "failed to get error message");
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "%s: %s", fromname, unicodeErr);
|
||||
lua_pushinteger(L, err);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
40
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_rmdir.c
vendored
Normal file
40
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_rmdir.c
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* \file os_rmdir.c
|
||||
* \brief Remove a subdirectory.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
|
||||
|
||||
int os_rmdir(lua_State* L)
|
||||
{
|
||||
int z;
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
z = RemoveDirectoryW(wide_path);
|
||||
#else
|
||||
z = (0 == rmdir(path));
|
||||
#endif
|
||||
|
||||
if (!z)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, "unable to remove directory '%s'", path);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
60
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_stat.c
vendored
Normal file
60
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_stat.c
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* \file os_stat.c
|
||||
* \brief Retrieve information about a file.
|
||||
* \author Copyright (c) 2011 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
int os_stat(lua_State* L)
|
||||
{
|
||||
const char* filename = luaL_checkstring(L, 1);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
struct _stat s;
|
||||
|
||||
wchar_t wide_filename[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, wide_filename, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushstring(L, "unable to encode source path");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
if (_wstat(wide_filename, &s) != 0)
|
||||
#else
|
||||
struct stat s;
|
||||
|
||||
if (stat(filename, &s) != 0)
|
||||
#endif
|
||||
{
|
||||
lua_pushnil(L);
|
||||
switch (errno)
|
||||
{
|
||||
case EACCES:
|
||||
lua_pushfstring(L, "'%s' could not be accessed", filename);
|
||||
break;
|
||||
case ENOENT:
|
||||
lua_pushfstring(L, "'%s' was not found", filename);
|
||||
break;
|
||||
default:
|
||||
lua_pushfstring(L, "An unknown error %d occured while accessing '%s'", errno, filename);
|
||||
break;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L, "mtime");
|
||||
lua_pushinteger(L, (lua_Integer)s.st_mtime);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "size");
|
||||
lua_pushnumber(L, (lua_Number)s.st_size);
|
||||
lua_settable(L, -3);
|
||||
|
||||
return 1;
|
||||
}
|
||||
146
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_touchfile.c
vendored
Normal file
146
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_touchfile.c
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* \file os_touchfile.c
|
||||
* \brief markes a file as modified without changing its contents.
|
||||
* \author Blizzard Entertainment (contact tvandijck@blizzard.com)
|
||||
* \author Copyright (c) 2015 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
static int truncate_file(const char* fn)
|
||||
{
|
||||
FILE* file = fopen(fn, "rb");
|
||||
size_t size;
|
||||
file = fopen(fn, "ab");
|
||||
if (file == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
fseek(file, 0, SEEK_END);
|
||||
size = ftell(file);
|
||||
// append a dummy space. There are better ways to do
|
||||
// a touch, however this is a rather simple
|
||||
// multiplatform method
|
||||
if (fwrite(" ", 1, 1, file) != 1)
|
||||
{
|
||||
fclose(file);
|
||||
return FALSE;
|
||||
}
|
||||
#if PLATFORM_WINDOWS
|
||||
if (_chsize(_fileno(file), (long)size) != 0)
|
||||
{
|
||||
fclose(file);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
fclose(file);
|
||||
#if !PLATFORM_WINDOWS
|
||||
if (truncate(fn, (off_t)size) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int os_touchfile(lua_State* L)
|
||||
{
|
||||
FILE* file;
|
||||
const char* dst = luaL_checkstring(L, 1);
|
||||
|
||||
// if destination exist, mark the file as modified
|
||||
if (do_isfile(L, dst))
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
SYSTEMTIME systemTime;
|
||||
FILETIME fileTime;
|
||||
HANDLE fileHandle;
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, dst, -1, wide_path, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushstring(L, "unable to encode path");
|
||||
return 2;
|
||||
}
|
||||
|
||||
fileHandle = CreateFileW(wide_path, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (fileHandle == NULL)
|
||||
{
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushfstring(L, "unable to touch file '%s'", dst);
|
||||
return 2;
|
||||
}
|
||||
|
||||
GetSystemTime(&systemTime);
|
||||
if (SystemTimeToFileTime(&systemTime, &fileTime) == 0)
|
||||
{
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushfstring(L, "unable to touch file '%s'", dst);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (SetFileTime(fileHandle, NULL, NULL, &fileTime) == 0)
|
||||
{
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushfstring(L, "unable to touch file '%s'", dst);
|
||||
return 2;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, 0);
|
||||
return 1;
|
||||
#else
|
||||
if (truncate_file(dst))
|
||||
{
|
||||
lua_pushinteger(L, 0);
|
||||
return 1;
|
||||
} else {
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushfstring(L, "unable to touch file '%s'", dst);
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, dst, -1, wide_path, PATH_MAX) == 0)
|
||||
{
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushstring(L, "unable to encode path");
|
||||
return 2;
|
||||
}
|
||||
|
||||
file = _wfopen(wide_path, L"wb");
|
||||
#else
|
||||
file = fopen(dst, "wb");
|
||||
#endif
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose(file);
|
||||
|
||||
lua_pushinteger(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushfstring(L, "unable to open file to '%s'", dst);
|
||||
return 2;
|
||||
}
|
||||
75
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_uuid.c
vendored
Normal file
75
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_uuid.c
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* \file os_uuid.c
|
||||
* \brief Create a new UUID.
|
||||
* \author Copyright (c) 2002-2012 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include <objbase.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Pull off the four lowest bytes of a value and add them to my array,
|
||||
* without the help of the determinately sized C99 data types that
|
||||
* are not yet universally supported.
|
||||
*/
|
||||
static void add(unsigned char* bytes, int offset, uint32_t value)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
bytes[offset++] = (unsigned char)(value & 0xff);
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int os_uuid(lua_State* L)
|
||||
{
|
||||
char uuid[38];
|
||||
unsigned char bytes[16];
|
||||
|
||||
/* If a name argument is supplied, build the UUID from that. For speed we
|
||||
* are using a simple DBJ2 hashing function; if this isn't sufficient we
|
||||
* can switch to a full RFC 4122 §4.3 implementation later. */
|
||||
const char* name = luaL_optstring(L, 1, NULL);
|
||||
if (name != NULL)
|
||||
{
|
||||
add(bytes, 0, do_hash(name, 0));
|
||||
add(bytes, 4, do_hash(name, 'L'));
|
||||
add(bytes, 8, do_hash(name, 'u'));
|
||||
add(bytes, 12, do_hash(name, 'a'));
|
||||
}
|
||||
|
||||
/* If no name is supplied, try to build one properly */
|
||||
else
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
CoCreateGuid((GUID*)bytes);
|
||||
#else
|
||||
int result;
|
||||
|
||||
/* not sure how to get a UUID here, so I fake it */
|
||||
FILE* rnd = fopen("/dev/urandom", "rb");
|
||||
result = fread(bytes, 16, 1, rnd);
|
||||
fclose(rnd);
|
||||
if (!result)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
sprintf(uuid, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3],
|
||||
bytes[4], bytes[5],
|
||||
bytes[6], bytes[7],
|
||||
bytes[8], bytes[9],
|
||||
bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]);
|
||||
|
||||
lua_pushstring(L, uuid);
|
||||
return 1;
|
||||
}
|
||||
109
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_writefile_ifnotequal.c
vendored
Normal file
109
Src/external_dependencies/openmpt-trunk/include/premake/src/host/os_writefile_ifnotequal.c
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* \file os_writefile_ifnotequal.c
|
||||
* \brief Writes a file only if it differs with its current contents.
|
||||
* \author Blizzard Entertainment (contact tvandijck@blizzard.com)
|
||||
* \author Copyright (c) 2015 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
|
||||
static int compare_file(const char* content, size_t length, const char* dst)
|
||||
{
|
||||
FILE* file;
|
||||
size_t size;
|
||||
size_t read;
|
||||
char buffer[4096];
|
||||
size_t num;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, dst, -1, wide_path, PATH_MAX) == 0)
|
||||
return FALSE;
|
||||
|
||||
file = _wfopen(wide_path, L"rb");
|
||||
#else
|
||||
file = fopen(dst, "rb");
|
||||
#endif
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// check sizes.
|
||||
fseek(file, 0, SEEK_END);
|
||||
size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
if (length != size)
|
||||
{
|
||||
fclose(file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
num = size > 4096 ? 4096 : size;
|
||||
|
||||
read = fread(buffer, 1, num, file);
|
||||
if (read != num)
|
||||
{
|
||||
fclose (file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (memcmp(content, buffer, num) != 0)
|
||||
{
|
||||
fclose(file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size -= num;
|
||||
content += num;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int os_writefile_ifnotequal(lua_State* L)
|
||||
{
|
||||
FILE* file;
|
||||
size_t length;
|
||||
const char* content = luaL_checklstring(L, 1, &length);
|
||||
const char* dst = luaL_checkstring(L, 2);
|
||||
|
||||
// if destination exist, and they are the same, no need to copy.
|
||||
if (do_isfile(L, dst) && compare_file(content, length, dst))
|
||||
{
|
||||
lua_pushinteger(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t wide_path[PATH_MAX];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, dst, -1, wide_path, PATH_MAX) == 0)
|
||||
return FALSE;
|
||||
|
||||
file = _wfopen(wide_path, L"wb");
|
||||
#else
|
||||
file = fopen(dst, "wb");
|
||||
#endif
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
fwrite(content, 1, length, file);
|
||||
fclose(file);
|
||||
|
||||
lua_pushinteger(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, -1);
|
||||
lua_pushfstring(L, "unable to write file to '%s'", dst);
|
||||
return 2;
|
||||
}
|
||||
105
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_getabsolute.c
vendored
Normal file
105
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_getabsolute.c
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* \file path_getabsolute.c
|
||||
* \brief Returns an absolute version of a relative path.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void do_getabsolute(char* result, const char* value, const char* relative_to)
|
||||
{
|
||||
int i;
|
||||
char* ch;
|
||||
char* prev;
|
||||
char buffer[0x4000] = { '\0' };
|
||||
|
||||
/* if the path is not already absolute, base it on working dir */
|
||||
if (!do_isabsolute(value)) {
|
||||
if (relative_to) {
|
||||
strcpy(buffer, relative_to);
|
||||
}
|
||||
else {
|
||||
do_getcwd(buffer, 0x4000);
|
||||
}
|
||||
strcat(buffer, "/");
|
||||
}
|
||||
|
||||
/* normalize the path */
|
||||
strcat(buffer, value);
|
||||
do_translate(buffer, '/');
|
||||
|
||||
/* process it part by part */
|
||||
result[0] = '\0';
|
||||
if (buffer[0] == '/') {
|
||||
strcat(result, "/");
|
||||
if (buffer[1] == '/') {
|
||||
strcat(result, "/");
|
||||
}
|
||||
}
|
||||
|
||||
prev = NULL;
|
||||
ch = strtok(buffer, "/");
|
||||
while (ch) {
|
||||
/* remove ".." where I can */
|
||||
if (strcmp(ch, "..") == 0 && (prev == NULL || (prev[0] != '$' && prev[0] != '%' && strcmp(prev, "..") != 0))) {
|
||||
i = (int)strlen(result) - 2;
|
||||
while (i >= 0 && result[i] != '/') {
|
||||
--i;
|
||||
}
|
||||
if (i >= 0) {
|
||||
result[i + 1] = '\0';
|
||||
}
|
||||
ch = NULL;
|
||||
}
|
||||
|
||||
/* allow everything except "." */
|
||||
else if (strcmp(ch, ".") != 0) {
|
||||
strcat(result, ch);
|
||||
strcat(result, "/");
|
||||
}
|
||||
|
||||
prev = ch;
|
||||
ch = strtok(NULL, "/");
|
||||
}
|
||||
|
||||
/* remove trailing slash */
|
||||
i = (int)strlen(result) - 1;
|
||||
if (result[i] == '/') {
|
||||
result[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int path_getabsolute(lua_State* L)
|
||||
{
|
||||
const char* relative_to;
|
||||
char buffer[0x4000];
|
||||
|
||||
relative_to = NULL;
|
||||
if (lua_gettop(L) > 1 && !lua_isnil(L,2)) {
|
||||
relative_to = luaL_checkstring(L, 2);
|
||||
}
|
||||
|
||||
if (lua_istable(L, 1)) {
|
||||
int i = 0;
|
||||
lua_newtable(L);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
const char* value = luaL_checkstring(L, -1);
|
||||
do_getabsolute(buffer, value, relative_to);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushstring(L, buffer);
|
||||
lua_rawseti(L, -3, ++i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
const char* value = luaL_checkstring(L, 1);
|
||||
do_getabsolute(buffer, value, relative_to);
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
99
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_getrelative.c
vendored
Normal file
99
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_getrelative.c
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* \file path_getrelative.c
|
||||
* \brief Returns a path relative to another.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
#if PLATFORM_WINDOWS
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
|
||||
int path_getrelative(lua_State* L)
|
||||
{
|
||||
int i, last, count;
|
||||
char src[0x4000];
|
||||
char dst[0x4000];
|
||||
|
||||
const char* p1 = luaL_checkstring(L, 1);
|
||||
const char* p2 = luaL_checkstring(L, 2);
|
||||
|
||||
/* normalize the paths */
|
||||
do_normalize(L, src, p1);
|
||||
do_normalize(L, dst, p2);
|
||||
|
||||
/* same directory? */
|
||||
#if PLATFORM_WINDOWS
|
||||
if (_stricmp(src, dst) == 0) {
|
||||
#else
|
||||
if (strcmp(src, dst) == 0) {
|
||||
#endif
|
||||
lua_pushstring(L, ".");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* dollar macro? Can't tell what the real path might be, so treat
|
||||
* as absolute. This enables paths like $(SDK_ROOT)/include to
|
||||
* work as expected. */
|
||||
if (dst[0] == '$') {
|
||||
lua_pushstring(L, dst);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* find the common leading directories */
|
||||
strcat(src, "/");
|
||||
strcat(dst, "/");
|
||||
|
||||
last = -1;
|
||||
i = 0;
|
||||
#if PLATFORM_WINDOWS
|
||||
while (src[i] && dst[i] && tolower(src[i]) == tolower(dst[i])) {
|
||||
#else
|
||||
while (src[i] && dst[i] && src[i] == dst[i]) {
|
||||
#endif
|
||||
if (src[i] == '/') {
|
||||
last = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
/* if I end up with just the root of the filesystem, either a single
|
||||
* slash (/) or a drive letter (c:) then return the absolute path. */
|
||||
if (last <= 0 || (last == 2 && src[1] == ':')) {
|
||||
dst[strlen(dst) - 1] = '\0';
|
||||
lua_pushstring(L, dst);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Relative paths within a server can't climb outside the server root.
|
||||
* If the paths don't share server name, return the absolute path. */
|
||||
if (src[0] == '/' && src[1] == '/' && last == 1) {
|
||||
dst[strlen(dst) - 1] = '\0';
|
||||
lua_pushstring(L, dst);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* count remaining levels in src */
|
||||
count = 0;
|
||||
for (i = last + 1; src[i] != '\0'; ++i) {
|
||||
if (src[i] == '/') {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
/* start my result by backing out that many levels */
|
||||
src[0] = '\0';
|
||||
for (i = 0; i < count; ++i) {
|
||||
strcat(src, "../");
|
||||
}
|
||||
|
||||
/* append what's left */
|
||||
strcat(src, dst + last + 1);
|
||||
|
||||
/* remove trailing slash and done */
|
||||
src[strlen(src) - 1] = '\0';
|
||||
lua_pushstring(L, src);
|
||||
return 1;
|
||||
}
|
||||
119
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_isabsolute.c
vendored
Normal file
119
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_isabsolute.c
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* \file path_isabsolute.c
|
||||
* \brief Determines if a path is absolute or relative.
|
||||
* \author Copyright (c) 2002-2016 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "path_isabsolute.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
int do_absolutetype(const char* path)
|
||||
{
|
||||
char c;
|
||||
const char* closing;
|
||||
size_t length;
|
||||
|
||||
while (path[0] == '"' || path[0] == '!')
|
||||
path++;
|
||||
if (path[0] == '/' || path[0] == '\\')
|
||||
return JOIN_ABSOLUTE;
|
||||
if (isalpha(path[0]) && path[1] == ':')
|
||||
return JOIN_ABSOLUTE;
|
||||
|
||||
// $(foo) and %(foo)
|
||||
if ((path[0] == '%' || path[0] == '$') && path[1] == '(')
|
||||
{
|
||||
char delimiter = path[0];
|
||||
closing = strchr(path + 2, ')');
|
||||
if (closing == NULL)
|
||||
return JOIN_RELATIVE;
|
||||
|
||||
path += 2;
|
||||
// special case VS macros %(filename) and %(extension) as normal text
|
||||
if (delimiter == '%')
|
||||
{
|
||||
length = closing - path;
|
||||
switch (length) {
|
||||
case 8:
|
||||
if (strncasecmp(path, "Filename)", length) == 0)
|
||||
return JOIN_RELATIVE;
|
||||
break;
|
||||
case 9:
|
||||
if (strncasecmp(path, "Extension)", length) == 0)
|
||||
return JOIN_RELATIVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// only alpha, digits, _ and . allowed inside $()
|
||||
while (path < closing) {
|
||||
c = *path++;
|
||||
if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.')
|
||||
return JOIN_RELATIVE;
|
||||
}
|
||||
|
||||
return JOIN_ABSOLUTE;
|
||||
}
|
||||
|
||||
// $ORIGIN.
|
||||
if (path[0] == '$')
|
||||
return JOIN_ABSOLUTE;
|
||||
|
||||
// either %ORIGIN% or %{<lua code>}
|
||||
if (path[0] == '%')
|
||||
{
|
||||
if (path[1] == '{') //${foo} need to defer join until after detokenization
|
||||
{
|
||||
closing = strchr(path + 2, '}');
|
||||
if (closing != NULL)
|
||||
return JOIN_MAYBE_ABSOLUTE;
|
||||
}
|
||||
// find the second closing %
|
||||
path += 1;
|
||||
closing = strchr(path, '%');
|
||||
if (closing == NULL)
|
||||
return JOIN_RELATIVE;
|
||||
|
||||
// need at least one character between the %%
|
||||
if (path == closing)
|
||||
return JOIN_RELATIVE;
|
||||
|
||||
// only alpha, digits and _ allowed inside %..%
|
||||
while (path < closing) {
|
||||
c = *path++;
|
||||
if (!isalpha(c) && !isdigit(c) && c != '_')
|
||||
return JOIN_RELATIVE;
|
||||
}
|
||||
return JOIN_ABSOLUTE;
|
||||
}
|
||||
|
||||
return JOIN_RELATIVE;
|
||||
}
|
||||
|
||||
int do_isabsolute(const char* path)
|
||||
{
|
||||
// backwards compatibility
|
||||
return (do_absolutetype(path) == 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
int path_isabsolute(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, -1);
|
||||
lua_pushboolean(L, do_isabsolute(path));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int path_absolutetype(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, -1);
|
||||
lua_pushinteger(L, do_absolutetype(path));
|
||||
return 1;
|
||||
}
|
||||
9
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_isabsolute.h
vendored
Normal file
9
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_isabsolute.h
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* \file path_isabsolute.h
|
||||
* \brief Determines if a path is absolute or relative.
|
||||
* \author Copyright (c) 2002-2016 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#define JOIN_RELATIVE 0
|
||||
#define JOIN_ABSOLUTE 1
|
||||
#define JOIN_MAYBE_ABSOLUTE 2
|
||||
191
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_join.c
vendored
Normal file
191
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_join.c
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* \file path_join.c
|
||||
* \brief Join two or more pieces of a file system path.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
#include "path_isabsolute.h"
|
||||
|
||||
#define DEFERRED_JOIN_DELIMITER '\a'
|
||||
|
||||
char* path_join_single(char* buffer, char* ptr, const char* part, int allowDeferredJoin)
|
||||
{
|
||||
int absoluteType;
|
||||
size_t len = strlen(part);
|
||||
/* remove leading "./" */
|
||||
while (strncmp(part, "./", 2) == 0) {
|
||||
part += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
/* remove trailing slashes */
|
||||
while (len > 1 && part[len - 1] == '/') {
|
||||
--len;
|
||||
}
|
||||
|
||||
/* ignore empty segments and "." */
|
||||
if (len == 0 || (len == 1 && part[0] == '.')) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
absoluteType = do_absolutetype(part);
|
||||
if (!allowDeferredJoin && absoluteType == JOIN_MAYBE_ABSOLUTE)
|
||||
absoluteType = JOIN_RELATIVE;
|
||||
|
||||
/* if I encounter an absolute path, restart my result */
|
||||
switch (absoluteType) {
|
||||
case JOIN_ABSOLUTE:
|
||||
ptr = buffer;
|
||||
break;
|
||||
case JOIN_RELATIVE:
|
||||
/* if source has a .. prefix then take off last dest path part
|
||||
note that this doesn't guarantee a normalized result as this
|
||||
code doesn't check for .. in the mid path, however .. occurring
|
||||
mid path are much more likely to occur during path joins
|
||||
and its faster if we handle here as we don't have to remove
|
||||
substrings from the middle of the string. */
|
||||
|
||||
while (ptr != buffer && len >= 2 && part[0] == '.' && part[1] == '.')
|
||||
{
|
||||
/* locate start of previous segment */
|
||||
char* start = strrchr(buffer, '/');
|
||||
if (!start) {
|
||||
start = buffer;
|
||||
}
|
||||
else {
|
||||
++start;
|
||||
}
|
||||
|
||||
/* if I hit a segment I can't trim, bail out */
|
||||
if (strcmp(start, "..") == 0 /* parent dir */
|
||||
|| strcmp(start, ".") == 0 /* current dir */
|
||||
|| strstr(start, "**") != NULL /* recursive wildcard */
|
||||
|| strchr(start, '$') != NULL) /* property expansion */
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* otherwise trim segment and the ".." sequence */
|
||||
if (start != buffer) {
|
||||
--start;
|
||||
}
|
||||
*start = '\0';
|
||||
ptr = start;
|
||||
part += 2;
|
||||
len -= 2;
|
||||
if (len > 0 && part[0] == '/') {
|
||||
++part;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the path is already started, split parts */
|
||||
if (ptr != buffer && *(ptr - 1) != '/') {
|
||||
*(ptr++) = '/';
|
||||
}
|
||||
|
||||
break;
|
||||
case JOIN_MAYBE_ABSOLUTE:
|
||||
*ptr = DEFERRED_JOIN_DELIMITER;
|
||||
ptr++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* append new part */
|
||||
strncpy(ptr, part, len);
|
||||
ptr += len;
|
||||
*ptr = '\0';
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int path_join_internal(lua_State* L, int allowDeferredJoin)
|
||||
{
|
||||
int i;
|
||||
const char* part;
|
||||
char buffer[0x4000];
|
||||
char* ptr = buffer;
|
||||
|
||||
/* for each argument... */
|
||||
int argc = lua_gettop(L);
|
||||
for (i = 1; i <= argc; ++i) {
|
||||
/* if next argument is nil, skip it */
|
||||
if (lua_isnil(L, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* grab the next argument */
|
||||
part = luaL_checkstring(L, i);
|
||||
ptr = path_join_single(buffer, ptr, part, allowDeferredJoin);
|
||||
}
|
||||
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int path_join(lua_State* L)
|
||||
{
|
||||
return path_join_internal(L, 0);
|
||||
}
|
||||
|
||||
|
||||
int path_deferred_join(lua_State* L)
|
||||
{
|
||||
return path_join_internal(L, 1);
|
||||
}
|
||||
|
||||
|
||||
int do_path_has_deferred_join(const char* path)
|
||||
{
|
||||
return (strchr(path, DEFERRED_JOIN_DELIMITER) != NULL);
|
||||
}
|
||||
|
||||
|
||||
int path_has_deferred_join(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, -1);
|
||||
lua_pushboolean(L, do_path_has_deferred_join(path));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int path_resolve_deferred_join(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, -1);
|
||||
char inBuffer[0x4000];
|
||||
char outBuffer[0x4000];
|
||||
char* ptr = outBuffer;
|
||||
char* nextPart;
|
||||
size_t len = strlen(path);
|
||||
int i;
|
||||
int numParts = 0;
|
||||
strncpy(inBuffer, path, len);
|
||||
inBuffer[len] = '\0';
|
||||
char *parts[0x200];
|
||||
// break up the string into parts and index the start of each part
|
||||
nextPart = strchr(inBuffer, DEFERRED_JOIN_DELIMITER);
|
||||
if (nextPart == NULL) // nothing to do
|
||||
{
|
||||
lua_pushlstring(L, inBuffer, len);
|
||||
return 1;
|
||||
}
|
||||
parts[numParts++] = inBuffer;
|
||||
while (nextPart != NULL)
|
||||
{
|
||||
*nextPart = '\0';
|
||||
nextPart++;
|
||||
parts[numParts++] = nextPart;
|
||||
nextPart = strchr(nextPart, DEFERRED_JOIN_DELIMITER);
|
||||
}
|
||||
|
||||
/* for each part... */
|
||||
for (i = 0; i < numParts; ++i) {
|
||||
nextPart = parts[i];
|
||||
ptr = path_join_single(outBuffer, ptr, nextPart, 0);
|
||||
}
|
||||
|
||||
lua_pushstring(L, outBuffer);
|
||||
return 1;
|
||||
}
|
||||
223
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_normalize.c
vendored
Normal file
223
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_normalize.c
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* \file path_normalize.c
|
||||
* \brief Removes any weirdness from a file system path string.
|
||||
* \author Copyright (c) 2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#define IS_SEP(__c) ((__c) == '/' || (__c) == '\\')
|
||||
#define IS_QUOTE(__c) ((__c) == '\"' || (__c) == '\'')
|
||||
|
||||
#define IS_UPPER_ALPHA(__c) ((__c) >= 'A' && (__c) <= 'Z')
|
||||
#define IS_LOWER_ALPHA(__c) ((__c) >= 'a' && (__c) <= 'z')
|
||||
#define IS_ALPHA(__c) (IS_UPPER_ALPHA(__c) || IS_LOWER_ALPHA(__c))
|
||||
|
||||
#define IS_SPACE(__c) ((__c >= '\t' && __c <= '\r') || __c == ' ')
|
||||
|
||||
#define IS_WIN_ENVVAR_START(__c) (*__c == '%')
|
||||
#define IS_WIN_ENVVAR_END(__c) (*__c == '%')
|
||||
|
||||
#define IS_VS_VAR_START(__c) (*__c == '$' && __c[1] == '(')
|
||||
#define IS_VS_VAR_END(__c) (*__c == ')')
|
||||
|
||||
#define IS_UNIX_ENVVAR_START(__c) (*__c == '$' && __c[1] == '{')
|
||||
#define IS_UNIX_ENVVAR_END(__c) (*__c == '}')
|
||||
|
||||
#define IS_PREMAKE_TOKEN_START(__c) (*__c == '%' && __c[1] == '{')
|
||||
#define IS_PREMAKE_TOKEN_END(__c) (*__c == '}')
|
||||
|
||||
static void* normalize_substring(const char* srcPtr, const char* srcEnd, char* dstPtr)
|
||||
{
|
||||
#define IS_END(__p) (__p >= srcEnd || *__p == '\0')
|
||||
#define IS_SEP_OR_END(__p) (IS_END(__p) || IS_SEP(*__p))
|
||||
|
||||
// Handle Windows absolute paths
|
||||
if (IS_ALPHA(srcPtr[0]) && srcPtr[1] == ':')
|
||||
{
|
||||
*(dstPtr++) = srcPtr[0];
|
||||
*(dstPtr++) = ':';
|
||||
|
||||
srcPtr += 2;
|
||||
}
|
||||
|
||||
// Handle path starting with a sep (C:/ or /)
|
||||
if (IS_SEP(*srcPtr))
|
||||
{
|
||||
++srcPtr;
|
||||
*(dstPtr++) = '/';
|
||||
// Handle path starting with //
|
||||
if (IS_SEP(*srcPtr))
|
||||
{
|
||||
++srcPtr;
|
||||
*(dstPtr++) = '/';
|
||||
}
|
||||
}
|
||||
|
||||
const char * const dstRoot = dstPtr;
|
||||
unsigned int folderDepth = 0;
|
||||
|
||||
while (!IS_END(srcPtr))
|
||||
{
|
||||
// Skip multiple sep and "./" pattern
|
||||
while (IS_SEP(*srcPtr) || (srcPtr[0] == '.' && IS_SEP_OR_END(&srcPtr[1])))
|
||||
++srcPtr;
|
||||
|
||||
if (IS_END(srcPtr))
|
||||
break;
|
||||
|
||||
// Handle "../ pattern"
|
||||
if (srcPtr[0] == '.' && srcPtr[1] == '.' && IS_SEP_OR_END(&srcPtr[2]))
|
||||
{
|
||||
if (folderDepth > 0)
|
||||
{
|
||||
// Here dstPtr[-1] is safe as folderDepth > 0.
|
||||
while (--dstPtr != dstRoot && !IS_SEP(dstPtr[-1]));
|
||||
|
||||
--folderDepth;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(dstPtr++) = '.';
|
||||
*(dstPtr++) = '.';
|
||||
*(dstPtr++) = '/';
|
||||
}
|
||||
srcPtr += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!IS_SEP_OR_END(srcPtr))
|
||||
*(dstPtr++) = *(srcPtr++);
|
||||
|
||||
if (IS_SEP(*srcPtr))
|
||||
{
|
||||
*(dstPtr++) = '/';
|
||||
++srcPtr;
|
||||
++folderDepth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove trailing slash except for C:/ or / (root)
|
||||
while (dstPtr != dstRoot && IS_SEP(dstPtr[-1]))
|
||||
--dstPtr;
|
||||
|
||||
return dstPtr;
|
||||
#undef IS_END
|
||||
#undef IS_SEP_OR_END
|
||||
}
|
||||
|
||||
static int skip_tokens(const char *readPtr)
|
||||
{
|
||||
int skipped = 0;
|
||||
|
||||
#define DO_SKIP_FOR(__kind)\
|
||||
if (IS_ ## __kind ## _START(readPtr)) { \
|
||||
do \
|
||||
{ \
|
||||
skipped++; \
|
||||
} while (!IS_ ## __kind ## _END(readPtr++)); \
|
||||
} \
|
||||
// DO_SKIP_FOR
|
||||
|
||||
do
|
||||
{
|
||||
DO_SKIP_FOR(PREMAKE_TOKEN)
|
||||
DO_SKIP_FOR(WIN_ENVVAR)
|
||||
DO_SKIP_FOR(VS_VAR)
|
||||
DO_SKIP_FOR(UNIX_ENVVAR)
|
||||
|
||||
} while (IS_WIN_ENVVAR_START(readPtr) ||
|
||||
IS_VS_VAR_START(readPtr) ||
|
||||
IS_UNIX_ENVVAR_START(readPtr) ||
|
||||
IS_PREMAKE_TOKEN_START(readPtr));
|
||||
|
||||
return skipped;
|
||||
#undef DO_SKIP_FOR
|
||||
}
|
||||
|
||||
int path_normalize(lua_State* L)
|
||||
{
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
const char *readPtr = path;
|
||||
char buffer[0x4000] = { 0 };
|
||||
char *writePtr = buffer;
|
||||
const char *endPtr;
|
||||
|
||||
// skip leading white spaces
|
||||
while (IS_SPACE(*readPtr))
|
||||
++readPtr;
|
||||
|
||||
endPtr = readPtr;
|
||||
|
||||
while (*endPtr) {
|
||||
|
||||
int skipped = skip_tokens(readPtr);
|
||||
if (skipped > 0) {
|
||||
|
||||
if (readPtr != path && writePtr != buffer &&
|
||||
IS_SEP(readPtr[-1]) && !IS_SEP(writePtr[-1]))
|
||||
{
|
||||
*(writePtr++) = (readPtr[-1]);
|
||||
}
|
||||
|
||||
while (skipped-- > 0)
|
||||
*(writePtr++) = *(readPtr++);
|
||||
|
||||
endPtr = readPtr;
|
||||
}
|
||||
|
||||
// find the end of sub path
|
||||
while (*endPtr && !IS_SPACE(*endPtr) &&
|
||||
!IS_WIN_ENVVAR_START(endPtr) &&
|
||||
!IS_VS_VAR_START(endPtr) &&
|
||||
!IS_UNIX_ENVVAR_START(endPtr) &&
|
||||
!IS_PREMAKE_TOKEN_START(endPtr))
|
||||
{
|
||||
++endPtr;
|
||||
}
|
||||
|
||||
// path is surrounded with quotes
|
||||
if (readPtr != endPtr &&
|
||||
IS_QUOTE(*readPtr))
|
||||
{
|
||||
*(writePtr++) = *(readPtr++);
|
||||
}
|
||||
|
||||
writePtr = normalize_substring(readPtr, endPtr, writePtr);
|
||||
|
||||
// skip any white spaces between sub paths
|
||||
while (IS_SPACE(*endPtr))
|
||||
*(writePtr++) = *(endPtr++);
|
||||
|
||||
readPtr = endPtr;
|
||||
}
|
||||
|
||||
// skip any trailing white spaces
|
||||
while (writePtr != buffer && IS_SPACE(writePtr[-1]))
|
||||
--writePtr;
|
||||
|
||||
*writePtr = 0;
|
||||
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Call the scripted path.normalize(), to allow for overrides */
|
||||
void do_normalize(lua_State* L, char* buffer, const char* path)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_getglobal(L, "path");
|
||||
lua_getfield(L, -1, "normalize");
|
||||
lua_pushstring(L, path);
|
||||
lua_call(L, 1, 1);
|
||||
|
||||
path = luaL_checkstring(L, -1);
|
||||
strcpy(buffer, path);
|
||||
|
||||
lua_settop(L, top);
|
||||
}
|
||||
65
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_translate.c
vendored
Normal file
65
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_translate.c
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* \file path_translate.c
|
||||
* \brief Translates between path separators.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void do_translate(char* value, const char sep)
|
||||
{
|
||||
char* ch;
|
||||
for (ch = value; *ch != '\0'; ++ch) {
|
||||
if (*ch == '/' || *ch == '\\') {
|
||||
*ch = sep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void translate(char* result, const char* value, const char sep)
|
||||
{
|
||||
strcpy(result, value);
|
||||
do_translate(result, sep);
|
||||
}
|
||||
|
||||
|
||||
int path_translate(lua_State* L)
|
||||
{
|
||||
const char* sep;
|
||||
char buffer[0x4000];
|
||||
|
||||
if (lua_gettop(L) == 1) {
|
||||
lua_getglobal(L, "path");
|
||||
lua_getfield(L, -1, "getDefaultSeparator");
|
||||
lua_call(L, 0, 1);
|
||||
sep = luaL_checkstring(L, -1);
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
else {
|
||||
sep = luaL_checkstring(L, 2);
|
||||
}
|
||||
|
||||
if (lua_istable(L, 1)) {
|
||||
int i = 0;
|
||||
lua_newtable(L);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
const char* value = luaL_checkstring(L, 4);
|
||||
translate(buffer, value, sep[0]);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushstring(L, buffer);
|
||||
lua_rawseti(L, -3, ++i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
const char* value = luaL_checkstring(L, 1);
|
||||
translate(buffer, value, sep[0]);
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
80
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_wildcards.c
vendored
Normal file
80
Src/external_dependencies/openmpt-trunk/include/premake/src/host/path_wildcards.c
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* \file path_wildcards.c
|
||||
* \brief Converts from a simple wildcard syntax to the corresponding Lua pattern.
|
||||
* \author Copyright (c) 2015 Tom van Dijck, Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
--Converts from a simple wildcard syntax, where * is "match any"
|
||||
-- and ** is "match recursive", to the corresponding Lua pattern.
|
||||
--
|
||||
-- @param pattern
|
||||
-- The wildcard pattern to convert.
|
||||
-- @returns
|
||||
-- The corresponding Lua pattern.
|
||||
*/
|
||||
int path_wildcards(lua_State* L)
|
||||
{
|
||||
size_t length, i;
|
||||
const char* input;
|
||||
char buffer[0x4000];
|
||||
char* output;
|
||||
|
||||
input = luaL_checklstring(L, 1, &length);
|
||||
output = buffer;
|
||||
|
||||
for (i = 0; i < length; ++i)
|
||||
{
|
||||
char c = input[i];
|
||||
switch (c)
|
||||
{
|
||||
case '+':
|
||||
case '.':
|
||||
case '-':
|
||||
case '^':
|
||||
case '$':
|
||||
case '(':
|
||||
case ')':
|
||||
case '%':
|
||||
*(output++) = '%';
|
||||
*(output++) = c;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if ((i + 1) < length && input[i + 1] == '*')
|
||||
{
|
||||
i++; // skip the next character.
|
||||
*(output++) = '.';
|
||||
*(output++) = '*';
|
||||
}
|
||||
else
|
||||
{
|
||||
*(output++) = '[';
|
||||
*(output++) = '^';
|
||||
*(output++) = '/';
|
||||
*(output++) = ']';
|
||||
*(output++) = '*';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*(output++) = c;
|
||||
break;
|
||||
}
|
||||
|
||||
if (output >= buffer + sizeof(buffer))
|
||||
{
|
||||
lua_pushstring(L, "Wildcards expansion too big.");
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
|
||||
*(output++) = '\0';
|
||||
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
}
|
||||
705
Src/external_dependencies/openmpt-trunk/include/premake/src/host/premake.c
vendored
Normal file
705
Src/external_dependencies/openmpt-trunk/include/premake/src/host/premake.c
vendored
Normal file
@@ -0,0 +1,705 @@
|
||||
/**
|
||||
* \file premake.c
|
||||
* \brief Program entry point.
|
||||
* \author Copyright (c) 2002-2017 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "premake.h"
|
||||
#include "lua_shimtable.h"
|
||||
|
||||
#if PLATFORM_MACOSX
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#endif
|
||||
|
||||
#if PLATFORM_BSD
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#define ERROR_MESSAGE "Error: %s\n"
|
||||
|
||||
|
||||
static void build_premake_path(lua_State* L);
|
||||
static int process_arguments(lua_State* L, int argc, const char** argv);
|
||||
static int run_premake_main(lua_State* L, const char* script);
|
||||
|
||||
|
||||
/* A search path for script files */
|
||||
const char* scripts_path = NULL;
|
||||
|
||||
|
||||
/* Built-in functions */
|
||||
static const luaL_Reg criteria_functions[] = {
|
||||
{ "_compile", criteria_compile },
|
||||
{ "_delete", criteria_delete },
|
||||
{ "matches", criteria_matches },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg debug_functions[] = {
|
||||
{ "prompt", debug_prompt },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg path_functions[] = {
|
||||
{ "getabsolute", path_getabsolute },
|
||||
{ "getrelative", path_getrelative },
|
||||
{ "isabsolute", path_isabsolute },
|
||||
{ "join", path_join },
|
||||
{ "deferredjoin", path_deferred_join },
|
||||
{ "hasdeferredjoin", path_has_deferred_join },
|
||||
{ "resolvedeferredjoin", path_resolve_deferred_join },
|
||||
{ "normalize", path_normalize },
|
||||
{ "translate", path_translate },
|
||||
{ "wildcards", path_wildcards },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg os_functions[] = {
|
||||
{ "chdir", os_chdir },
|
||||
{ "chmod", os_chmod },
|
||||
{ "comparefiles", os_comparefiles },
|
||||
{ "copyfile", os_copyfile },
|
||||
{ "_is64bit", os_is64bit },
|
||||
{ "isdir", os_isdir },
|
||||
{ "getcwd", os_getcwd },
|
||||
{ "getpass", os_getpass },
|
||||
{ "getWindowsRegistry", os_getWindowsRegistry },
|
||||
{ "listWindowsRegistry", os_listWindowsRegistry },
|
||||
{ "getversion", os_getversion },
|
||||
{ "host", os_host },
|
||||
{ "isfile", os_isfile },
|
||||
{ "islink", os_islink },
|
||||
{ "locate", os_locate },
|
||||
{ "matchdone", os_matchdone },
|
||||
{ "matchisfile", os_matchisfile },
|
||||
{ "matchname", os_matchname },
|
||||
{ "matchnext", os_matchnext },
|
||||
{ "matchstart", os_matchstart },
|
||||
{ "mkdir", os_mkdir },
|
||||
#if PLATFORM_WINDOWS
|
||||
// utf8 functions for Windows (assuming posix already handle utf8)
|
||||
{"remove", os_remove },
|
||||
{"rename", os_rename },
|
||||
#endif
|
||||
{ "pathsearch", os_pathsearch },
|
||||
{ "realpath", os_realpath },
|
||||
{ "rmdir", os_rmdir },
|
||||
{ "stat", os_stat },
|
||||
{ "uuid", os_uuid },
|
||||
{ "writefile_ifnotequal", os_writefile_ifnotequal },
|
||||
{ "touchfile", os_touchfile },
|
||||
{ "compile", os_compile },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg premake_functions[] = {
|
||||
{ "getEmbeddedResource", premake_getEmbeddedResource },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg string_functions[] = {
|
||||
{ "endswith", string_endswith },
|
||||
{ "hash", string_hash },
|
||||
{ "sha1", string_sha1 },
|
||||
{ "startswith", string_startswith },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg buffered_functions[] = {
|
||||
{ "new", buffered_new },
|
||||
{ "write", buffered_write },
|
||||
{ "writeln", buffered_writeln },
|
||||
{ "tostring", buffered_tostring },
|
||||
{ "close", buffered_close },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg term_functions[] = {
|
||||
{ "getTextColor", term_getTextColor },
|
||||
{ "setTextColor", term_setTextColor },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#ifdef PREMAKE_CURL
|
||||
static const luaL_Reg http_functions[] = {
|
||||
{ "get", http_get },
|
||||
{ "post", http_post },
|
||||
{ "download", http_download },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef PREMAKE_COMPRESSION
|
||||
static const luaL_Reg zip_functions[] = {
|
||||
{ "extract", zip_extract },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static void lua_getorcreate_table(lua_State *L, const char *modname)
|
||||
{
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); // get _LOADED table stack = {_LOADED}
|
||||
lua_getfield(L, -1, modname); // get _LOADED[modname] stack = { _LOADED, result }
|
||||
if (!lua_istable(L, -1)) // not found? stack = { _LOADED, result }
|
||||
{
|
||||
lua_pop(L, 1); // remove previous result stack = { _LOADED }
|
||||
lua_pushglobaltable(L); // push _G onto stack stack = { _LOADED, _G }
|
||||
lua_createtable(L, 0, 0); // new table for field stack = { _LOADED, _G, result }
|
||||
lua_pushlstring(L, modname, strlen(modname)); // stack = { _LOADED, _G, result, modname }
|
||||
lua_pushvalue(L, -2); // stack = { _LOADED, _G, result, modname, result }
|
||||
lua_settable(L, -4); // _G[modname] = result stack = { _LOADED, _G, result }
|
||||
lua_remove(L, -2); // remove _G from stack stack = { _LOADED, result }
|
||||
lua_pushvalue(L, -1); // duplicate result stack = { _LOADED, result, result }
|
||||
lua_setfield(L, -3, modname); // _LOADED[modname] = result stack = { _LOADED, result }
|
||||
}
|
||||
|
||||
lua_remove(L, -2); // remove _LOADED from stack stack = { result }
|
||||
}
|
||||
|
||||
|
||||
void luaL_register(lua_State *L, const char *libname, const luaL_Reg *l)
|
||||
{
|
||||
lua_getorcreate_table(L, libname);
|
||||
luaL_setfuncs(L, l, 0);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the Premake Lua environment.
|
||||
*/
|
||||
int premake_init(lua_State* L)
|
||||
{
|
||||
const char* value;
|
||||
|
||||
luaL_register(L, "premake", premake_functions);
|
||||
luaL_register(L, "criteria", criteria_functions);
|
||||
luaL_register(L, "debug", debug_functions);
|
||||
luaL_register(L, "path", path_functions);
|
||||
luaL_register(L, "os", os_functions);
|
||||
luaL_register(L, "string", string_functions);
|
||||
luaL_register(L, "buffered", buffered_functions);
|
||||
luaL_register(L, "term", term_functions);
|
||||
|
||||
#ifdef PREMAKE_CURL
|
||||
luaL_register(L, "http", http_functions);
|
||||
#endif
|
||||
|
||||
#ifdef PREMAKE_COMPRESSION
|
||||
luaL_register(L, "zip", zip_functions);
|
||||
#endif
|
||||
|
||||
lua_pushlightuserdata(L, &s_shimTable);
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, 0x5348494D); // equal to 'SHIM'
|
||||
|
||||
/* push the application metadata */
|
||||
lua_pushstring(L, LUA_COPYRIGHT);
|
||||
lua_setglobal(L, "_COPYRIGHT");
|
||||
|
||||
lua_pushstring(L, PREMAKE_VERSION);
|
||||
lua_setglobal(L, "_PREMAKE_VERSION");
|
||||
|
||||
lua_pushstring(L, PREMAKE_COPYRIGHT);
|
||||
lua_setglobal(L, "_PREMAKE_COPYRIGHT");
|
||||
|
||||
lua_pushstring(L, PREMAKE_PROJECT_URL);
|
||||
lua_setglobal(L, "_PREMAKE_URL");
|
||||
|
||||
/* set the OS platform variable */
|
||||
lua_pushstring(L, PLATFORM_STRING);
|
||||
lua_setglobal(L, "_TARGET_OS");
|
||||
|
||||
/* find the user's home directory */
|
||||
value = getenv("HOME");
|
||||
if (!value) value = getenv("USERPROFILE");
|
||||
if (!value) value = "~";
|
||||
lua_pushstring(L, value);
|
||||
lua_setglobal(L, "_USER_HOME_DIR");
|
||||
|
||||
/* publish the initial working directory */
|
||||
os_getcwd(L);
|
||||
lua_setglobal(L, "_WORKING_DIR");
|
||||
|
||||
#if !defined(PREMAKE_NO_BUILTIN_SCRIPTS)
|
||||
/* let native modules initialize themselves */
|
||||
registerModules(L);
|
||||
#endif
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
static void setErrorColor(lua_State* L)
|
||||
{
|
||||
int errorColor = 12;
|
||||
|
||||
lua_getglobal(L, "term");
|
||||
lua_pushstring(L, "errorColor");
|
||||
lua_gettable(L, -2);
|
||||
|
||||
if (!lua_isnil(L, -1))
|
||||
errorColor = (int)luaL_checkinteger(L, -1);
|
||||
|
||||
term_doSetTextColor(errorColor);
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void printLastError(lua_State* L)
|
||||
{
|
||||
const char* message = lua_tostring(L, -1);
|
||||
int oldColor = term_doGetTextColor();
|
||||
setErrorColor(L);
|
||||
printf(ERROR_MESSAGE, message);
|
||||
term_doSetTextColor(oldColor);
|
||||
}
|
||||
|
||||
static int lua_error_handler(lua_State* L)
|
||||
{
|
||||
// in debug mode, show full traceback on all errors
|
||||
#if !defined(NDEBUG)
|
||||
lua_getglobal(L, "debug");
|
||||
lua_getfield(L, -1, "traceback");
|
||||
lua_remove(L, -2); // remove debug table
|
||||
lua_insert(L, -2); // insert traceback function before error message
|
||||
lua_pushinteger(L, 3); // push level
|
||||
lua_call(L, 2, 1); // call traceback
|
||||
#else
|
||||
(void) L;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int premake_pcall(lua_State* L, int nargs, int nresults)
|
||||
{
|
||||
lua_pushcfunction(L, lua_error_handler);
|
||||
|
||||
int error_handler_index = lua_gettop(L) - nargs - 1;
|
||||
lua_insert(L, error_handler_index); // insert lua_error_handler before call parameters
|
||||
int result = lua_pcall(L, nargs, nresults, error_handler_index);
|
||||
lua_remove(L, error_handler_index); // remove lua_error_handler from stack
|
||||
return result;
|
||||
}
|
||||
|
||||
int premake_execute(lua_State* L, int argc, const char** argv, const char* script)
|
||||
{
|
||||
/* push the absolute path to the Premake executable */
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
premake_locate_executable(L, argv[0]);
|
||||
lua_call(L, 1, 1);
|
||||
lua_setglobal(L, "_PREMAKE_COMMAND");
|
||||
|
||||
/* Parse the command line arguments */
|
||||
if (process_arguments(L, argc, argv) != OKAY) {
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* Use --scripts and PREMAKE_PATH to populate premake.path */
|
||||
build_premake_path(L);
|
||||
|
||||
/* Find and run the main Premake bootstrapping script */
|
||||
if (run_premake_main(L, script) != OKAY) {
|
||||
printLastError(L);
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* and call the main entry point */
|
||||
lua_getglobal(L, "_premake_main");
|
||||
if (premake_pcall(L, 0, 1) != OKAY) {
|
||||
printLastError(L);
|
||||
return !OKAY;
|
||||
}
|
||||
else {
|
||||
int exitCode = (int)lua_tonumber(L, -1);
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Locate the Premake executable, and push its full path to the Lua stack.
|
||||
* Based on:
|
||||
* http://sourceforge.net/tracker/index.php?func=detail&aid=3351583&group_id=71616&atid=531880
|
||||
* http://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c
|
||||
* http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
|
||||
*/
|
||||
int premake_locate_executable(lua_State* L, const char* argv0)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
const char* path = NULL;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
wchar_t widebuffer[PATH_MAX];
|
||||
|
||||
DWORD len = GetModuleFileNameW(NULL, widebuffer, PATH_MAX);
|
||||
if (len > 0)
|
||||
{
|
||||
WideCharToMultiByte(CP_UTF8, 0, widebuffer, len, buffer, PATH_MAX, NULL, NULL);
|
||||
|
||||
buffer[len] = 0;
|
||||
path = buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PLATFORM_MACOSX
|
||||
CFURLRef bundleURL = CFBundleCopyExecutableURL(CFBundleGetMainBundle());
|
||||
CFStringRef pathRef = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
|
||||
if (CFStringGetCString(pathRef, buffer, PATH_MAX - 1, kCFStringEncodingUTF8))
|
||||
path = buffer;
|
||||
#endif
|
||||
|
||||
#if PLATFORM_LINUX
|
||||
int len = readlink("/proc/self/exe", buffer, PATH_MAX - 1);
|
||||
if (len > 0)
|
||||
{
|
||||
buffer[len] = 0;
|
||||
path = buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PLATFORM_BSD && !defined(__OpenBSD__)
|
||||
int len = readlink("/proc/curproc/file", buffer, PATH_MAX - 1);
|
||||
if (len < 0)
|
||||
len = readlink("/proc/curproc/exe", buffer, PATH_MAX - 1);
|
||||
if (len < 0)
|
||||
{
|
||||
int mib[4];
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PATHNAME;
|
||||
mib[3] = -1;
|
||||
size_t cb = sizeof(buffer);
|
||||
sysctl(mib, 4, buffer, &cb, NULL, 0);
|
||||
len = (int)cb;
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
buffer[len] = 0;
|
||||
path = buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PLATFORM_SOLARIS
|
||||
int len = readlink("/proc/self/path/a.out", buffer, PATH_MAX - 1);
|
||||
if (len > 0)
|
||||
{
|
||||
buffer[len] = 0;
|
||||
path = buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* As a fallback, search the PATH with argv[0] */
|
||||
if (!path)
|
||||
{
|
||||
lua_pushcfunction(L, os_pathsearch);
|
||||
lua_pushstring(L, argv0);
|
||||
lua_pushstring(L, getenv("PATH"));
|
||||
if (lua_pcall(L, 2, 1, 0) == OKAY && !lua_isnil(L, -1))
|
||||
{
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushstring(L, argv0);
|
||||
lua_concat(L, 3);
|
||||
path = lua_tostring(L, -1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
/* If all else fails, use argv[0] as-is and hope for the best */
|
||||
if (!path)
|
||||
{
|
||||
/* make it absolute, if needed */
|
||||
os_getcwd(L);
|
||||
lua_pushstring(L, "/");
|
||||
lua_pushstring(L, argv0);
|
||||
|
||||
if (!do_isabsolute(argv0)) {
|
||||
lua_concat(L, 3);
|
||||
}
|
||||
else {
|
||||
lua_pop(L, 3);
|
||||
lua_pushstring(L, argv0);
|
||||
}
|
||||
|
||||
path = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
lua_pushstring(L, path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks one or more of the standard script search locations to locate the
|
||||
* specified file. If found, returns the discovered path to the script on
|
||||
* the top of the Lua stack.
|
||||
*/
|
||||
int premake_test_file(lua_State* L, const char* filename, int searchMask)
|
||||
{
|
||||
if (searchMask & TEST_LOCAL) {
|
||||
if (do_isfile(L, filename)) {
|
||||
lua_pushcfunction(L, path_getabsolute);
|
||||
lua_pushstring(L, filename);
|
||||
lua_call(L, 1, 1);
|
||||
return OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
if (scripts_path && (searchMask & TEST_SCRIPTS)) {
|
||||
if (do_locate(L, filename, scripts_path)) return OKAY;
|
||||
}
|
||||
|
||||
if (searchMask & TEST_PATH) {
|
||||
const char* path = getenv("PREMAKE_PATH");
|
||||
if (path && do_locate(L, filename, path)) return OKAY;
|
||||
}
|
||||
|
||||
#if !defined(PREMAKE_NO_BUILTIN_SCRIPTS)
|
||||
if ((searchMask & TEST_EMBEDDED) != 0) {
|
||||
/* Try to locate a record matching the filename */
|
||||
if (premake_find_embedded_script(filename) != NULL) {
|
||||
lua_pushstring(L, "$/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 2);
|
||||
return OKAY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char* set_scripts_path(const char* relativePath)
|
||||
{
|
||||
char* path = (char*)malloc(PATH_MAX);
|
||||
do_getabsolute(path, relativePath, NULL);
|
||||
scripts_path = path;
|
||||
return scripts_path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the premake.path variable, pulling from the --scripts argument
|
||||
* and PREMAKE_PATH environment variable if present.
|
||||
*/
|
||||
static void build_premake_path(lua_State* L)
|
||||
{
|
||||
int top;
|
||||
const char* value;
|
||||
|
||||
lua_getglobal(L, "premake");
|
||||
top = lua_gettop(L);
|
||||
|
||||
/* Start by searching the current working directory */
|
||||
lua_pushstring(L, ".");
|
||||
|
||||
/* The --scripts argument goes next, if present */
|
||||
if (scripts_path) {
|
||||
lua_pushstring(L, ";");
|
||||
lua_pushstring(L, scripts_path);
|
||||
}
|
||||
|
||||
/* Then the PREMAKE_PATH environment variable */
|
||||
value = getenv("PREMAKE_PATH");
|
||||
if (value) {
|
||||
lua_pushstring(L, ";");
|
||||
lua_pushstring(L, value);
|
||||
}
|
||||
|
||||
/* Then in ~/.premake */
|
||||
lua_pushstring(L, ";");
|
||||
lua_getglobal(L, "_USER_HOME_DIR");
|
||||
lua_pushstring(L, "/.premake");
|
||||
|
||||
/* In the user's Application Support folder */
|
||||
#if defined(PLATFORM_MACOSX)
|
||||
lua_pushstring(L, ";");
|
||||
lua_getglobal(L, "_USER_HOME_DIR");
|
||||
lua_pushstring(L, "/Library/Application Support/Premake");
|
||||
#endif
|
||||
|
||||
/* In the /usr tree */
|
||||
lua_pushstring(L, ";/usr/local/share/premake;/usr/share/premake");
|
||||
|
||||
/* Put it all together */
|
||||
lua_concat(L, lua_gettop(L) - top);
|
||||
|
||||
/* Match Lua's package.path; use semicolon separators */
|
||||
#if !defined(PLATFORM_WINDOWS)
|
||||
lua_getglobal(L, "string");
|
||||
lua_getfield(L, -1, "gsub");
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushstring(L, ":");
|
||||
lua_pushstring(L, ";");
|
||||
lua_call(L, 3, 1);
|
||||
/* remove the string global table */
|
||||
lua_remove(L, -2);
|
||||
/* remove the previously concatonated result */
|
||||
lua_remove(L, -2);
|
||||
#endif
|
||||
|
||||
/* Store it in premake.path */
|
||||
lua_setfield(L, -2, "path");
|
||||
|
||||
/* Remove the premake namespace table */
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Copy all command line arguments into the script-side _ARGV global, and
|
||||
* check for the presence of a /scripts=<path> argument to help locate
|
||||
* the manifest if needed.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
static int process_arguments(lua_State* L, int argc, const char** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Copy all arguments in the _ARGV global */
|
||||
lua_newtable(L);
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
lua_pushstring(L, argv[i]);
|
||||
lua_rawseti(L, -2, luaL_len(L, -2) + 1);
|
||||
|
||||
/* The /scripts option gets picked up here; used later to find the
|
||||
* manifest and scripts later if necessary */
|
||||
if (strncmp(argv[i], "/scripts=", 9) == 0)
|
||||
{
|
||||
argv[i] = set_scripts_path(argv[i] + 9);
|
||||
}
|
||||
else if (strncmp(argv[i], "--scripts=", 10) == 0)
|
||||
{
|
||||
argv[i] = set_scripts_path(argv[i] + 10);
|
||||
}
|
||||
}
|
||||
lua_setglobal(L, "_ARGV");
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find and run the main Premake bootstrapping script. The loading of the
|
||||
* bootstrap and the other core scripts use a limited set of search paths
|
||||
* to avoid mismatches between the native host code and the scripts
|
||||
* themselves.
|
||||
*/
|
||||
static int run_premake_main(lua_State* L, const char* script)
|
||||
{
|
||||
/* Release builds want to load the embedded scripts, with --scripts
|
||||
* argument allowed as an override. Debug builds will look at the
|
||||
* local file system first, then fall back to embedded. */
|
||||
#if defined(NDEBUG)
|
||||
int z = premake_test_file(L, script,
|
||||
TEST_SCRIPTS | TEST_EMBEDDED);
|
||||
#else
|
||||
int z = premake_test_file(L, script,
|
||||
TEST_LOCAL | TEST_SCRIPTS | TEST_PATH | TEST_EMBEDDED);
|
||||
#endif
|
||||
|
||||
/* If no embedded script can be found, release builds will then
|
||||
* try to fall back to the local file system, just in case */
|
||||
#if defined(NDEBUG)
|
||||
if (z != OKAY) {
|
||||
z = premake_test_file(L, script, TEST_LOCAL | TEST_PATH);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (z == OKAY) {
|
||||
const char* filename = lua_tostring(L, -1);
|
||||
z = luaL_dofile(L, filename);
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Locate a file in the embedded script index. If found, returns the
|
||||
* contents of the file's script.
|
||||
*/
|
||||
|
||||
const buildin_mapping* premake_find_embedded_script(const char* filename)
|
||||
{
|
||||
#if !defined(PREMAKE_NO_BUILTIN_SCRIPTS)
|
||||
int i;
|
||||
for (i = 0; builtin_scripts[i].name != NULL; ++i) {
|
||||
if (strcmp(builtin_scripts[i].name, filename) == 0) {
|
||||
return builtin_scripts + i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load a script that was previously embedded into the executable. If
|
||||
* successful, a function containing the new script chunk is pushed to
|
||||
* the stack, just like luaL_loadfile would do had the chunk been loaded
|
||||
* from a file.
|
||||
*/
|
||||
|
||||
int premake_load_embedded_script(lua_State* L, const char* filename)
|
||||
{
|
||||
#if !defined(NDEBUG)
|
||||
static int warned = 0;
|
||||
#endif
|
||||
|
||||
const buildin_mapping* chunk = premake_find_embedded_script(filename);
|
||||
if (chunk == NULL) {
|
||||
return LUA_ERRFILE;
|
||||
}
|
||||
|
||||
/* Debug builds probably want to be loading scripts from the disk */
|
||||
#if !defined(NDEBUG)
|
||||
if (!warned) {
|
||||
warned = 1;
|
||||
printf("** warning: using embedded script '%s'; use /scripts argument to load from files\n", filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* "Fully qualify" the filename by turning it into the form $/filename */
|
||||
lua_pushstring(L, "$/");
|
||||
lua_pushstring(L, filename);
|
||||
lua_concat(L, 2);
|
||||
|
||||
/* Load the chunk */
|
||||
return luaL_loadbuffer(L, (const char*)chunk->bytecode, chunk->length, filename);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Give the lua runtime raw access to embedded files.
|
||||
*/
|
||||
int premake_getEmbeddedResource(lua_State* L)
|
||||
{
|
||||
const char* filename = luaL_checkstring(L, 1);
|
||||
const buildin_mapping* chunk = premake_find_embedded_script(filename);
|
||||
if (chunk == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushlstring(L, (const char*)chunk->bytecode, chunk->length);
|
||||
return 1;
|
||||
}
|
||||
201
Src/external_dependencies/openmpt-trunk/include/premake/src/host/premake.h
vendored
Normal file
201
Src/external_dependencies/openmpt-trunk/include/premake/src/host/premake.h
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* \file premake.h
|
||||
* \brief Program-wide constants and definitions.
|
||||
* \author Copyright (c) 2002-2021 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#define lua_c
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define PREMAKE_VERSION "5.0.0-beta1"
|
||||
#define PREMAKE_COPYRIGHT "Copyright (C) 2002-2021 Jason Perkins and the Premake Project"
|
||||
#define PREMAKE_PROJECT_URL "https://github.com/premake/premake-core/wiki"
|
||||
|
||||
/* Identify the current platform I'm not sure how to reliably detect
|
||||
* Windows but since it is the most common I use it as the default */
|
||||
#if defined(__linux__)
|
||||
#define PLATFORM_LINUX (1)
|
||||
#define PLATFORM_STRING "linux"
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
#define PLATFORM_BSD (1)
|
||||
#define PLATFORM_STRING "bsd"
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#define PLATFORM_MACOSX (1)
|
||||
#define PLATFORM_STRING "macosx"
|
||||
#elif defined(__sun__) && defined(__svr4__)
|
||||
#define PLATFORM_SOLARIS (1)
|
||||
#define PLATFORM_STRING "solaris"
|
||||
#elif defined(__HAIKU__)
|
||||
#define PLATFORM_HAIKU (1)
|
||||
#define PLATFORM_STRING "haiku"
|
||||
#elif defined (_AIX)
|
||||
#define PLATFORM_AIX (1)
|
||||
#define PLATFORM_STRING "aix"
|
||||
#elif defined (__GNU__)
|
||||
#define PLATFORM_HURD (1)
|
||||
#define PLATFORM_STRING "hurd"
|
||||
#else
|
||||
#define PLATFORM_WINDOWS (1)
|
||||
#define PLATFORM_STRING "windows"
|
||||
#endif
|
||||
|
||||
#define PLATFORM_POSIX (PLATFORM_LINUX || PLATFORM_BSD || PLATFORM_MACOSX || PLATFORM_SOLARIS || PLATFORM_HAIKU)
|
||||
|
||||
|
||||
/* Pull in platform-specific headers required by built-in functions */
|
||||
#if PLATFORM_WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
/* not all platforms define this */
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/* Fill in any missing bits */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX (4096)
|
||||
#endif
|
||||
|
||||
|
||||
/* A success return code */
|
||||
#define OKAY (0)
|
||||
|
||||
|
||||
/* Bitmasks for the different script file search locations */
|
||||
#define TEST_LOCAL (0x01)
|
||||
#define TEST_SCRIPTS (0x02)
|
||||
#define TEST_PATH (0x04)
|
||||
#define TEST_EMBEDDED (0x08)
|
||||
|
||||
|
||||
/* If a /scripts argument is present, its value */
|
||||
extern const char* scripts_path;
|
||||
|
||||
|
||||
/* Bootstrapping helper functions */
|
||||
int do_chdir(lua_State* L, const char* path);
|
||||
uint32_t do_hash(const char* str, int seed);
|
||||
void do_getabsolute(char* result, const char* value, const char* relative_to);
|
||||
int do_getcwd(char* buffer, size_t size);
|
||||
int do_isabsolute(const char* path);
|
||||
int do_absolutetype(const char* path);
|
||||
int do_isfile(lua_State* L, const char* filename);
|
||||
int do_locate(lua_State* L, const char* filename, const char* path);
|
||||
void do_normalize(lua_State* L, char* buffer, const char* path);
|
||||
int do_pathsearch(lua_State* L, const char* filename, const char* path);
|
||||
void do_translate(char* value, const char sep);
|
||||
|
||||
int term_doGetTextColor();
|
||||
void term_doSetTextColor(int color);
|
||||
void printLastError(lua_State* L);
|
||||
|
||||
/* Built-in functions */
|
||||
int criteria_compile(lua_State* L);
|
||||
int criteria_delete(lua_State* L);
|
||||
int criteria_matches(lua_State* L);
|
||||
int debug_prompt(lua_State* L);
|
||||
int path_getabsolute(lua_State* L);
|
||||
int path_getrelative(lua_State* L);
|
||||
int path_isabsolute(lua_State* L);
|
||||
int path_join(lua_State* L);
|
||||
int path_deferred_join(lua_State* L);
|
||||
int path_has_deferred_join(lua_State* L);
|
||||
int path_resolve_deferred_join(lua_State* L);
|
||||
int path_normalize(lua_State* L);
|
||||
int path_translate(lua_State* L);
|
||||
int path_wildcards(lua_State* L);
|
||||
int os_chdir(lua_State* L);
|
||||
int os_chmod(lua_State* L);
|
||||
int os_comparefiles(lua_State* L);
|
||||
int os_copyfile(lua_State* L);
|
||||
int os_getcwd(lua_State* L);
|
||||
int os_getpass(lua_State* L);
|
||||
int os_getWindowsRegistry(lua_State* L);
|
||||
int os_listWindowsRegistry(lua_State* L);
|
||||
int os_getversion(lua_State* L);
|
||||
int os_host(lua_State* L);
|
||||
int os_is64bit(lua_State* L);
|
||||
int os_isdir(lua_State* L);
|
||||
int os_isfile(lua_State* L);
|
||||
int os_islink(lua_State* L);
|
||||
int os_locate(lua_State* L);
|
||||
int os_matchdone(lua_State* L);
|
||||
int os_matchisfile(lua_State* L);
|
||||
int os_matchname(lua_State* L);
|
||||
int os_matchnext(lua_State* L);
|
||||
int os_matchstart(lua_State* L);
|
||||
int os_mkdir(lua_State* L);
|
||||
int os_pathsearch(lua_State* L);
|
||||
int os_realpath(lua_State* L);
|
||||
#if PLATFORM_WINDOWS
|
||||
// utf8 versions
|
||||
int os_remove(lua_State* L);
|
||||
int os_rename(lua_State* L);
|
||||
#endif
|
||||
int os_rmdir(lua_State* L);
|
||||
int os_stat(lua_State* L);
|
||||
int os_uuid(lua_State* L);
|
||||
int os_writefile_ifnotequal(lua_State* L);
|
||||
int os_touchfile(lua_State* L);
|
||||
int os_compile(lua_State* L);
|
||||
int premake_getEmbeddedResource(lua_State* L);
|
||||
int string_endswith(lua_State* L);
|
||||
int string_hash(lua_State* L);
|
||||
int string_sha1(lua_State* L);
|
||||
int string_startswith(lua_State* L);
|
||||
int buffered_new(lua_State* L);
|
||||
int buffered_write(lua_State* L);
|
||||
int buffered_writeln(lua_State* L);
|
||||
int buffered_close(lua_State* L);
|
||||
int buffered_tostring(lua_State* L);
|
||||
int term_getTextColor(lua_State* L);
|
||||
int term_setTextColor(lua_State* L);
|
||||
|
||||
#ifdef PREMAKE_CURL
|
||||
int http_get(lua_State* L);
|
||||
int http_post(lua_State* L);
|
||||
int http_download(lua_State* L);
|
||||
#endif
|
||||
|
||||
#ifdef PREMAKE_COMPRESSION
|
||||
int zip_extract(lua_State* L);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef snprintf
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Engine interface */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* name;
|
||||
const unsigned char* bytecode;
|
||||
size_t length;
|
||||
} buildin_mapping;
|
||||
|
||||
extern const buildin_mapping builtin_scripts[];
|
||||
extern void registerModules(lua_State* L);
|
||||
|
||||
int premake_init(lua_State* L);
|
||||
int premake_pcall(lua_State* L, int nargs, int nresults);
|
||||
int premake_execute(lua_State* L, int argc, const char** argv, const char* script);
|
||||
int premake_load_embedded_script(lua_State* L, const char* filename);
|
||||
const buildin_mapping* premake_find_embedded_script(const char* filename);
|
||||
|
||||
int premake_locate_executable(lua_State* L, const char* argv0);
|
||||
int premake_test_file(lua_State* L, const char* filename, int searchMask);
|
||||
24
Src/external_dependencies/openmpt-trunk/include/premake/src/host/premake_main.c
vendored
Normal file
24
Src/external_dependencies/openmpt-trunk/include/premake/src/host/premake_main.c
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* \file premake_main.c
|
||||
* \brief Program entry point.
|
||||
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
lua_State* L;
|
||||
int z;
|
||||
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
z = premake_init(L);
|
||||
if (z == OKAY) {
|
||||
z = premake_execute(L, argc, argv, "src/_premake_main.lua");
|
||||
}
|
||||
|
||||
lua_close(L);
|
||||
return z;
|
||||
}
|
||||
16
Src/external_dependencies/openmpt-trunk/include/premake/src/host/resource.h
vendored
Normal file
16
Src/external_dependencies/openmpt-trunk/include/premake/src/host/resource.h
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
107
Src/external_dependencies/openmpt-trunk/include/premake/src/host/resource.rc
vendored
Normal file
107
Src/external_dependencies/openmpt-trunk/include/premake/src/host/resource.rc
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
#include "premake.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 5,0,0
|
||||
PRODUCTVERSION 5,0,0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Jason Perkins and the Premake Project"
|
||||
VALUE "FileDescription", "Premake5"
|
||||
VALUE "FileVersion", PREMAKE_VERSION
|
||||
VALUE "LegalCopyright", PREMAKE_COPYRIGHT
|
||||
VALUE "OriginalFilename", "premake5.exe"
|
||||
VALUE "ProductName", "Premake5"
|
||||
VALUE "ProductVersion", PREMAKE_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
//IDI_ICON1 ICON ""
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
28
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_endswith.c
vendored
Normal file
28
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_endswith.c
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* \file string_endswith.c
|
||||
* \brief Determines if a string ends with the given sequence.
|
||||
* \author Copyright (c) 2002-2009 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int string_endswith(lua_State* L)
|
||||
{
|
||||
const char* haystack = luaL_optstring(L, 1, NULL);
|
||||
const char* needle = luaL_optstring(L, 2, NULL);
|
||||
|
||||
if (haystack && needle)
|
||||
{
|
||||
size_t hlen = strlen(haystack);
|
||||
size_t nlen = strlen(needle);
|
||||
if (hlen >= nlen)
|
||||
{
|
||||
lua_pushboolean(L, strcmp(haystack + hlen - nlen, needle) == 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_hash.c
vendored
Normal file
36
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_hash.c
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* \file string_hash.c
|
||||
* \brief Computes a hash value for a string.
|
||||
* \author Copyright (c) 2012-2014 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int string_hash(lua_State* L)
|
||||
{
|
||||
const char* str = luaL_checkstring(L, 1);
|
||||
int seed = (int)luaL_optinteger(L, 2, 0);
|
||||
lua_pushinteger(L, do_hash(str, seed));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t do_hash(const char* str, int seed)
|
||||
{
|
||||
/* DJB2 hashing; see http://www.cse.yorku.ca/~oz/hash.html */
|
||||
|
||||
uint32_t hash = 5381;
|
||||
|
||||
if (seed != 0) {
|
||||
hash = hash * 33 + seed;
|
||||
}
|
||||
|
||||
while (*str) {
|
||||
hash = hash * 33 + (*str);
|
||||
str++;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
185
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_sha1.c
vendored
Normal file
185
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_sha1.c
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
|
||||
#define HASH_LENGTH 20
|
||||
#define BLOCK_LENGTH 64
|
||||
|
||||
typedef struct sha1nfo {
|
||||
uint32_t buffer[BLOCK_LENGTH / 4];
|
||||
uint32_t state[HASH_LENGTH / 4];
|
||||
uint32_t byteCount;
|
||||
uint8_t bufferOffset;
|
||||
uint8_t keyBuffer[BLOCK_LENGTH];
|
||||
uint8_t innerHash[HASH_LENGTH];
|
||||
} sha1nfo;
|
||||
|
||||
/* public API - prototypes - TODO: doxygen*/
|
||||
void sha1_init(sha1nfo *s);
|
||||
void sha1_writebyte(sha1nfo *s, uint8_t data);
|
||||
void sha1_write(sha1nfo *s, const char *data, size_t len);
|
||||
uint8_t* sha1_result(sha1nfo *s);
|
||||
|
||||
/* code */
|
||||
#define SHA1_K0 0x5a827999
|
||||
#define SHA1_K20 0x6ed9eba1
|
||||
#define SHA1_K40 0x8f1bbcdc
|
||||
#define SHA1_K60 0xca62c1d6
|
||||
|
||||
void sha1_init(sha1nfo *s)
|
||||
{
|
||||
s->state[0] = 0x67452301;
|
||||
s->state[1] = 0xefcdab89;
|
||||
s->state[2] = 0x98badcfe;
|
||||
s->state[3] = 0x10325476;
|
||||
s->state[4] = 0xc3d2e1f0;
|
||||
s->byteCount = 0;
|
||||
s->bufferOffset = 0;
|
||||
}
|
||||
|
||||
uint32_t sha1_rol32(uint32_t number, uint8_t bits)
|
||||
{
|
||||
return ((number << bits) | (number >> (32 - bits)));
|
||||
}
|
||||
|
||||
void sha1_hashBlock(sha1nfo *s)
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t a, b, c, d, e, t;
|
||||
|
||||
a = s->state[0];
|
||||
b = s->state[1];
|
||||
c = s->state[2];
|
||||
d = s->state[3];
|
||||
e = s->state[4];
|
||||
for (i = 0; i < 80; i++)
|
||||
{
|
||||
if (i >= 16)
|
||||
{
|
||||
t = s->buffer[(i + 13) & 15] ^ s->buffer[(i + 8) & 15] ^ s->buffer[(i + 2) & 15] ^ s->buffer[i & 15];
|
||||
s->buffer[i & 15] = sha1_rol32(t, 1);
|
||||
}
|
||||
if (i < 20)
|
||||
{
|
||||
t = (d ^ (b & (c ^ d))) + SHA1_K0;
|
||||
}
|
||||
else if (i < 40)
|
||||
{
|
||||
t = (b ^ c ^ d) + SHA1_K20;
|
||||
}
|
||||
else if (i < 60)
|
||||
{
|
||||
t = ((b & c) | (d & (b | c))) + SHA1_K40;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = (b ^ c ^ d) + SHA1_K60;
|
||||
}
|
||||
t += sha1_rol32(a, 5) + e + s->buffer[i & 15];
|
||||
e = d;
|
||||
d = c;
|
||||
c = sha1_rol32(b, 30);
|
||||
b = a;
|
||||
a = t;
|
||||
}
|
||||
s->state[0] += a;
|
||||
s->state[1] += b;
|
||||
s->state[2] += c;
|
||||
s->state[3] += d;
|
||||
s->state[4] += e;
|
||||
}
|
||||
|
||||
void sha1_addUncounted(sha1nfo *s, uint8_t data)
|
||||
{
|
||||
uint8_t * const b = (uint8_t*)s->buffer;
|
||||
b[s->bufferOffset ^ 3] = data;
|
||||
s->bufferOffset++;
|
||||
if (s->bufferOffset == BLOCK_LENGTH)
|
||||
{
|
||||
sha1_hashBlock(s);
|
||||
s->bufferOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sha1_writebyte(sha1nfo *s, uint8_t data)
|
||||
{
|
||||
++s->byteCount;
|
||||
sha1_addUncounted(s, data);
|
||||
}
|
||||
|
||||
void sha1_write(sha1nfo *s, const char *data, size_t len)
|
||||
{
|
||||
for (; len--;) sha1_writebyte(s, (uint8_t)*data++);
|
||||
}
|
||||
|
||||
void sha1_pad(sha1nfo *s)
|
||||
{
|
||||
// Implement SHA-1 padding (fips180-2 §5.1.1)
|
||||
|
||||
// Pad with 0x80 followed by 0x00 until the end of the block
|
||||
sha1_addUncounted(s, 0x80);
|
||||
while (s->bufferOffset != 56) sha1_addUncounted(s, 0x00);
|
||||
|
||||
// Append length in the last 8 bytes
|
||||
sha1_addUncounted(s, 0); // We're only using 32 bit lengths
|
||||
sha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths
|
||||
sha1_addUncounted(s, 0); // So zero pad the top bits
|
||||
sha1_addUncounted(s, s->byteCount >> 29); // Shifting to multiply by 8
|
||||
sha1_addUncounted(s, (uint8_t)(s->byteCount >> 21)); // as SHA-1 supports bitstreams as well as
|
||||
sha1_addUncounted(s, (uint8_t)(s->byteCount >> 13)); // byte.
|
||||
sha1_addUncounted(s, (uint8_t)(s->byteCount >> 5));
|
||||
sha1_addUncounted(s, (uint8_t)(s->byteCount << 3));
|
||||
}
|
||||
|
||||
uint8_t* sha1_result(sha1nfo *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Pad to complete the last block
|
||||
sha1_pad(s);
|
||||
|
||||
// Swap byte order back
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
s->state[i] =
|
||||
(((s->state[i]) << 24) & 0xff000000)
|
||||
| (((s->state[i]) << 8) & 0x00ff0000)
|
||||
| (((s->state[i]) >> 8) & 0x0000ff00)
|
||||
| (((s->state[i]) >> 24) & 0x000000ff);
|
||||
}
|
||||
|
||||
// Return pointer to hash (20 characters)
|
||||
return (uint8_t*)s->state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int string_sha1(lua_State* L)
|
||||
{
|
||||
static const char* g_int2hex = "0123456789ABCDEF";
|
||||
uint8_t* result;
|
||||
size_t l;
|
||||
sha1nfo s;
|
||||
int i;
|
||||
char output[41];
|
||||
|
||||
const char *str = luaL_checklstring(L, 1, &l);
|
||||
if (str != NULL)
|
||||
{
|
||||
sha1_init(&s);
|
||||
sha1_write(&s, str, l);
|
||||
result = sha1_result(&s);
|
||||
|
||||
for (i = 0; i < 20; ++i)
|
||||
{
|
||||
output[i * 2 + 0] = g_int2hex[result[i] & 0x0f];
|
||||
output[i * 2 + 1] = g_int2hex[result[i] >> 4];
|
||||
}
|
||||
output[40] = 0;
|
||||
|
||||
lua_pushlstring(L, output, 40);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
24
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_startswith.c
vendored
Normal file
24
Src/external_dependencies/openmpt-trunk/include/premake/src/host/string_startswith.c
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* \file string_startswith.c
|
||||
* \brief Determines if a string starts with the given sequence.
|
||||
* \author Copyright (c) 2013 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int string_startswith(lua_State* L)
|
||||
{
|
||||
const char* haystack = luaL_optstring(L, 1, NULL);
|
||||
const char* needle = luaL_optstring(L, 2, NULL);
|
||||
|
||||
if (haystack && needle)
|
||||
{
|
||||
size_t nlen = strlen(needle);
|
||||
lua_pushboolean(L, strncmp(haystack, needle, nlen) == 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
114
Src/external_dependencies/openmpt-trunk/include/premake/src/host/term_textColor.c
vendored
Normal file
114
Src/external_dependencies/openmpt-trunk/include/premake/src/host/term_textColor.c
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* \file term_textColor.c
|
||||
* \brief Change the foreground color of the terminal output.
|
||||
* \author Copyright (c) 2017 Blizzard Entertainment and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if PLATFORM_POSIX
|
||||
static int s_currentColor = -1;
|
||||
#endif
|
||||
|
||||
int canUseColors()
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
return _isatty(_fileno(stdout));
|
||||
#else
|
||||
return isatty(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *getenvOrFallback(const char *var, const char *fallback)
|
||||
{
|
||||
const char *value = getenv(var);
|
||||
return (value != NULL) ? value : fallback;
|
||||
}
|
||||
|
||||
static int s_shouldUseColor = -1;
|
||||
static int shouldUseColors()
|
||||
{
|
||||
if (s_shouldUseColor < 0)
|
||||
{
|
||||
// CLICOLOR* documented at: http://bixense.com/clicolors/
|
||||
s_shouldUseColor = ((getenvOrFallback("CLICOLOR", "1")[0] != '0') && canUseColors())
|
||||
|| getenvOrFallback("CLICOLOR_FORCE", "0")[0] != '0';
|
||||
}
|
||||
return s_shouldUseColor;
|
||||
}
|
||||
|
||||
int term_doGetTextColor()
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info))
|
||||
return -1;
|
||||
return (int)info.wAttributes;
|
||||
#else
|
||||
return s_currentColor;
|
||||
#endif
|
||||
}
|
||||
|
||||
void term_doSetTextColor(int color)
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
if (color >= 0 && shouldUseColors())
|
||||
{
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (WORD)color);
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), (WORD)color);
|
||||
}
|
||||
#else
|
||||
|
||||
// Do not output colors e.g. into a pipe, unless forced.
|
||||
if (!shouldUseColors())
|
||||
return;
|
||||
|
||||
s_currentColor = color;
|
||||
|
||||
const char* colorTable[] =
|
||||
{
|
||||
"\x1B[0;30m", // term.black = 0
|
||||
"\x1B[0;34m", // term.blue = 1
|
||||
"\x1B[0;32m", // term.green = 2
|
||||
"\x1B[0;36m", // term.cyan = 3
|
||||
"\x1B[0;31m", // term.red = 4
|
||||
"\x1B[0;35m", // term.purple = 5
|
||||
"\x1B[0;33m", // term.brown = 6
|
||||
"\x1B[0;37m", // term.lightGray = 7
|
||||
"\x1B[1;30m", // term.gray = 8
|
||||
"\x1B[1;34m", // term.lightBlue = 9
|
||||
"\x1B[1;32m", // term.lightGreen = 10
|
||||
"\x1B[1;36m", // term.lightCyan = 11
|
||||
"\x1B[1;31m", // term.lightRed = 12
|
||||
"\x1B[1;35m", // term.magenta = 13
|
||||
"\x1B[1;33m", // term.yellow = 14
|
||||
"\x1B[1;37m", // term.white = 15
|
||||
};
|
||||
if (color >= 0 && color < 16)
|
||||
{
|
||||
fputs(colorTable[color], stdout);
|
||||
} else
|
||||
{
|
||||
fputs("\x1B[0m", stdout);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int term_getTextColor(lua_State* L)
|
||||
{
|
||||
int color = term_doGetTextColor();
|
||||
lua_pushinteger(L, color);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int term_setTextColor(lua_State* L)
|
||||
{
|
||||
term_doSetTextColor((int)luaL_optinteger(L, 1, -1));
|
||||
return 0;
|
||||
}
|
||||
234
Src/external_dependencies/openmpt-trunk/include/premake/src/host/zip_extract.c
vendored
Normal file
234
Src/external_dependencies/openmpt-trunk/include/premake/src/host/zip_extract.c
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* \file os_unzip.c
|
||||
* \brief Unzip file using libzip library.
|
||||
* \author battle.net -- abrunasso.int@blizzard.com
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
|
||||
#ifdef PREMAKE_COMPRESSION
|
||||
|
||||
#include "zip.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
// File Attribute for Unix
|
||||
#define FA_IFIFO 0010000 /* named pipe (fifo) */
|
||||
#define FA_IFCHR 0020000 /* character special */
|
||||
#define FA_IFDIR 0040000 /* directory */
|
||||
#define FA_IFBLK 0060000 /* block special */
|
||||
#define FA_IFREG 0100000 /* regular */
|
||||
#define FA_IFLNK 0120000 /* symbolic link */
|
||||
#define FA_IFSOCK 0140000 /* socket */
|
||||
|
||||
#define FA_ISUID 0004000 /* set user id on execution */
|
||||
#define FA_ISGID 0002000 /* set group id on execution */
|
||||
#define FA_ISTXT 0001000 /* sticky bit */
|
||||
#define FA_IRWXU 0000700 /* RWX mask for owner */
|
||||
#define FA_IRUSR 0000400 /* R for owner */
|
||||
#define FA_IWUSR 0000200 /* W for owner */
|
||||
#define FA_IXUSR 0000100 /* X for owner */
|
||||
#define FA_IRWXG 0000070 /* RWX mask for group */
|
||||
#define FA_IRGRP 0000040 /* R for group */
|
||||
#define FA_IWGRP 0000020 /* W for group */
|
||||
#define FA_IXGRP 0000010 /* X for group */
|
||||
#define FA_IRWXO 0000007 /* RWX mask for other */
|
||||
#define FA_IROTH 0000004 /* R for other */
|
||||
#define FA_IWOTH 0000002 /* W for other */
|
||||
#define FA_IXOTH 0000001 /* X for other */
|
||||
#define FA_ISVTX 0001000 /* save swapped text even after use */
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static int is_symlink(zip_uint8_t opsys, zip_uint32_t attrib)
|
||||
{
|
||||
if (opsys == ZIP_OPSYS_DOS)
|
||||
return (attrib & 0x400) == 0x400; // FILE_ATTRIBUTE_REPARSE_POINT
|
||||
|
||||
if (opsys == ZIP_OPSYS_UNIX)
|
||||
return ((attrib >> 16) & FA_IFLNK) == FA_IFLNK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int is_directory(zip_uint8_t opsys, zip_uint32_t attrib)
|
||||
{
|
||||
if (opsys == ZIP_OPSYS_DOS)
|
||||
return (attrib & 0x10) == 0x10; // FILE_ATTRIBUTE_DIRECTORY
|
||||
|
||||
if (opsys == ZIP_OPSYS_UNIX)
|
||||
return ((attrib >> 16) & FA_IFDIR) == FA_IFDIR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int write_link(const char* filename, const char* bytes, size_t count)
|
||||
{
|
||||
#if PLATFORM_POSIX
|
||||
(void)(count);
|
||||
return symlink(bytes, filename);
|
||||
#else
|
||||
FILE* fp = fopen(filename, "wb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("Error creating file:\n %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
fwrite(bytes, sizeof(char), count, fp);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int do_mkdir(const char* path);
|
||||
|
||||
static void parse_path(const char* full_name, char* filename, char* directory)
|
||||
{
|
||||
const char *ssc;
|
||||
size_t orig_length = strlen(full_name);
|
||||
size_t l = 0;
|
||||
size_t dir_size;
|
||||
|
||||
ssc = strstr(full_name, "/");
|
||||
do
|
||||
{
|
||||
l = strlen(ssc) + 1;
|
||||
full_name = &full_name[strlen(full_name) - l + 2];
|
||||
ssc = strstr(full_name, "/");
|
||||
} while (ssc);
|
||||
|
||||
// full_name currently pointing to beginning of filename
|
||||
memcpy(filename, full_name, strlen(full_name));
|
||||
filename[strlen(full_name)] = 0; // Null terminate it
|
||||
|
||||
dir_size = orig_length - strlen(filename);
|
||||
// full_name points to beginning of original string(with directory)
|
||||
full_name = &full_name[strlen(full_name) - orig_length];
|
||||
|
||||
// Extract directory from full name by removing filename
|
||||
memcpy(directory, full_name, dir_size);
|
||||
directory[dir_size] = 0;
|
||||
}
|
||||
|
||||
|
||||
static int extract(const char* src, const char* destination)
|
||||
{
|
||||
int err = 0;
|
||||
FILE *fp = NULL;
|
||||
struct zip *z_archive = zip_open(src, 0, &err);
|
||||
int i;
|
||||
zip_int64_t entries;
|
||||
char buffer[4096];
|
||||
char appended_full_name[512];
|
||||
char directory[512];
|
||||
char filename[512];
|
||||
size_t result;
|
||||
zip_int64_t bytes_read;
|
||||
|
||||
if (!z_archive)
|
||||
{
|
||||
printf("%s does not exist\n", src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0, entries = zip_get_num_entries(z_archive, 0); i < entries; ++i)
|
||||
{
|
||||
zip_uint8_t opsys;
|
||||
zip_uint32_t attrib;
|
||||
const char* full_name;
|
||||
|
||||
struct zip_file* zf = zip_fopen_index(z_archive, i, 0);
|
||||
if (!zf)
|
||||
continue;
|
||||
|
||||
zip_file_get_external_attributes(z_archive, i, 0, &opsys, &attrib);
|
||||
|
||||
full_name = zip_get_name(z_archive, i, 0);
|
||||
|
||||
sprintf(appended_full_name, "%s/%s", destination, full_name);
|
||||
do_translate(appended_full_name, '/');
|
||||
|
||||
parse_path(appended_full_name, filename, directory);
|
||||
do_mkdir(directory);
|
||||
|
||||
// is this a symbolic link?
|
||||
if (is_symlink(opsys, attrib))
|
||||
{
|
||||
bytes_read = zip_fread(zf, buffer, sizeof(buffer));
|
||||
buffer[bytes_read] = '\0';
|
||||
if (write_link(appended_full_name, buffer, (size_t)bytes_read) != 0)
|
||||
{
|
||||
printf(" Failed to create symbolic link [%s->%s]\n", appended_full_name, buffer);
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
{
|
||||
// If blank filename it's just a directory so create it and move on
|
||||
if (!is_directory(opsys, attrib) && strlen(filename) > 0)
|
||||
{
|
||||
// mark as read-write, so we can overwrite the file if it already exists.
|
||||
chmod(appended_full_name, 0666);
|
||||
|
||||
fp = fopen(appended_full_name, "wb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("Error creating file:\n %s\n", appended_full_name);
|
||||
return -1;
|
||||
}
|
||||
for(;;)
|
||||
{
|
||||
// Read content from zipped file
|
||||
bytes_read = zip_fread(zf, buffer, sizeof(buffer));
|
||||
if (bytes_read == 0) break;
|
||||
// Write that content to file
|
||||
result = fwrite(buffer, sizeof(char), (size_t)bytes_read, fp);
|
||||
// If all bytes read weren't written, report error
|
||||
if (result != (size_t)bytes_read)
|
||||
{
|
||||
printf(" Writing data to %s failed\n %d bytes were written\n %d bytes were attempted to be written\n File may be corrupt\n",
|
||||
appended_full_name, (int)result, (int)bytes_read);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
// mark read-only, but maintain the other properties.
|
||||
if (opsys == ZIP_OPSYS_UNIX)
|
||||
chmod(appended_full_name, (attrib >> 16) & ~0222);
|
||||
else
|
||||
chmod(appended_full_name, 0444);
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
zip_fclose(zf);
|
||||
}
|
||||
zip_close(z_archive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int zip_extract(lua_State* L)
|
||||
{
|
||||
const char* src = luaL_checkstring(L, 1);
|
||||
const char* dst = luaL_checkstring(L, 2);
|
||||
|
||||
int res = extract(src, dst);
|
||||
|
||||
lua_pushnumber(L, (lua_Number)res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
336
Src/external_dependencies/openmpt-trunk/include/premake/src/tools/clang.lua
vendored
Normal file
336
Src/external_dependencies/openmpt-trunk/include/premake/src/tools/clang.lua
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
--
|
||||
-- clang.lua
|
||||
-- Clang toolset adapter for Premake
|
||||
-- Copyright (c) 2013 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local p = premake
|
||||
p.tools.clang = {}
|
||||
local clang = p.tools.clang
|
||||
local gcc = p.tools.gcc
|
||||
local config = p.config
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Build a list of flags for the C preprocessor corresponding to the
|
||||
-- settings in a particular project configuration.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- An array of C preprocessor flags.
|
||||
--
|
||||
|
||||
function clang.getcppflags(cfg)
|
||||
|
||||
-- Just pass through to GCC for now
|
||||
local flags = gcc.getcppflags(cfg)
|
||||
return flags
|
||||
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Build a list of C compiler flags corresponding to the settings in
|
||||
-- a particular project configuration. These flags are exclusive
|
||||
-- of the C++ compiler flags, there is no overlap.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- An array of C compiler flags.
|
||||
--
|
||||
|
||||
clang.shared = {
|
||||
architecture = gcc.shared.architecture,
|
||||
flags = gcc.shared.flags,
|
||||
floatingpoint = {
|
||||
Fast = "-ffast-math",
|
||||
},
|
||||
strictaliasing = gcc.shared.strictaliasing,
|
||||
optimize = {
|
||||
Off = "-O0",
|
||||
On = "-O2",
|
||||
Debug = "-O0",
|
||||
Full = "-O3",
|
||||
Size = "-Os",
|
||||
Speed = "-O3",
|
||||
},
|
||||
pic = gcc.shared.pic,
|
||||
vectorextensions = gcc.shared.vectorextensions,
|
||||
isaextensions = gcc.shared.isaextensions,
|
||||
warnings = gcc.shared.warnings,
|
||||
symbols = gcc.shared.symbols,
|
||||
unsignedchar = gcc.shared.unsignedchar,
|
||||
omitframepointer = gcc.shared.omitframepointer,
|
||||
compileas = gcc.shared.compileas
|
||||
}
|
||||
|
||||
clang.cflags = table.merge(gcc.cflags, {
|
||||
})
|
||||
|
||||
function clang.getcflags(cfg)
|
||||
local shared = config.mapFlags(cfg, clang.shared)
|
||||
local cflags = config.mapFlags(cfg, clang.cflags)
|
||||
|
||||
local flags = table.join(shared, cflags)
|
||||
flags = table.join(flags, clang.getwarnings(cfg), clang.getsystemversionflags(cfg))
|
||||
|
||||
return flags
|
||||
end
|
||||
|
||||
function clang.getwarnings(cfg)
|
||||
return gcc.getwarnings(cfg)
|
||||
end
|
||||
|
||||
--
|
||||
-- Returns C/C++ system version related build flags
|
||||
--
|
||||
|
||||
function clang.getsystemversionflags(cfg)
|
||||
local flags = {}
|
||||
|
||||
if cfg.system == p.MACOSX or cfg.system == p.IOS then
|
||||
local minVersion = p.project.systemversion(cfg)
|
||||
if minVersion ~= nil then
|
||||
local name = iif(cfg.system == p.MACOSX, "macosx", "iphoneos")
|
||||
table.insert (flags, "-m" .. name .. "-version-min=" .. p.project.systemversion(cfg))
|
||||
end
|
||||
end
|
||||
|
||||
return flags
|
||||
end
|
||||
|
||||
--
|
||||
-- Build a list of C++ compiler flags corresponding to the settings
|
||||
-- in a particular project configuration. These flags are exclusive
|
||||
-- of the C compiler flags, there is no overlap.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- An array of C++ compiler flags.
|
||||
--
|
||||
|
||||
clang.cxxflags = table.merge(gcc.cxxflags, {
|
||||
})
|
||||
|
||||
function clang.getcxxflags(cfg)
|
||||
local shared = config.mapFlags(cfg, clang.shared)
|
||||
local cxxflags = config.mapFlags(cfg, clang.cxxflags)
|
||||
local flags = table.join(shared, cxxflags)
|
||||
flags = table.join(flags, clang.getwarnings(cfg), clang.getsystemversionflags(cfg))
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns a list of defined preprocessor symbols, decorated for
|
||||
-- the compiler command line.
|
||||
--
|
||||
-- @param defines
|
||||
-- An array of preprocessor symbols to define; as an array of
|
||||
-- string values.
|
||||
-- @return
|
||||
-- An array of symbols with the appropriate flag decorations.
|
||||
--
|
||||
|
||||
function clang.getdefines(defines)
|
||||
|
||||
-- Just pass through to GCC for now
|
||||
local flags = gcc.getdefines(defines)
|
||||
return flags
|
||||
|
||||
end
|
||||
|
||||
function clang.getundefines(undefines)
|
||||
|
||||
-- Just pass through to GCC for now
|
||||
local flags = gcc.getundefines(undefines)
|
||||
return flags
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns a list of forced include files, decorated for the compiler
|
||||
-- command line.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- An array of force include files with the appropriate flags.
|
||||
--
|
||||
|
||||
function clang.getforceincludes(cfg)
|
||||
|
||||
-- Just pass through to GCC for now
|
||||
local flags = gcc.getforceincludes(cfg)
|
||||
return flags
|
||||
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns a list of include file search directories, decorated for
|
||||
-- the compiler command line.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @param dirs
|
||||
-- An array of include file search directories; as an array of
|
||||
-- string values.
|
||||
-- @return
|
||||
-- An array of symbols with the appropriate flag decorations.
|
||||
--
|
||||
|
||||
function clang.getincludedirs(cfg, dirs, sysdirs, frameworkdirs)
|
||||
|
||||
-- Just pass through to GCC for now
|
||||
local flags = gcc.getincludedirs(cfg, dirs, sysdirs, frameworkdirs)
|
||||
return flags
|
||||
|
||||
end
|
||||
|
||||
clang.getrunpathdirs = gcc.getrunpathdirs
|
||||
|
||||
--
|
||||
-- get the right output flag.
|
||||
--
|
||||
function clang.getsharedlibarg(cfg)
|
||||
return gcc.getsharedlibarg(cfg)
|
||||
end
|
||||
|
||||
--
|
||||
-- Build a list of linker flags corresponding to the settings in
|
||||
-- a particular project configuration.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- An array of linker flags.
|
||||
--
|
||||
|
||||
clang.ldflags = {
|
||||
architecture = {
|
||||
x86 = "-m32",
|
||||
x86_64 = "-m64",
|
||||
},
|
||||
flags = {
|
||||
LinkTimeOptimization = "-flto",
|
||||
},
|
||||
kind = {
|
||||
SharedLib = function(cfg)
|
||||
local r = { clang.getsharedlibarg(cfg) }
|
||||
if cfg.system == "windows" and not cfg.flags.NoImportLib then
|
||||
table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"')
|
||||
elseif cfg.system == p.LINUX then
|
||||
table.insert(r, '-Wl,-soname=' .. p.quoted(cfg.linktarget.name))
|
||||
elseif table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
table.insert(r, '-Wl,-install_name,' .. p.quoted('@rpath/' .. cfg.linktarget.name))
|
||||
end
|
||||
return r
|
||||
end,
|
||||
WindowedApp = function(cfg)
|
||||
if cfg.system == p.WINDOWS then return "-mwindows" end
|
||||
end,
|
||||
},
|
||||
system = {
|
||||
wii = "$(MACHDEP)",
|
||||
}
|
||||
}
|
||||
|
||||
function clang.getldflags(cfg)
|
||||
local flags = config.mapFlags(cfg, clang.ldflags)
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Build a list of additional library directories for a particular
|
||||
-- project configuration, decorated for the tool command line.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- An array of decorated additional library directories.
|
||||
--
|
||||
|
||||
function clang.getLibraryDirectories(cfg)
|
||||
|
||||
-- Just pass through to GCC for now
|
||||
local flags = gcc.getLibraryDirectories(cfg)
|
||||
return flags
|
||||
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Build a list of libraries to be linked for a particular project
|
||||
-- configuration, decorated for the linker command line.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @param systemOnly
|
||||
-- Boolean flag indicating whether to link only system libraries,
|
||||
-- or system libraries and sibling projects as well.
|
||||
-- @return
|
||||
-- A list of libraries to link, decorated for the linker.
|
||||
--
|
||||
|
||||
function clang.getlinks(cfg, systemonly, nogroups)
|
||||
return gcc.getlinks(cfg, systemonly, nogroups)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Return a list of makefile-specific configuration rules. This will
|
||||
-- be going away when I get a chance to overhaul these adapters.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- A list of additional makefile rules.
|
||||
--
|
||||
|
||||
function clang.getmakesettings(cfg)
|
||||
|
||||
-- Just pass through to GCC for now
|
||||
local flags = gcc.getmakesettings(cfg)
|
||||
return flags
|
||||
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieves the executable command name for a tool, based on the
|
||||
-- provided configuration and the operating environment. I will
|
||||
-- be moving these into global configuration blocks when I get
|
||||
-- the chance.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to query.
|
||||
-- @param tool
|
||||
-- The tool to fetch, one of "cc" for the C compiler, "cxx" for
|
||||
-- the C++ compiler, or "ar" for the static linker.
|
||||
-- @return
|
||||
-- The executable command name for a tool, or nil if the system's
|
||||
-- default value should be used.
|
||||
--
|
||||
|
||||
clang.tools = {
|
||||
cc = "clang",
|
||||
cxx = "clang++",
|
||||
ar = function(cfg) return iif(cfg.flags.LinkTimeOptimization, "llvm-ar", "ar") end
|
||||
}
|
||||
|
||||
function clang.gettoolname(cfg, tool)
|
||||
local value = clang.tools[tool]
|
||||
if type(value) == "function" then
|
||||
value = value(cfg)
|
||||
end
|
||||
return value
|
||||
end
|
||||
329
Src/external_dependencies/openmpt-trunk/include/premake/src/tools/dotnet.lua
vendored
Normal file
329
Src/external_dependencies/openmpt-trunk/include/premake/src/tools/dotnet.lua
vendored
Normal file
@@ -0,0 +1,329 @@
|
||||
--
|
||||
-- dotnet.lua
|
||||
-- Interface for the C# compilers, all of which are flag compatible.
|
||||
-- Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
local p = premake
|
||||
p.tools.dotnet = {}
|
||||
local dotnet = p.tools.dotnet
|
||||
local project = p.project
|
||||
local config = p.config
|
||||
|
||||
|
||||
--
|
||||
-- Examine the file and project configurations to glean additional
|
||||
-- information about a source code in a C# project.
|
||||
--
|
||||
-- @param fcfg
|
||||
-- The file configuration to consider.
|
||||
-- @return
|
||||
-- A table containing the following keys:
|
||||
--
|
||||
-- action: the build action for the file; one of "Compile", "Copy",
|
||||
-- "EmbeddedResource", or "None".
|
||||
-- subtype: an additional categorization of the file type, or nil if
|
||||
-- no subtype is required.
|
||||
-- dependency: a related file name, (i.e. *.Designer.cs) if appropriate
|
||||
-- for the file action and subtype.
|
||||
--
|
||||
|
||||
function dotnet.fileinfo(fcfg)
|
||||
local info = {}
|
||||
if (fcfg == nil) then
|
||||
return info
|
||||
end
|
||||
|
||||
local fname = fcfg.abspath
|
||||
local ext = path.getextension(fname):lower()
|
||||
|
||||
-- Determine the build action for the file, falling back to the file
|
||||
-- extension if no explicit action is available.
|
||||
|
||||
if fcfg.buildaction == "Compile" or ext == ".cs" or ext == ".fs" then
|
||||
info.action = "Compile"
|
||||
elseif fcfg.buildaction == "Embed" or ext == ".resx" then
|
||||
info.action = "EmbeddedResource"
|
||||
elseif fcfg.buildaction == "Copy" or ext == ".asax" or ext == ".aspx" or ext == ".dll" or ext == ".tt" then
|
||||
info.action = "Content"
|
||||
elseif fcfg.buildaction == "Resource" then
|
||||
info.action = "Resource"
|
||||
elseif ext == ".xaml" then
|
||||
if fcfg.buildaction == "Application" or path.getbasename(fname) == "App" then
|
||||
if fcfg.project.kind == p.SHAREDLIB then
|
||||
info.action = "None"
|
||||
else
|
||||
info.action = "ApplicationDefinition"
|
||||
end
|
||||
else
|
||||
info.action = "Page"
|
||||
end
|
||||
else
|
||||
info.action = "None"
|
||||
end
|
||||
|
||||
-- Try to work out any subtypes, based on the files in the project
|
||||
|
||||
if info.action == "Compile" and fname:endswith(".cs") then
|
||||
|
||||
if fname:endswith(".Designer.cs") then
|
||||
local basename = fname:sub(1, -13)
|
||||
|
||||
-- Look for associated files: .resx, .settings, .cs, .xsd
|
||||
local testname = basename .. ".resx"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.AutoGen = "True"
|
||||
info.DependentUpon = testname
|
||||
end
|
||||
|
||||
testname = basename .. ".settings"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.AutoGen = "True"
|
||||
info.DependentUpon = testname
|
||||
info.DesignTimeSharedInput = "True"
|
||||
end
|
||||
|
||||
testname = basename .. ".cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.AutoGen = nil
|
||||
info.SubType = "Dependency"
|
||||
info.DependentUpon = testname
|
||||
end
|
||||
|
||||
testname = basename .. ".xsd"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.AutoGen = "True"
|
||||
info.DesignTime = "True"
|
||||
info.DependentUpon = testname
|
||||
end
|
||||
|
||||
elseif fname:endswith(".xaml.cs") then
|
||||
info.SubType = "Code"
|
||||
info.DependentUpon = fname:sub(1, -4)
|
||||
|
||||
else
|
||||
local basename = fname:sub(1, -4)
|
||||
|
||||
-- Is there a matching *.xsd?
|
||||
testname = basename .. ".xsd"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.DependentUpon = testname
|
||||
end
|
||||
|
||||
-- Is there a matching *.Designer.cs?
|
||||
testname = basename .. ".Designer.cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.SubType = "Form"
|
||||
end
|
||||
|
||||
testname = basename .. ".tt"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.AutoGen = "True"
|
||||
info.DesignTime = "True"
|
||||
info.DependentUpon = testname
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Allow C# object type build actions to override the default
|
||||
if fcfg.buildaction == "Component" or
|
||||
fcfg.buildaction == "Form" or
|
||||
fcfg.buildaction == "UserControl"
|
||||
then
|
||||
info.SubType = fcfg.buildaction
|
||||
end
|
||||
|
||||
-- This flag is deprecated, will remove eventually
|
||||
if fcfg.flags and fcfg.flags.Component then
|
||||
info.SubType = "Component"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if info.action == "Content" then
|
||||
info.CopyToOutputDirectory = "PreserveNewest"
|
||||
end
|
||||
|
||||
if info.action == "EmbeddedResource" and fname:endswith(".resx") then
|
||||
local basename = fname:sub(1, -6)
|
||||
|
||||
-- Is there a matching *.cs file?
|
||||
local testname = basename .. ".cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.DependentUpon = testname
|
||||
if project.hasfile(fcfg.project, basename .. ".Designer.cs") then
|
||||
info.SubType = "DesignerType"
|
||||
end
|
||||
else
|
||||
-- Is there a matching *.Designer.cs?
|
||||
testname = basename .. ".Designer.cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.SubType = "Designer"
|
||||
|
||||
local resourceAccessGenerator = "ResXFileCodeGenerator"
|
||||
if fcfg.project.resourcegenerator then
|
||||
if fcfg.project.resourcegenerator == "public" then
|
||||
resourceAccessGenerator = "PublicResXFileCodeGenerator"
|
||||
end
|
||||
end
|
||||
|
||||
info.Generator = resourceAccessGenerator
|
||||
info.LastGenOutput = path.getname(testname)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if info.action == "None" and fname:endswith(".settings") then
|
||||
local testname = fname:sub(1, -10) .. ".Designer.cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.Generator = "SettingsSingleFileGenerator"
|
||||
info.LastGenOutput = path.getname(testname)
|
||||
end
|
||||
end
|
||||
|
||||
if info.action == "Content" and fname:endswith(".tt") then
|
||||
local testname = fname:sub(1, -4) .. ".cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.Generator = "TextTemplatingFileGenerator"
|
||||
info.LastGenOutput = path.getname(testname)
|
||||
info.CopyToOutputDirectory = nil
|
||||
end
|
||||
end
|
||||
|
||||
if info.action == "None" and fname:endswith(".xsd") then
|
||||
local testname = fname:sub(1, -5) .. ".Designer.cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.SubType = "Designer"
|
||||
info.Generator = "MSDataSetGenerator"
|
||||
info.LastGenOutput = path.getname(testname)
|
||||
end
|
||||
end
|
||||
|
||||
if info.action == "None" and (fname:endswith(".xsc") or fname:endswith(".xss")) then
|
||||
local testname = fname:sub(1, -5) .. ".xsd"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.DependentUpon = testname
|
||||
end
|
||||
end
|
||||
|
||||
if fname:endswith(".xaml") then
|
||||
local testname = fname .. ".cs"
|
||||
if project.hasfile(fcfg.project, testname) then
|
||||
info.SubType = "Designer"
|
||||
info.Generator = "MSBuild:Compile"
|
||||
end
|
||||
end
|
||||
|
||||
if info.DependentUpon then
|
||||
info.DependentUpon = path.getname(info.DependentUpon)
|
||||
end
|
||||
|
||||
return info
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Retrieves the executable command name for a tool, based on the
|
||||
-- provided configuration and the operating environment.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to query.
|
||||
-- @param tool
|
||||
-- The tool to fetch, one of "csc" for the C# compiler, or
|
||||
-- "resgen" for the resource compiler.
|
||||
-- @return
|
||||
-- The executable command name for a tool, or nil if the system's
|
||||
-- default value should be used.
|
||||
--
|
||||
|
||||
function dotnet.gettoolname(cfg, tool)
|
||||
local compilers = {
|
||||
msnet = "csc",
|
||||
mono = "mcs",
|
||||
pnet = "cscc",
|
||||
}
|
||||
|
||||
if tool == "csc" then
|
||||
local toolset = _OPTIONS.dotnet or "msnet"
|
||||
return compilers[toolset]
|
||||
else
|
||||
return "resgen"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns a list of compiler flags, based on the supplied configuration.
|
||||
--
|
||||
|
||||
dotnet.flags = {
|
||||
clr = {
|
||||
Unsafe = "/unsafe",
|
||||
},
|
||||
flags = {
|
||||
FatalWarning = "/warnaserror",
|
||||
},
|
||||
optimize = {
|
||||
On = "/optimize",
|
||||
Size = "/optimize",
|
||||
Speed = "/optimize",
|
||||
},
|
||||
symbols = {
|
||||
On = "/debug",
|
||||
}
|
||||
}
|
||||
|
||||
function dotnet.getflags(cfg)
|
||||
local flags = config.mapFlags(cfg, dotnet.flags)
|
||||
|
||||
-- Tells the compiler not to include the csc.rsp response file which
|
||||
-- it does by default and references all the assemblies shipped with
|
||||
-- the .NET Framework. VS sets this flag by default for C# projects.
|
||||
table.insert(flags, '/noconfig')
|
||||
|
||||
if cfg.project.icon then
|
||||
local fn = project.getrelative(cfg.project, cfg.project.icon)
|
||||
table.insert(flags, string.format('/win32icon:"%s"', fn))
|
||||
end
|
||||
|
||||
if #cfg.defines > 0 then
|
||||
table.insert(flags, table.implode(cfg.defines, "/d:", "", " "))
|
||||
end
|
||||
|
||||
if cfg.csversion ~= nil then
|
||||
table.insert(flags, '/langversion:' .. cfg.csversion)
|
||||
end
|
||||
|
||||
return table.join(flags, cfg.buildoptions)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Translates the Premake kind into the CSC kind string.
|
||||
--
|
||||
|
||||
function dotnet.getkind(cfg)
|
||||
if (cfg.kind == "ConsoleApp") then
|
||||
return "Exe"
|
||||
elseif (cfg.kind == "WindowedApp") then
|
||||
return "WinExe"
|
||||
elseif (cfg.kind == "SharedLib") then
|
||||
return "Library"
|
||||
else
|
||||
error("invalid dotnet kind " .. cfg.kind .. ". Valid kinds are ConsoleApp, WindowsApp, SharedLib")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns makefile-specific configuration rules.
|
||||
--
|
||||
|
||||
function dotnet.getmakesettings(cfg)
|
||||
return nil
|
||||
end
|
||||
639
Src/external_dependencies/openmpt-trunk/include/premake/src/tools/gcc.lua
vendored
Normal file
639
Src/external_dependencies/openmpt-trunk/include/premake/src/tools/gcc.lua
vendored
Normal file
@@ -0,0 +1,639 @@
|
||||
---
|
||||
-- gcc.lua
|
||||
-- Provides GCC-specific configuration strings.
|
||||
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
|
||||
p.tools.gcc = {}
|
||||
local gcc = p.tools.gcc
|
||||
|
||||
local project = p.project
|
||||
local config = p.config
|
||||
|
||||
|
||||
--
|
||||
-- Returns list of C preprocessor flags for a configuration.
|
||||
--
|
||||
|
||||
gcc.cppflags = {
|
||||
system = {
|
||||
haiku = "-MMD",
|
||||
wii = { "-MMD", "-MP", "-I$(LIBOGC_INC)", "$(MACHDEP)" },
|
||||
_ = { "-MMD", "-MP" }
|
||||
}
|
||||
}
|
||||
|
||||
function gcc.getcppflags(cfg)
|
||||
local flags = config.mapFlags(cfg, gcc.cppflags)
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns string to be appended to -g
|
||||
--
|
||||
function gcc.getdebugformat(cfg)
|
||||
local flags = {
|
||||
Default = "",
|
||||
Dwarf = "dwarf",
|
||||
SplitDwarf = "split-dwarf",
|
||||
}
|
||||
return flags
|
||||
end
|
||||
|
||||
--
|
||||
-- Returns list of C compiler flags for a configuration.
|
||||
--
|
||||
gcc.shared = {
|
||||
architecture = {
|
||||
x86 = "-m32",
|
||||
x86_64 = "-m64",
|
||||
},
|
||||
flags = {
|
||||
FatalCompileWarnings = "-Werror",
|
||||
LinkTimeOptimization = "-flto",
|
||||
ShadowedVariables = "-Wshadow",
|
||||
UndefinedIdentifiers = "-Wundef",
|
||||
},
|
||||
floatingpoint = {
|
||||
Fast = "-ffast-math",
|
||||
Strict = "-ffloat-store",
|
||||
},
|
||||
strictaliasing = {
|
||||
Off = "-fno-strict-aliasing",
|
||||
Level1 = { "-fstrict-aliasing", "-Wstrict-aliasing=1" },
|
||||
Level2 = { "-fstrict-aliasing", "-Wstrict-aliasing=2" },
|
||||
Level3 = { "-fstrict-aliasing", "-Wstrict-aliasing=3" },
|
||||
},
|
||||
optimize = {
|
||||
Off = "-O0",
|
||||
On = "-O2",
|
||||
Debug = "-Og",
|
||||
Full = "-O3",
|
||||
Size = "-Os",
|
||||
Speed = "-O3",
|
||||
},
|
||||
pic = {
|
||||
On = "-fPIC",
|
||||
},
|
||||
vectorextensions = {
|
||||
AVX = "-mavx",
|
||||
AVX2 = "-mavx2",
|
||||
SSE = "-msse",
|
||||
SSE2 = "-msse2",
|
||||
SSE3 = "-msse3",
|
||||
SSSE3 = "-mssse3",
|
||||
["SSE4.1"] = "-msse4.1",
|
||||
["SSE4.2"] = "-msse4.2",
|
||||
},
|
||||
isaextensions = {
|
||||
MOVBE = "-mmovbe",
|
||||
POPCNT = "-mpopcnt",
|
||||
PCLMUL = "-mpclmul",
|
||||
LZCNT = "-mlzcnt",
|
||||
BMI = "-mbmi",
|
||||
BMI2 = "-mbmi2",
|
||||
F16C = "-mf16c",
|
||||
AES = "-maes",
|
||||
FMA = "-mfma",
|
||||
FMA4 = "-mfma4",
|
||||
RDRND = "-mrdrnd",
|
||||
},
|
||||
warnings = {
|
||||
Off = "-w",
|
||||
High = "-Wall",
|
||||
Extra = {"-Wall", "-Wextra"},
|
||||
Everything = "-Weverything",
|
||||
},
|
||||
symbols = function(cfg, mappings)
|
||||
local values = gcc.getdebugformat(cfg)
|
||||
local debugformat = values[cfg.debugformat] or ""
|
||||
return {
|
||||
On = "-g" .. debugformat,
|
||||
FastLink = "-g" .. debugformat,
|
||||
Full = "-g" .. debugformat,
|
||||
}
|
||||
end,
|
||||
unsignedchar = {
|
||||
On = "-funsigned-char",
|
||||
Off = "-fno-unsigned-char"
|
||||
},
|
||||
omitframepointer = {
|
||||
On = "-fomit-frame-pointer",
|
||||
Off = "-fno-omit-frame-pointer"
|
||||
},
|
||||
compileas = {
|
||||
["Objective-C"] = "-x objective-c",
|
||||
["Objective-C++"] = "-x objective-c++",
|
||||
}
|
||||
}
|
||||
|
||||
gcc.cflags = {
|
||||
cdialect = {
|
||||
["C89"] = "-std=c89",
|
||||
["C90"] = "-std=c90",
|
||||
["C99"] = "-std=c99",
|
||||
["C11"] = "-std=c11",
|
||||
["gnu89"] = "-std=gnu89",
|
||||
["gnu90"] = "-std=gnu90",
|
||||
["gnu99"] = "-std=gnu99",
|
||||
["gnu11"] = "-std=gnu11",
|
||||
}
|
||||
}
|
||||
|
||||
function gcc.getcflags(cfg)
|
||||
local shared_flags = config.mapFlags(cfg, gcc.shared)
|
||||
local cflags = config.mapFlags(cfg, gcc.cflags)
|
||||
local flags = table.join(shared_flags, cflags, gcc.getsystemversionflags(cfg))
|
||||
flags = table.join(flags, gcc.getwarnings(cfg))
|
||||
return flags
|
||||
end
|
||||
|
||||
function gcc.getwarnings(cfg)
|
||||
local result = {}
|
||||
for _, enable in ipairs(cfg.enablewarnings) do
|
||||
table.insert(result, '-W' .. enable)
|
||||
end
|
||||
for _, disable in ipairs(cfg.disablewarnings) do
|
||||
table.insert(result, '-Wno-' .. disable)
|
||||
end
|
||||
for _, fatal in ipairs(cfg.fatalwarnings) do
|
||||
table.insert(result, '-Werror=' .. fatal)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--
|
||||
-- Returns C/C++ system version build flags
|
||||
--
|
||||
|
||||
function gcc.getsystemversionflags(cfg)
|
||||
local flags = {}
|
||||
|
||||
if cfg.system == p.MACOSX then
|
||||
local minVersion = p.project.systemversion(cfg)
|
||||
if minVersion ~= nil then
|
||||
table.insert (flags, "-mmacosx-version-min=" .. minVersion)
|
||||
end
|
||||
end
|
||||
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns list of C++ compiler flags for a configuration.
|
||||
--
|
||||
|
||||
gcc.cxxflags = {
|
||||
exceptionhandling = {
|
||||
Off = "-fno-exceptions"
|
||||
},
|
||||
flags = {
|
||||
NoBufferSecurityCheck = "-fno-stack-protector",
|
||||
},
|
||||
cppdialect = {
|
||||
["C++98"] = "-std=c++98",
|
||||
["C++0x"] = "-std=c++0x",
|
||||
["C++11"] = "-std=c++11",
|
||||
["C++1y"] = "-std=c++1y",
|
||||
["C++14"] = "-std=c++14",
|
||||
["C++1z"] = "-std=c++1z",
|
||||
["C++17"] = "-std=c++17",
|
||||
["C++2a"] = "-std=c++2a",
|
||||
["C++20"] = "-std=c++20",
|
||||
["gnu++98"] = "-std=gnu++98",
|
||||
["gnu++0x"] = "-std=gnu++0x",
|
||||
["gnu++11"] = "-std=gnu++11",
|
||||
["gnu++1y"] = "-std=gnu++1y",
|
||||
["gnu++14"] = "-std=gnu++14",
|
||||
["gnu++1z"] = "-std=gnu++1z",
|
||||
["gnu++17"] = "-std=gnu++17",
|
||||
["gnu++2a"] = "-std=gnu++2a",
|
||||
["gnu++20"] = "-std=gnu++20",
|
||||
["C++latest"] = "-std=c++20",
|
||||
},
|
||||
rtti = {
|
||||
Off = "-fno-rtti"
|
||||
},
|
||||
visibility = {
|
||||
Default = "-fvisibility=default",
|
||||
Hidden = "-fvisibility=hidden",
|
||||
Internal = "-fvisibility=internal",
|
||||
Protected = "-fvisibility=protected",
|
||||
},
|
||||
inlinesvisibility = {
|
||||
Hidden = "-fvisibility-inlines-hidden"
|
||||
}
|
||||
}
|
||||
|
||||
function gcc.getcxxflags(cfg)
|
||||
local shared_flags = config.mapFlags(cfg, gcc.shared)
|
||||
local cxxflags = config.mapFlags(cfg, gcc.cxxflags)
|
||||
local flags = table.join(shared_flags, cxxflags)
|
||||
flags = table.join(flags, gcc.getwarnings(cfg), gcc.getsystemversionflags(cfg))
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Decorate defines for the GCC command line.
|
||||
--
|
||||
|
||||
function gcc.getdefines(defines)
|
||||
local result = {}
|
||||
for _, define in ipairs(defines) do
|
||||
table.insert(result, '-D' .. p.esc(define))
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function gcc.getundefines(undefines)
|
||||
local result = {}
|
||||
for _, undefine in ipairs(undefines) do
|
||||
table.insert(result, '-U' .. p.esc(undefine))
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns a list of forced include files, decorated for the compiler
|
||||
-- command line.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The project configuration.
|
||||
-- @return
|
||||
-- An array of force include files with the appropriate flags.
|
||||
--
|
||||
|
||||
function gcc.getforceincludes(cfg)
|
||||
local result = {}
|
||||
|
||||
table.foreachi(cfg.forceincludes, function(value)
|
||||
local fn = project.getrelative(cfg.project, value)
|
||||
table.insert(result, string.format('-include %s', p.quoted(fn)))
|
||||
end)
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Decorate include file search paths for the GCC command line.
|
||||
--
|
||||
|
||||
function gcc.getincludedirs(cfg, dirs, sysdirs, frameworkdirs)
|
||||
local result = {}
|
||||
for _, dir in ipairs(dirs) do
|
||||
dir = project.getrelative(cfg.project, dir)
|
||||
table.insert(result, '-I' .. p.quoted(dir))
|
||||
end
|
||||
|
||||
if table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
for _, dir in ipairs(frameworkdirs or {}) do
|
||||
dir = project.getrelative(cfg.project, dir)
|
||||
table.insert(result, '-F' .. p.quoted(dir))
|
||||
end
|
||||
end
|
||||
|
||||
for _, dir in ipairs(sysdirs or {}) do
|
||||
dir = project.getrelative(cfg.project, dir)
|
||||
table.insert(result, '-isystem ' .. p.quoted(dir))
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- relative pch file path if any
|
||||
function gcc.getpch(cfg)
|
||||
-- If there is no header, or if PCH has been disabled, I can early out
|
||||
if not cfg.pchheader or cfg.flags.NoPCH then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Visual Studio requires the PCH header to be specified in the same way
|
||||
-- it appears in the #include statements used in the source code; the PCH
|
||||
-- source actual handles the compilation of the header. GCC compiles the
|
||||
-- header file directly, and needs the file's actual file system path in
|
||||
-- order to locate it.
|
||||
|
||||
-- To maximize the compatibility between the two approaches, see if I can
|
||||
-- locate the specified PCH header on one of the include file search paths
|
||||
-- and, if so, adjust the path automatically so the user doesn't have
|
||||
-- add a conditional configuration to the project script.
|
||||
|
||||
local pch = cfg.pchheader
|
||||
local found = false
|
||||
|
||||
-- test locally in the project folder first (this is the most likely location)
|
||||
local testname = path.join(cfg.project.basedir, pch)
|
||||
if os.isfile(testname) then
|
||||
return project.getrelative(cfg.project, testname)
|
||||
else
|
||||
-- else scan in all include dirs.
|
||||
for _, incdir in ipairs(cfg.includedirs) do
|
||||
testname = path.join(incdir, pch)
|
||||
if os.isfile(testname) then
|
||||
return project.getrelative(cfg.project, testname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return project.getrelative(cfg.project, path.getabsolute(pch))
|
||||
end
|
||||
|
||||
--
|
||||
-- Return a list of decorated rpaths
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to query.
|
||||
-- @param dirs
|
||||
-- List of absolute paths
|
||||
-- @param mode
|
||||
-- Output mode
|
||||
-- - "linker" (default) Linker rpath instructions
|
||||
-- - "path" List of path relative to configuration target directory
|
||||
--
|
||||
|
||||
function gcc.getrunpathdirs(cfg, dirs, mode)
|
||||
local result = {}
|
||||
mode = iif (mode == nil, "linker", mode)
|
||||
|
||||
if not (table.contains(os.getSystemTags(cfg.system), "darwin")
|
||||
or (cfg.system == p.LINUX)) then
|
||||
return result
|
||||
end
|
||||
|
||||
for _, fullpath in ipairs(dirs) do
|
||||
local rpath = path.getrelative(cfg.buildtarget.directory, fullpath)
|
||||
if table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
rpath = "@loader_path/" .. rpath
|
||||
elseif (cfg.system == p.LINUX) then
|
||||
rpath = iif(rpath == ".", "", "/" .. rpath)
|
||||
rpath = "$$ORIGIN" .. rpath
|
||||
end
|
||||
|
||||
if mode == "linker" then
|
||||
rpath = "-Wl,-rpath,'" .. rpath .. "'"
|
||||
end
|
||||
|
||||
table.insert(result, rpath)
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
--
|
||||
-- get the right output flag.
|
||||
--
|
||||
function gcc.getsharedlibarg(cfg)
|
||||
if table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
if cfg.sharedlibtype == "OSXBundle" then
|
||||
return "-bundle"
|
||||
elseif cfg.sharedlibtype == "XCTest" then
|
||||
return "-bundle"
|
||||
elseif cfg.sharedlibtype == "OSXFramework" then
|
||||
return "-framework"
|
||||
else
|
||||
return "-dynamiclib"
|
||||
end
|
||||
else
|
||||
return "-shared"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Return a list of LDFLAGS for a specific configuration.
|
||||
--
|
||||
|
||||
function gcc.ldsymbols(cfg)
|
||||
-- OS X has a bug, see http://lists.apple.com/archives/Darwin-dev/2006/Sep/msg00084.html
|
||||
return iif(table.contains(os.getSystemTags(cfg.system), "darwin"), "-Wl,-x", "-s")
|
||||
end
|
||||
|
||||
gcc.ldflags = {
|
||||
architecture = {
|
||||
x86 = "-m32",
|
||||
x86_64 = "-m64",
|
||||
},
|
||||
flags = {
|
||||
LinkTimeOptimization = "-flto",
|
||||
},
|
||||
kind = {
|
||||
SharedLib = function(cfg)
|
||||
local r = { gcc.getsharedlibarg(cfg) }
|
||||
if cfg.system == p.WINDOWS and not cfg.flags.NoImportLib then
|
||||
table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"')
|
||||
elseif cfg.system == p.LINUX then
|
||||
table.insert(r, '-Wl,-soname=' .. p.quoted(cfg.linktarget.name))
|
||||
elseif table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
table.insert(r, '-Wl,-install_name,' .. p.quoted('@rpath/' .. cfg.linktarget.name))
|
||||
end
|
||||
return r
|
||||
end,
|
||||
WindowedApp = function(cfg)
|
||||
if cfg.system == p.WINDOWS then return "-mwindows" end
|
||||
end,
|
||||
},
|
||||
system = {
|
||||
wii = "$(MACHDEP)",
|
||||
},
|
||||
symbols = {
|
||||
Off = gcc.ldsymbols,
|
||||
Default = gcc.ldsymbols,
|
||||
}
|
||||
}
|
||||
|
||||
function gcc.getldflags(cfg)
|
||||
local flags = config.mapFlags(cfg, gcc.ldflags)
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Return a list of decorated additional libraries directories.
|
||||
--
|
||||
|
||||
gcc.libraryDirectories = {
|
||||
architecture = {
|
||||
x86 = function (cfg)
|
||||
local r = {}
|
||||
if not table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
table.insert (r, "-L/usr/lib32")
|
||||
end
|
||||
return r
|
||||
end,
|
||||
x86_64 = function (cfg)
|
||||
local r = {}
|
||||
if not table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
table.insert (r, "-L/usr/lib64")
|
||||
end
|
||||
return r
|
||||
end,
|
||||
},
|
||||
system = {
|
||||
wii = "-L$(LIBOGC_LIB)",
|
||||
}
|
||||
}
|
||||
|
||||
function gcc.getLibraryDirectories(cfg)
|
||||
local flags = {}
|
||||
|
||||
-- Scan the list of linked libraries. If any are referenced with
|
||||
-- paths, add those to the list of library search paths. The call
|
||||
-- config.getlinks() all includes cfg.libdirs.
|
||||
for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do
|
||||
table.insert(flags, '-L' .. p.quoted(dir))
|
||||
end
|
||||
|
||||
if table.contains(os.getSystemTags(cfg.system), "darwin") then
|
||||
for _, dir in ipairs(cfg.frameworkdirs) do
|
||||
dir = project.getrelative(cfg.project, dir)
|
||||
table.insert(flags, '-F' .. p.quoted(dir))
|
||||
end
|
||||
end
|
||||
|
||||
if cfg.flags.RelativeLinks then
|
||||
for _, dir in ipairs(config.getlinks(cfg, "siblings", "directory")) do
|
||||
local libFlag = "-L" .. p.project.getrelative(cfg.project, dir)
|
||||
if not table.contains(flags, libFlag) then
|
||||
table.insert(flags, libFlag)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, dir in ipairs(cfg.syslibdirs) do
|
||||
table.insert(flags, '-L' .. p.quoted(dir))
|
||||
end
|
||||
|
||||
local gccFlags = config.mapFlags(cfg, gcc.libraryDirectories)
|
||||
flags = table.join(flags, gccFlags)
|
||||
|
||||
return flags
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Return the list of libraries to link, decorated with flags as needed.
|
||||
--
|
||||
|
||||
function gcc.getlinks(cfg, systemonly, nogroups)
|
||||
local result = {}
|
||||
|
||||
if not systemonly then
|
||||
if cfg.flags.RelativeLinks then
|
||||
local libFiles = config.getlinks(cfg, "siblings", "basename")
|
||||
for _, link in ipairs(libFiles) do
|
||||
if string.startswith(link, "lib") then
|
||||
link = link:sub(4)
|
||||
end
|
||||
table.insert(result, "-l" .. link)
|
||||
end
|
||||
else
|
||||
-- Don't use the -l form for sibling libraries, since they may have
|
||||
-- custom prefixes or extensions that will confuse the linker. Instead
|
||||
-- just list out the full relative path to the library.
|
||||
result = config.getlinks(cfg, "siblings", "fullpath")
|
||||
end
|
||||
end
|
||||
|
||||
-- The "-l" flag is fine for system libraries
|
||||
local links = config.getlinks(cfg, "system", "fullpath")
|
||||
local static_syslibs = {"-Wl,-Bstatic"}
|
||||
local shared_syslibs = {}
|
||||
|
||||
for _, link in ipairs(links) do
|
||||
if path.isframework(link) then
|
||||
table.insert(result, "-framework")
|
||||
table.insert(result, path.getbasename(link))
|
||||
elseif path.isobjectfile(link) then
|
||||
table.insert(result, link)
|
||||
else
|
||||
local endswith = function(s, ptrn)
|
||||
return ptrn == string.sub(s, -string.len(ptrn))
|
||||
end
|
||||
local name = path.getname(link)
|
||||
-- Check whether link mode decorator is present
|
||||
if endswith(name, ":static") then
|
||||
name = string.sub(name, 0, -8)
|
||||
table.insert(static_syslibs, "-l" .. name)
|
||||
elseif endswith(name, ":shared") then
|
||||
name = string.sub(name, 0, -8)
|
||||
table.insert(shared_syslibs, "-l" .. name)
|
||||
else
|
||||
table.insert(shared_syslibs, "-l" .. name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local move = function(a1, a2)
|
||||
local t = #a2
|
||||
for i = 1, #a1 do a2[t + i] = a1[i] end
|
||||
end
|
||||
if #static_syslibs > 1 then
|
||||
table.insert(static_syslibs, "-Wl,-Bdynamic")
|
||||
move(static_syslibs, result)
|
||||
end
|
||||
move(shared_syslibs, result)
|
||||
|
||||
if not nogroups and #result > 1 and (cfg.linkgroups == p.ON) then
|
||||
table.insert(result, 1, "-Wl,--start-group")
|
||||
table.insert(result, "-Wl,--end-group")
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns makefile-specific configuration rules.
|
||||
--
|
||||
|
||||
gcc.makesettings = {
|
||||
system = {
|
||||
wii = [[
|
||||
ifeq ($(strip $(DEVKITPPC)),)
|
||||
$(error "DEVKITPPC environment variable is not set")'
|
||||
endif
|
||||
include $(DEVKITPPC)/wii_rules']]
|
||||
}
|
||||
}
|
||||
|
||||
function gcc.getmakesettings(cfg)
|
||||
local settings = config.mapFlags(cfg, gcc.makesettings)
|
||||
return table.concat(settings)
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Retrieves the executable command name for a tool, based on the
|
||||
-- provided configuration and the operating environment.
|
||||
--
|
||||
-- @param cfg
|
||||
-- The configuration to query.
|
||||
-- @param tool
|
||||
-- The tool to fetch, one of "cc" for the C compiler, "cxx" for
|
||||
-- the C++ compiler, or "ar" for the static linker.
|
||||
-- @return
|
||||
-- The executable command name for a tool, or nil if the system's
|
||||
-- default value should be used.
|
||||
--
|
||||
|
||||
gcc.tools = {
|
||||
cc = "gcc",
|
||||
cxx = "g++",
|
||||
ar = "ar",
|
||||
rc = "windres"
|
||||
}
|
||||
|
||||
function gcc.gettoolname(cfg, tool)
|
||||
if (cfg.gccprefix and gcc.tools[tool]) or tool == "rc" then
|
||||
return (cfg.gccprefix or "") .. gcc.tools[tool]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user