diff options
-rw-r--r-- | .hgignore | 6 | ||||
-rw-r--r-- | Premake4.vs8.sln | 23 | ||||
-rw-r--r-- | Premake4.vs8.vcproj | 1409 | ||||
-rw-r--r-- | README.rst | 29 | ||||
-rw-r--r-- | premake4.lua | 94 | ||||
-rw-r--r-- | release.cmd | 33 | ||||
-rw-r--r-- | scripts/embed.lua | 57 | ||||
-rw-r--r-- | scripts/luasrcdiet/COPYRIGHT | 45 | ||||
-rw-r--r-- | scripts/luasrcdiet/COPYRIGHT_Lua51 | 34 | ||||
-rw-r--r-- | scripts/luasrcdiet/LuaSrcDiet.lua | 4615 | ||||
-rw-r--r-- | scripts/luasrcdiet/README.LuaSrcDiet | 140 | ||||
-rw-r--r-- | scripts/luasrcdiet/README.premake | 12 | ||||
-rw-r--r-- | setvcvars.cmd | 237 | ||||
-rw-r--r-- | src/actions/vstudio/_vstudio.lua | 53 | ||||
-rw-r--r-- | src/actions/vstudio/vs2005_csproj.lua | 22 | ||||
-rw-r--r-- | src/base/cmdline.lua | 6 | ||||
-rw-r--r-- | src/host/os_match.c | 38 | ||||
-rwxr-xr-x | src/host/premake.c | 12 | ||||
-rw-r--r-- | src/host/premake4.ico | bin | 0 -> 56033 bytes | |||
-rw-r--r-- | src/host/premake4.rc | 55 | ||||
-rw-r--r-- | src/host/scripts.c | 301 | ||||
-rw-r--r-- | tests/actions/test_clean.lua | 4 |
22 files changed, 7139 insertions, 86 deletions
@@ -35,3 +35,9 @@ Scratchpad.txt Unix Worksheet.worksheet project.bbprojectdata Premake4.tmproj +Visual Lint/PC-lint/**.vlstatus +*.lnt +intermediate/** +premake4.exe +src/host/hgtip.h +*.asc diff --git a/Premake4.vs8.sln b/Premake4.vs8.sln new file mode 100644 index 0000000..553260a --- /dev/null +++ b/Premake4.vs8.sln @@ -0,0 +1,23 @@ +
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Premake4", "Premake4.vs8.vcproj", "{7F000221-EACC-2F4F-A07F-6A5D34AF10D0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Release|Win32 = Release|Win32
+ Debug|Win32 = Debug|Win32
+ Publish|Win32 = Publish|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7F000221-EACC-2F4F-A07F-6A5D34AF10D0}.Release|Win32.ActiveCfg = Release|Win32
+ {7F000221-EACC-2F4F-A07F-6A5D34AF10D0}.Release|Win32.Build.0 = Release|Win32
+ {7F000221-EACC-2F4F-A07F-6A5D34AF10D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7F000221-EACC-2F4F-A07F-6A5D34AF10D0}.Debug|Win32.Build.0 = Debug|Win32
+ {7F000221-EACC-2F4F-A07F-6A5D34AF10D0}.Publish|Win32.ActiveCfg = Publish|Win32
+ {7F000221-EACC-2F4F-A07F-6A5D34AF10D0}.Publish|Win32.Build.0 = Publish|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Premake4.vs8.vcproj b/Premake4.vs8.vcproj new file mode 100644 index 0000000..4e13f0a --- /dev/null +++ b/Premake4.vs8.vcproj @@ -0,0 +1,1409 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="Premake4"
+ ProjectGUID="{7F000221-EACC-2F4F-A07F-6A5D34AF10D0}"
+ RootNamespace="Premake4"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="bin\release"
+ IntermediateDirectory="intermediate\vs2005_$(PlatformName)_$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories="src\host\lua-5.1.4\src"
+ PreprocessorDefinitions="NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="false"
+ ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
+ DebugInformationFormat="0"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
+ AdditionalIncludeDirectories="src\host\lua-5.1.4\src"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ole32.lib"
+ OutputFile="$(OutDir)\premake4.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="false"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ EntryPointSymbol="mainCRTStartup"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="bin\debug"
+ IntermediateDirectory="intermediate\vs2005_$(PlatformName)_$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="src\host\lua-5.1.4\src"
+ PreprocessorDefinitions="_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="false"
+ ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
+ DebugInformationFormat="4"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
+ AdditionalIncludeDirectories="src\host\lua-5.1.4\src"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ole32.lib"
+ OutputFile="$(OutDir)\premake4.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="true"
+ ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
+ SubSystem="1"
+ EntryPointSymbol="mainCRTStartup"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Publish|Win32"
+ OutputDirectory="bin\release"
+ IntermediateDirectory="intermediate\vs2005_$(PlatformName)_$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories="src\host\lua-5.1.4\src"
+ PreprocessorDefinitions="NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;HAVE_HGTIP"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="false"
+ ProgramDataBaseFileName="$(OutDir)\premake4.pdb"
+ DebugInformationFormat="0"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;HAVE_HGTIP"
+ AdditionalIncludeDirectories="src\host\lua-5.1.4\src"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ole32.lib"
+ OutputFile="$(OutDir)\premake4.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="false"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ EntryPointSymbol="mainCRTStartup"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="ollisign.cmd -a "$(TargetPath)" "https://bitbucket.org/windirstat/premake-stable" "premake4""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="BUILD.txt"
+ >
+ </File>
+ <File
+ RelativePath="CHANGES.txt"
+ >
+ </File>
+ <File
+ RelativePath="LICENSE.txt"
+ >
+ </File>
+ <File
+ RelativePath="README.txt"
+ >
+ </File>
+ <File
+ RelativePath="premake4.lua"
+ >
+ </File>
+ <Filter
+ Name="samples"
+ Filter=""
+ >
+ <Filter
+ Name="project"
+ Filter=""
+ >
+ <Filter
+ Name="CppConsoleApp"
+ Filter=""
+ >
+ <File
+ RelativePath="samples\project\CppConsoleApp\premake4.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CppSharedLib"
+ Filter=""
+ >
+ <File
+ RelativePath="samples\project\CppSharedLib\premake4.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CppStaticLib"
+ Filter=""
+ >
+ <File
+ RelativePath="samples\project\CppStaticLib\premake4.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CppWindowedApp"
+ Filter=""
+ >
+ <File
+ RelativePath="samples\project\CppWindowedApp\premake4.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CsConsoleApp"
+ Filter=""
+ >
+ <File
+ RelativePath="samples\project\CsConsoleApp\premake4.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CsSharedLib"
+ Filter=""
+ >
+ <File
+ RelativePath="samples\project\CsSharedLib\premake4.lua"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="samples\project\premake4.lua"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="scripts"
+ Filter=""
+ >
+ <File
+ RelativePath="scripts\embed.lua"
+ >
+ </File>
+ <Filter
+ Name="luasrcdiet"
+ Filter=""
+ >
+ <File
+ RelativePath="scripts\luasrcdiet\LuaSrcDiet.lua"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="scripts\release.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="src"
+ Filter=""
+ >
+ <File
+ RelativePath="src\_manifest.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\_premake_main.lua"
+ >
+ </File>
+ <Filter
+ Name="actions"
+ Filter=""
+ >
+ <Filter
+ Name="clean"
+ Filter=""
+ >
+ <File
+ RelativePath="src\actions\clean\_clean.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="codeblocks"
+ Filter=""
+ >
+ <File
+ RelativePath="src\actions\codeblocks\_codeblocks.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\codeblocks\codeblocks_cbp.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\codeblocks\codeblocks_workspace.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="codelite"
+ Filter=""
+ >
+ <File
+ RelativePath="src\actions\codelite\_codelite.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\codelite\codelite_project.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\codelite\codelite_workspace.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="example"
+ Filter=""
+ >
+ <File
+ RelativePath="src\actions\example\_example.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\example\example_project.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\example\example_solution.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="make"
+ Filter=""
+ >
+ <File
+ RelativePath="src\actions\make\_make.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\make\make_cpp.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\make\make_csharp.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\make\make_solution.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="vstudio"
+ Filter=""
+ >
+ <File
+ RelativePath="src\actions\vstudio\_vstudio.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2002_csproj.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2002_csproj_user.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2002_solution.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2003_solution.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2005_csproj.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2005_csproj_user.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2005_solution.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs200x_vcproj.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs200x_vcproj_user.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2010_vcxproj.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2010_vcxproj_filters.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2012.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2013.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\vstudio\vs2015.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="xcode"
+ Filter=""
+ >
+ <File
+ RelativePath="src\actions\xcode\_xcode.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\xcode\xcode4_workspace.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\xcode\xcode_common.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\actions\xcode\xcode_project.lua"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="base"
+ Filter=""
+ >
+ <File
+ RelativePath="src\base\action.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\api.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\bake.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\cmdline.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\config.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\globals.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\help.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\io.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\option.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\os.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\path.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\premake.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\project.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\solution.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\string.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\table.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\tree.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\base\validate.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="host"
+ Filter=""
+ >
+ <Filter
+ Name="lua-5.1.4"
+ Filter=""
+ >
+ <Filter
+ Name="src"
+ Filter=""
+ >
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lapi.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lapi.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lauxlib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lauxlib.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lbaselib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lcode.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lcode.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ldblib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ldebug.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ldebug.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ldo.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ldo.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ldump.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lfunc.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lfunc.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lgc.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lgc.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\linit.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\liolib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\llex.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\llex.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\llimits.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lmathlib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lmem.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lmem.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\loadlib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lobject.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lobject.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lopcodes.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lopcodes.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\loslib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lparser.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lparser.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lstate.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lstate.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lstring.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lstring.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lstrlib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ltable.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ltable.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ltablib.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ltm.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\ltm.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lua.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\luaconf.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lualib.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lundump.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lundump.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lvm.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lvm.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lzio.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\lua-5.1.4\src\lzio.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <File
+ RelativePath="src\host\os_chdir.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_copyfile.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_getcwd.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_getversion.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_is64bit.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_isdir.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_isfile.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_match.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_mkdir.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_pathsearch.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_rmdir.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_stat.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\os_uuid.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\path_getabsolute.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\path_getrelative.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\path_isabsolute.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\path_join.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\path_normalize.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\path_translate.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\premake.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\premake.h"
+ >
+ </File>
+ <File
+ RelativePath="src\host\premake4.rc"
+ >
+ </File>
+ <File
+ RelativePath="src\host\premake_main.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\scripts.c"
+ >
+ </File>
+ <File
+ RelativePath="src\host\string_endswith.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="tools"
+ Filter=""
+ >
+ <File
+ RelativePath="src\tools\dotnet.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\tools\gcc.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\tools\msc.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\tools\ow.lua"
+ >
+ </File>
+ <File
+ RelativePath="src\tools\snc.lua"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="tests"
+ Filter=""
+ >
+ <Filter
+ Name="actions"
+ Filter=""
+ >
+ <Filter
+ Name="codeblocks"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\codeblocks\codeblocks_files.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\codeblocks\environment_variables.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\codeblocks\test_filters.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="codelite"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\codelite\codelite_files.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="make"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\make\test_make_escaping.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\make\test_make_linking.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\make\test_make_pch.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\make\test_makesettings.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\make\test_wiidev.lua"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="tests\actions\test_clean.lua"
+ >
+ </File>
+ <Filter
+ Name="vstudio"
+ Filter=""
+ >
+ <Filter
+ Name="cs2002"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\vstudio\cs2002\test_files.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="cs2005"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\vstudio\cs2005\buildevents.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\cs2005\projectelement.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\cs2005\projectsettings.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\cs2005\propertygroup.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\cs2005\test_files.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="sln2005"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\vstudio\sln2005\dependencies.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\sln2005\header.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\sln2005\layout.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\sln2005\platforms.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\sln2005\projectplatforms.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\sln2005\projects.lua"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="tests\actions\vstudio\test_vs200x_vcproj.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\test_vs200x_vcproj_linker.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\test_vs2010_flags.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\test_vs2010_project_kinds.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\test_vs2010_vcxproj.lua"
+ >
+ </File>
+ <Filter
+ Name="vc200x"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\vstudio\vc200x\debugdir.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc200x\header.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc200x\test_files.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc200x\test_filters.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc200x\test_mfc.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="vc2010"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_config_props.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_debugdir.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_files.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_filters.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_header.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_link_settings.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_links.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_mfc.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_output_props.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_pch.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\vstudio\vc2010\test_project_refs.lua"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="xcode"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\actions\xcode\test_file_references.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\xcode\test_xcode4_project.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\xcode\test_xcode4_workspace.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\xcode\test_xcode_common.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\xcode\test_xcode_dependencies.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\actions\xcode\test_xcode_project.lua"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="baking"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\baking\test_merging.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="base"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\base\test_action.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_api.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_baking.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_config.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_config_bug.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_location.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_os.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_path.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_premake_command.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_table.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\base\test_tree.lua"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="folder"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\folder\ok.lua"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="tests\pepperfish_profiler.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\premake4.lua"
+ >
+ </File>
+ <Filter
+ Name="project"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\project\test_eachfile.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\project\test_vpaths.lua"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="tests\test_dofile.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_gmake_cpp.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_gmake_cs.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_keywords.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_platforms.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_premake.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_project.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_stress.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_string.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_targets.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_vs2002_sln.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\test_vs2003_sln.lua"
+ >
+ </File>
+ <File
+ RelativePath="tests\testfx.lua"
+ >
+ </File>
+ <Filter
+ Name="tools"
+ Filter=""
+ >
+ <File
+ RelativePath="tests\tools\test_gcc.lua"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..82d543d --- /dev/null +++ b/README.rst @@ -0,0 +1,29 @@ +================================= + Premake 4.4 fork for WinDirStat +================================= + +About +----- +This is a friendly fork of `premake/premake-4.x +<https://bitbucket.org/premake/premake-4.x/>`_. + +I usually send pull requests to Jason, but I realize that not all of +my changes may be suitable or desirable. So I keep a separate branch. + +Downloads +--------- + +I provide code-signed binaries in the `download area +<https://bitbucket.org/windirstat/premake-stable/downloads>`_ for the +benefit of those who don't want to build the binary themselves. + +The version I build and provide is exclusively from the ``WDS-build`` +branch, which should also be the one you get to see by default when +looking at this project in a browser. + +License +------- +My changes are not substantial enough to claim any copyright. As far +as I am concerned any contributions that go into upstream are under +the license under which ``premake4`` was at the time of my +contribution.
\ No newline at end of file diff --git a/premake4.lua b/premake4.lua index 1220073..2ab2fc6 100644 --- a/premake4.lua +++ b/premake4.lua @@ -1,7 +1,80 @@ -- -- Premake 4.x build configuration script -- - +-- The below is used to insert the .vs(2005|2008|2010|2012|2013|2015) into the file names for projects and solutions +local action = _ACTION or "" +do + -- This is mainly to support older premake4 builds + if not premake.project.getbasename then + print "Magic happens ..." + -- override the function to establish the behavior we'd get after patching Premake to have premake.project.getbasename + premake.project.getbasename = function(prjname, pattern) + return pattern:gsub("%%%%", prjname) + end + -- obviously we also need to overwrite the following to generate functioning VS solution files + premake.vstudio.projectfile = function(prj) + local pattern + if prj.language == "C#" then + pattern = "%%.csproj" + else + pattern = iif(_ACTION > "vs2008", "%%.vcxproj", "%%.vcproj") + end + + local fname = premake.project.getbasename(prj.name, pattern) + fname = path.join(prj.location, fname) + return fname + end + -- we simply overwrite the original function on older Premake versions + premake.project.getfilename = function(prj, pattern) + local fname = premake.project.getbasename(prj.name, pattern) + fname = path.join(prj.location, fname) + return path.getrelative(os.getcwd(), fname) + end + end + -- Name the project files after their VS version + local orig_getbasename = premake.project.getbasename + premake.project.getbasename = function(prjname, pattern) + -- The below is used to insert the .vs(8|9|10|11|12|14) into the file names for projects and solutions + if _ACTION then + name_map = {vs2005 = "vs8", vs2008 = "vs9", vs2010 = "vs10", vs2012 = "vs11", vs2013 = "vs12", vs2015 = "vs14"} + if name_map[_ACTION] then + pattern = pattern:gsub("%%%%", "%%%%." .. name_map[_ACTION]) + else + pattern = pattern:gsub("%%%%", "%%%%." .. _ACTION) + end + end + return orig_getbasename(prjname, pattern) + end + -- Override the object directory paths ... don't make them "unique" inside premake4 + local orig_gettarget = premake.gettarget + premake.gettarget = function(cfg, direction, pathstyle, namestyle, system) + local r = orig_gettarget(cfg, direction, pathstyle, namestyle, system) + if (cfg.objectsdir) and (cfg.objdir) then + cfg.objectsdir = cfg.objdir + end + return r + end + -- Silently suppress generation of the .user files ... + local orig_generate = premake.generate + premake.generate = function(obj, filename, callback) + if filename:find('.vcproj.user') or filename:find('.vcxproj.user') then + return + end + orig_generate(obj, filename, callback) + end +end +local function transformMN(input) -- transform the macro names for older Visual Studio versions + local new_map = { vs2002 = 0, vs2003 = 0, vs2005 = 0, vs2008 = 0 } + local replacements = { Platform = "PlatformName", Configuration = "ConfigurationName" } + if new_map[action] ~= nil then + for k,v in pairs(replacements) do + if input:find(k) then + input = input:gsub(k, v) + end + end + end + return input +end -- -- Define the project. Put the release configuration first so it will be the -- default when folks build using the makefile. That way they don't have to @@ -9,13 +82,16 @@ -- solution "Premake4" - configurations { "Release", "Debug" } + configurations { "Release", "Debug", "Publish" } location ( _OPTIONS["to"] ) project "Premake4" + local int_dir = "intermediate/" .. action .. "_$(" .. transformMN("Platform") .. ")_$(" .. transformMN("Configuration") .. ")" + uuid "7F000221-EACC-2F4F-A07F-6A5D34AF10D0" targetname "premake4" language "C" kind "ConsoleApp" + objdir (int_dir) flags { "No64BitChecks", "ExtraWarnings", "StaticRuntime" } includedirs { "src/host/lua-5.1.4/src" } @@ -33,7 +109,8 @@ "src/host/lua-5.1.4/src/luac.c", "src/host/lua-5.1.4/src/print.c", "src/host/lua-5.1.4/**.lua", - "src/host/lua-5.1.4/etc/*.c" + "src/host/lua-5.1.4/etc/*.c", + "src/host/hgtip.h" } configuration "Debug" @@ -41,7 +118,7 @@ defines "_DEBUG" flags { "Symbols" } - configuration "Release" + configuration "Release or Publish" targetdir "bin/release" defines "NDEBUG" flags { "OptimizeSize" } @@ -50,10 +127,15 @@ defines { "_CRT_SECURE_NO_WARNINGS" } configuration "vs2005" - defines {"_CRT_SECURE_NO_DEPRECATE" } + defines {"_CRT_SECURE_NO_DEPRECATE" } configuration "windows" - links { "ole32" } + links { "ole32" } + files { "src/host/premake4.rc" } + + configuration {"windows", "Publish"} + postbuildcommands { 'ollisign.cmd -a "$(TargetPath)" "https://bitbucket.org/windirstat/premake-stable" "premake4"' } + defines "HAVE_HGTIP" configuration "linux or bsd" defines { "LUA_USE_POSIX", "LUA_USE_DLOPEN" } diff --git a/release.cmd b/release.cmd new file mode 100644 index 0000000..248fc7d --- /dev/null +++ b/release.cmd @@ -0,0 +1,33 @@ +@echo off
+@if not "%OS%"=="Windows_NT" @(echo This script requires Windows NT 4.0 or later to run properly! & goto :EOF)
+setlocal ENABLEEXTENSIONS & pushd .
+call setvcvars.cmd 8.0
+if NOT defined VCVER_FRIENDLY echo Unfortunately setvcvars.cmd didn't do its job. Fix the problem and run this script again.&goto :EOF
+set HGTIPFILE="%~dp0src\host\hgtip.h"
+for /f %%i in ('hg id -i -r tip') do @call :SetVar HG_TIP_ID "%%i"
+for /f %%i in ('hg id -n -r tip') do @call :SetVar HG_TIP_REVNO "%%i"
+echo #define HG_TIP_ID "%HG_TIP_ID%" > %HGTIPFILE%
+echo #define HG_TIP_REVNO "%HG_TIP_REVNO%" >> %HGTIPFILE%
+if exist %HGTIPFILE% type %HGTIPFILE%
+vcbuild /rebuild /time Premake4.vs8.sln "Publish|Win32"
+"%~dp0bin\release\premake4.exe" embed
+vcbuild /rebuild /time Premake4.vs8.sln "Publish|Win32"
+set NEWNAME=%~dp0premake4.rev-%HG_TIP_REVNO%-%HG_TIP_ID%.exe
+copy /y "%~dp0bin\release\premake4.exe" "%NEWNAME%"
+sigcheck -a "%NEWNAME%"
+gpg2 -bao "%NEWNAME%.asc" "%NEWNAME%"
+popd & endlocal & goto :EOF
+goto :EOF
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: / SetVar subroutine
+::: Param1 == name of the variable, Param2 == value to be set for the variable
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:SetVar
+:: Get the name of the variable we are working with
+setlocal ENABLEEXTENSIONS&set VAR_NAME=%1
+endlocal & set %VAR_NAME%=%~2
+goto :EOF
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: \ SetVar subroutine
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
diff --git a/scripts/embed.lua b/scripts/embed.lua index 94b7cbf..5dd08c5 100644 --- a/scripts/embed.lua +++ b/scripts/embed.lua @@ -1,39 +1,33 @@ -- -- Embed the Lua scripts into src/host/scripts.c as static data buffers. --- I embed the actual scripts, rather than Lua bytecodes, because the --- bytecodes are not portable to different architectures, which causes +-- I embed the actual scripts, rather than Lua bytecodes, because the +-- bytecodes are not portable to different architectures, which causes -- issues in Mac OS X Universal builds. -- - local function stripfile(fname) - local f = io.open(fname) - local s = assert(f:read("*a")) - f:close() + local raw_sum = 0 + local trim_sum = 0 - -- strip tabs - s = s:gsub("[\t]", "") - + local function stripfile(fname) + dofile("scripts/luasrcdiet/LuaSrcDiet.lua") + -- Let LuaSrcDiet do its job + local s,l = get_slim_luasrc(fname) + -- Now do some cleanup so we can write these out as C strings -- strip any CRs s = s:gsub("[\r]", "") - - -- strip out comments - s = s:gsub("\n%-%-[^\n]*", "") - - -- escape backslashes - s = s:gsub("\\", "\\\\") - -- strip duplicate line feeds - s = s:gsub("\n+", "\n") + -- overall counters + raw_sum = raw_sum + l:len() + trim_sum = trim_sum + s:len() - -- strip out leading comments - s = s:gsub("^%-%-\n", "") + -- escape backslashes + s = s:gsub("\\", "\\\\") -- escape line feeds s = s:gsub("\n", "\\n") -- escape double quote marks s = s:gsub("\"", "\\\"") - return s end @@ -43,14 +37,14 @@ out:write(s) out:write(iif(continues, "\"\n", "\",\n")) end - - + + local function writefile(out, fname, contents) local max = 1024 out:write("\t/* " .. fname .. " */\n") - - -- break up large strings to fit in Visual Studio's string length limit + + -- break up large strings to fit in Visual Studio's string length limit local start = 1 local len = contents:len() while start <= len do @@ -61,36 +55,39 @@ -- make sure I don't cut an escape sequence while contents:sub(finish, finish) == "\\" do finish = finish - 1 - end + end writeline(out, contents:sub(start, finish), finish < len) start = finish + 1 - end + end out:write("\n") end function doembed() + raw_sum = 0 + trim_sum = 0 -- load the manifest of script files scripts = dofile("src/_manifest.lua") - + -- main script always goes at the end table.insert(scripts, "_premake_main.lua") - + -- open scripts.c and write the file header local out = io.open("src/host/scripts.c", "w+b") out:write("/* Premake's Lua scripts, as static data buffers for release mode builds */\n") out:write("/* DO NOT EDIT - this file is autogenerated - see BUILD.txt */\n") out:write("/* To regenerate this file, run: premake4 embed */ \n\n") out:write("const char* builtin_scripts[] = {\n") - + for i,fn in ipairs(scripts) do print(fn) local s = stripfile("src/" .. fn) writefile(out, fn, s) end - out:write("\t0\n};\n"); + out:write("\t0\n};\n"); out:close() + print(string.format("Lua scripts trimmed down to %2.1f%% of original size (%d/%d)", (trim_sum / raw_sum) * 100, trim_sum, raw_sum)) end diff --git a/scripts/luasrcdiet/COPYRIGHT b/scripts/luasrcdiet/COPYRIGHT new file mode 100644 index 0000000..4afe0e3 --- /dev/null +++ b/scripts/luasrcdiet/COPYRIGHT @@ -0,0 +1,45 @@ +LuaSrcDiet License +------------------ + +LuaSrcDiet is licensed under the terms of the MIT license reproduced +below. This means that LuaSrcDiet is free software and can be used for +both academic and commercial purposes at absolutely no cost. + +Think of LuaSrcDiet as a compiler or a text filter; whatever that is +processed by LuaSrcDiet is not affected by its license. It does not add +anything new into your source code; it only transforms code that already +exist. + +Hence, there is no need to tag this license onto Lua programs that are +only processed. Given the liberal terms of this kind of license, the +primary purpose is just to claim authorship of LuaSrcDiet. + +Parts of LuaSrcDiet is based on Lua 5 code. See the file COPYRIGHT_Lua51 +(Lua 5.1.4) for Lua 5's license. + +=============================================================================== + +Copyright (C) 2005-2008,2011 Kein-Hong Man <keinhong@gmail.com> +Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this 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 this 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. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/scripts/luasrcdiet/COPYRIGHT_Lua51 b/scripts/luasrcdiet/COPYRIGHT_Lua51 new file mode 100644 index 0000000..3a53e74 --- /dev/null +++ b/scripts/luasrcdiet/COPYRIGHT_Lua51 @@ -0,0 +1,34 @@ +Lua License +----------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see http://www.lua.org/license.html . + +=============================================================================== + +Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this 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 this 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. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/scripts/luasrcdiet/LuaSrcDiet.lua b/scripts/luasrcdiet/LuaSrcDiet.lua new file mode 100644 index 0000000..4feed22 --- /dev/null +++ b/scripts/luasrcdiet/LuaSrcDiet.lua @@ -0,0 +1,4615 @@ +#!/usr/bin/env lua +--[[-------------------------------------------------------------------- + + LuaSrcDiet + Compresses Lua source code by removing unnecessary characters. + For Lua 5.1.x source code. + + Copyright (c) 2008,2011,2012 Kein-Hong Man <keinhong@gmail.com> + The COPYRIGHT file describes the conditions + under which this software may be distributed. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- NOTES: +-- * Remember to update version and date information below (MSG_TITLE) +-- * TODO: passing data tables around is a horrific mess +-- * TODO: to implement pcall() to properly handle lexer etc. errors +-- * TODO: need some automatic testing for a semblance of sanity +-- * TODO: the plugin module is highly experimental and unstable +----------------------------------------------------------------------]] + +-- standard libraries, functions +local string = string +local math = math +local table = table +local require = require +local print = print +local sub = string.sub +local gmatch = string.gmatch +local match = string.match + +-- modules incorporated as preload functions follows +local preload = package.preload +local base = _G + +local plugin_info = { + html = "html generates a HTML file for checking globals", + sloc = "sloc calculates SLOC for given source file", +} + +local p_embedded = { + 'html', + 'sloc', +} + +-- preload function for module llex +preload.llex = +function() +--start of inserted module +module "llex" + +local string = base.require "string" +local find = string.find +local match = string.match +local sub = string.sub + +---------------------------------------------------------------------- +-- initialize keyword list, variables +---------------------------------------------------------------------- + +local kw = {} +for v in string.gmatch([[ +and break do else elseif end false for function if in +local nil not or repeat return then true until while]], "%S+") do + kw[v] = true +end + +-- see init() for module variables (externally visible): +-- tok, seminfo, tokln + +local z, -- source stream + sourceid, -- name of source + I, -- position of lexer + buff, -- buffer for strings + ln -- line number + +---------------------------------------------------------------------- +-- add information to token listing +---------------------------------------------------------------------- + +local function addtoken(token, info) + local i = #tok + 1 + tok[i] = token + seminfo[i] = info + tokln[i] = ln +end + +---------------------------------------------------------------------- +-- handles line number incrementation and end-of-line characters +---------------------------------------------------------------------- + +local function inclinenumber(i, is_tok) + local sub = sub + local old = sub(z, i, i) + i = i + 1 -- skip '\n' or '\r' + local c = sub(z, i, i) + if (c == "\n" or c == "\r") and (c ~= old) then + i = i + 1 -- skip '\n\r' or '\r\n' + old = old..c + end + if is_tok then addtoken("TK_EOL", old) end + ln = ln + 1 + I = i + return i +end + +---------------------------------------------------------------------- +-- initialize lexer for given source _z and source name _sourceid +---------------------------------------------------------------------- + +function init(_z, _sourceid) + z = _z -- source + sourceid = _sourceid -- name of source + I = 1 -- lexer's position in source + ln = 1 -- line number + tok = {} -- lexed token list* + seminfo = {} -- lexed semantic information list* + tokln = {} -- line numbers for messages* + -- (*) externally visible thru' module + -------------------------------------------------------------------- + -- initial processing (shbang handling) + -------------------------------------------------------------------- + local p, _, q, r = find(z, "^(#[^\r\n]*)(\r?\n?)") + if p then -- skip first line + I = I + #q + addtoken("TK_COMMENT", q) + if #r > 0 then inclinenumber(I, true) end + end +end + +---------------------------------------------------------------------- +-- returns a chunk name or id, no truncation for long names +---------------------------------------------------------------------- + +function chunkid() + if sourceid and match(sourceid, "^[=@]") then + return sub(sourceid, 2) -- remove first char + end + return "[string]" +end + +---------------------------------------------------------------------- +-- formats error message and throws error +-- * a simplified version, does not report what token was responsible +---------------------------------------------------------------------- + +function errorline(s, line) + local e = error or base.error + e(string.format("%s:%d: %s", chunkid(), line or ln, s)) +end +local errorline = errorline + +------------------------------------------------------------------------ +-- count separators ("=") in a long string delimiter +------------------------------------------------------------------------ + +local function skip_sep(i) + local sub = sub + local s = sub(z, i, i) + i = i + 1 + local count = #match(z, "=*", i) + i = i + count + I = i + return (sub(z, i, i) == s) and count or (-count) - 1 +end + +---------------------------------------------------------------------- +-- reads a long string or long comment +---------------------------------------------------------------------- + +local function read_long_string(is_str, sep) + local i = I + 1 -- skip 2nd '[' + local sub = sub + local c = sub(z, i, i) + if c == "\r" or c == "\n" then -- string starts with a newline? + i = inclinenumber(i) -- skip it + end + while true do + local p, q, r = find(z, "([\r\n%]])", i) -- (long range match) + if not p then + errorline(is_str and "unfinished long string" or + "unfinished long comment") + end + i = p + if r == "]" then -- delimiter test + if skip_sep(i) == sep then + buff = sub(z, buff, I) + I = I + 1 -- skip 2nd ']' + return buff + end + i = I + else -- newline + buff = buff.."\n" + i = inclinenumber(i) + end + end--while +end + +---------------------------------------------------------------------- +-- reads a string +---------------------------------------------------------------------- + +local function read_string(del) + local i = I + local find = find + local sub = sub + while true do + local p, q, r = find(z, "([\n\r\\\"\'])", i) -- (long range match) + if p then + if r == "\n" or r == "\r" then + errorline("unfinished string") + end + i = p + if r == "\\" then -- handle escapes + i = i + 1 + r = sub(z, i, i) + if r == "" then break end -- (EOZ error) + p = find("abfnrtv\n\r", r, 1, true) + ------------------------------------------------------ + if p then -- special escapes + if p > 7 then + i = inclinenumber(i) + else + i = i + 1 + end + ------------------------------------------------------ + elseif find(r, "%D") then -- other non-digits + i = i + 1 + ------------------------------------------------------ + else -- \xxx sequence + local p, q, s = find(z, "^(%d%d?%d?)", i) + i = q + 1 + if s + 1 > 256 then -- UCHAR_MAX + errorline("escape sequence too large") + end + ------------------------------------------------------ + end--if p + else + i = i + 1 + if r == del then -- ending delimiter + I = i + return sub(z, buff, i - 1) -- return string + end + end--if r + else + break -- (error) + end--if p + end--while + errorline("unfinished string") +end + +------------------------------------------------------------------------ +-- main lexer function +------------------------------------------------------------------------ + +function llex() + local find = find + local match = match + while true do--outer + local i = I + -- inner loop allows break to be used to nicely section tests + while true do--inner + ---------------------------------------------------------------- + local p, _, r = find(z, "^([_%a][_%w]*)", i) + if p then + I = i + #r + if kw[r] then + addtoken("TK_KEYWORD", r) -- reserved word (keyword) + else + addtoken("TK_NAME", r) -- identifier + end + break -- (continue) + end + ---------------------------------------------------------------- + local p, _, r = find(z, "^(%.?)%d", i) + if p then -- numeral + if r == "." then i = i + 1 end + local _, q, r = find(z, "^%d*[%.%d]*([eE]?)", i) + i = q + 1 + if #r == 1 then -- optional exponent + if match(z, "^[%+%-]", i) then -- optional sign + i = i + 1 + end + end + local _, q = find(z, "^[_%w]*", i) + I = q + 1 + local v = sub(z, p, q) -- string equivalent + if not base.tonumber(v) then -- handles hex test also + errorline("malformed number") + end + addtoken("TK_NUMBER", v) + break -- (continue) + end + ---------------------------------------------------------------- + local p, q, r, t = find(z, "^((%s)[ \t\v\f]*)", i) + if p then + if t == "\n" or t == "\r" then -- newline + inclinenumber(i, true) + else + I = q + 1 -- whitespace + addtoken("TK_SPACE", r) + end + break -- (continue) + end + ---------------------------------------------------------------- + local r = match(z, "^%p", i) + if r then + buff = i + local p = find("-[\"\'.=<>~", r, 1, true) + if p then + -- two-level if block for punctuation/symbols + -------------------------------------------------------- + if p <= 2 then + if p == 1 then -- minus + local c = match(z, "^%-%-(%[?)", i) + if c then + i = i + 2 + local sep = -1 + if c == "[" then + sep = skip_sep(i) + end + if sep >= 0 then -- long comment + addtoken("TK_LCOMMENT", read_long_string(false, sep)) + else -- short comment + I = find(z, "[\n\r]", i) or (#z + 1) + addtoken("TK_COMMENT", sub(z, buff, I - 1)) + end + break -- (continue) + end + -- (fall through for "-") + else -- [ or long string + local sep = skip_sep(i) + if sep >= 0 then + addtoken("TK_LSTRING", read_long_string(true, sep)) + elseif sep == -1 then + addtoken("TK_OP", "[") + else + errorline("invalid long string delimiter") + end + break -- (continue) + end + -------------------------------------------------------- + elseif p <= 5 then + if p < 5 then -- strings + I = i + 1 + addtoken("TK_STRING", read_string(r)) + break -- (continue) + end + r = match(z, "^%.%.?%.?", i) -- .|..|... dots + -- (fall through) + -------------------------------------------------------- + else -- relational + r = match(z, "^%p=?", i) + -- (fall through) + end + end + I = i + #r + addtoken("TK_OP", r) -- for other symbols, fall through + break -- (continue) + end + ---------------------------------------------------------------- + local r = sub(z, i, i) + if r ~= "" then + I = i + 1 + addtoken("TK_OP", r) -- other single-char tokens + break + end + addtoken("TK_EOS", "") -- end of stream, + return -- exit here + ---------------------------------------------------------------- + end--while inner + end--while outer +end +--end of inserted module +end + +-- preload function for module lparser +preload.lparser = +function() +--start of inserted module +module "lparser" + +local string = base.require "string" + +--[[-------------------------------------------------------------------- +-- variable and data structure initialization +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- initialization: main variables +---------------------------------------------------------------------- + +local toklist, -- grammar-only token tables (token table, + seminfolist, -- semantic information table, line number + toklnlist, -- table, cross-reference table) + xreflist, + tpos, -- token position + + line, -- start line # for error messages + lastln, -- last line # for ambiguous syntax chk + tok, seminfo, ln, xref, -- token, semantic info, line + nameref, -- proper position of <name> token + fs, -- current function state + top_fs, -- top-level function state + + globalinfo, -- global variable information table + globallookup, -- global variable name lookup table + localinfo, -- local variable information table + ilocalinfo, -- inactive locals (prior to activation) + ilocalrefs, -- corresponding references to activate + statinfo -- statements labeled by type + +-- forward references for local functions +local explist1, expr, block, exp1, body, chunk + +---------------------------------------------------------------------- +-- initialization: data structures +---------------------------------------------------------------------- + +local gmatch = string.gmatch + +local block_follow = {} -- lookahead check in chunk(), returnstat() +for v in gmatch("else elseif end until <eof>", "%S+") do + block_follow[v] = true +end + +local binopr_left = {} -- binary operators, left priority +local binopr_right = {} -- binary operators, right priority +for op, lt, rt in gmatch([[ +{+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{% 7 7} +{^ 10 9}{.. 5 4} +{~= 3 3}{== 3 3} +{< 3 3}{<= 3 3}{> 3 3}{>= 3 3} +{and 2 2}{or 1 1} +]], "{(%S+)%s(%d+)%s(%d+)}") do + binopr_left[op] = lt + 0 + binopr_right[op] = rt + 0 +end + +local unopr = { ["not"] = true, ["-"] = true, + ["#"] = true, } -- unary operators +local UNARY_PRIORITY = 8 -- priority for unary operators + +--[[-------------------------------------------------------------------- +-- support functions +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- formats error message and throws error (duplicated from llex) +-- * a simplified version, does not report what token was responsible +---------------------------------------------------------------------- + +local function errorline(s, line) + local e = error or base.error + e(string.format("(source):%d: %s", line or ln, s)) +end + +---------------------------------------------------------------------- +-- handles incoming token, semantic information pairs +-- * NOTE: 'nextt' is named 'next' originally +---------------------------------------------------------------------- + +-- reads in next token +local function nextt() + lastln = toklnlist[tpos] + tok, seminfo, ln, xref + = toklist[tpos], seminfolist[tpos], toklnlist[tpos], xreflist[tpos] + tpos = tpos + 1 +end + +-- peek at next token (single lookahead for table constructor) +local function lookahead() + return toklist[tpos] +end + +---------------------------------------------------------------------- +-- throws a syntax error, or if token expected is not there +---------------------------------------------------------------------- + +local function syntaxerror(msg) + local tok = tok + if tok ~= "<number>" and tok ~= "<string>" then + if tok == "<name>" then tok = seminfo end + tok = "'"..tok.."'" + end + errorline(msg.." near "..tok) +end + +local function error_expected(token) + syntaxerror("'"..token.."' expected") +end + +---------------------------------------------------------------------- +-- tests for a token, returns outcome +-- * return value changed to boolean +---------------------------------------------------------------------- + +local function testnext(c) + if tok == c then nextt(); return true end +end + +---------------------------------------------------------------------- +-- check for existence of a token, throws error if not found +---------------------------------------------------------------------- + +local function check(c) + if tok ~= c then error_expected(c) end +end + +---------------------------------------------------------------------- +-- verify existence of a token, then skip it +---------------------------------------------------------------------- + +local function checknext(c) + check(c); nextt() +end + +---------------------------------------------------------------------- +-- throws error if condition not matched +---------------------------------------------------------------------- + +local function check_condition(c, msg) + if not c then syntaxerror(msg) end +end + +---------------------------------------------------------------------- +-- verifies token conditions are met or else throw error +---------------------------------------------------------------------- + +local function check_match(what, who, where) + if not testnext(what) then + if where == ln then + error_expected(what) + else + syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")") + end + end +end + +---------------------------------------------------------------------- +-- expect that token is a name, return the name +---------------------------------------------------------------------- + +local function str_checkname() + check("<name>") + local ts = seminfo + nameref = xref + nextt() + return ts +end + +---------------------------------------------------------------------- +-- adds given string s in string pool, sets e as VK +---------------------------------------------------------------------- + +local function codestring(e, s) + e.k = "VK" +end + +---------------------------------------------------------------------- +-- consume a name token, adds it to string pool +---------------------------------------------------------------------- + +local function checkname(e) + codestring(e, str_checkname()) +end + +--[[-------------------------------------------------------------------- +-- variable (global|local|upvalue) handling +-- * to track locals and globals, variable management code needed +-- * entry point is singlevar() for variable lookups +-- * lookup tables (bl.locallist) are maintained awkwardly in the basic +-- block data structures, PLUS the function data structure (this is +-- an inelegant hack, since bl is nil for the top level of a function) +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- register a local variable, create local variable object, set in +-- to-activate variable list +-- * used in new_localvarliteral(), parlist(), fornum(), forlist(), +-- localfunc(), localstat() +---------------------------------------------------------------------- + +local function new_localvar(name, special) + local bl = fs.bl + local locallist + -- locate locallist in current block object or function root object + if bl then + locallist = bl.locallist + else + locallist = fs.locallist + end + -- build local variable information object and set localinfo + local id = #localinfo + 1 + localinfo[id] = { -- new local variable object + name = name, -- local variable name + xref = { nameref }, -- xref, first value is declaration + decl = nameref, -- location of declaration, = xref[1] + } + if special then -- "self" must be not be changed + localinfo[id].isself = true + end + -- this can override a local with the same name in the same scope + -- but first, keep it inactive until it gets activated + local i = #ilocalinfo + 1 + ilocalinfo[i] = id + ilocalrefs[i] = locallist +end + +---------------------------------------------------------------------- +-- actually activate the variables so that they are visible +-- * remember Lua semantics, e.g. RHS is evaluated first, then LHS +-- * used in parlist(), forbody(), localfunc(), localstat(), body() +---------------------------------------------------------------------- + +local function adjustlocalvars(nvars) + local sz = #ilocalinfo + -- i goes from left to right, in order of local allocation, because + -- of something like: local a,a,a = 1,2,3 which gives a = 3 + while nvars > 0 do + nvars = nvars - 1 + local i = sz - nvars + local id = ilocalinfo[i] -- local's id + local obj = localinfo[id] + local name = obj.name -- name of local + obj.act = xref -- set activation location + ilocalinfo[i] = nil + local locallist = ilocalrefs[i] -- ref to lookup table to update + ilocalrefs[i] = nil + local existing = locallist[name] -- if existing, remove old first! + if existing then -- do not overlap, set special + obj = localinfo[existing] -- form of rem, as -id + obj.rem = -id + end + locallist[name] = id -- activate, now visible to Lua + end +end + +---------------------------------------------------------------------- +-- remove (deactivate) variables in current scope (before scope exits) +-- * zap entire locallist tables since we are not allocating registers +-- * used in leaveblock(), close_func() +---------------------------------------------------------------------- + +local function removevars() + local bl = fs.bl + local locallist + -- locate locallist in current block object or function root object + if bl then + locallist = bl.locallist + else + locallist = fs.locallist + end + -- enumerate the local list at current scope and deactivate 'em + for name, id in base.pairs(locallist) do + local obj = localinfo[id] + obj.rem = xref -- set deactivation location + end +end + +---------------------------------------------------------------------- +-- creates a new local variable given a name +-- * skips internal locals (those starting with '('), so internal +-- locals never needs a corresponding adjustlocalvars() call +-- * special is true for "self" which must not be optimized +-- * used in fornum(), forlist(), parlist(), body() +---------------------------------------------------------------------- + +local function new_localvarliteral(name, special) + if string.sub(name, 1, 1) == "(" then -- can skip internal locals + return + end + new_localvar(name, special) +end + +---------------------------------------------------------------------- +-- search the local variable namespace of the given fs for a match +-- * returns localinfo index +-- * used only in singlevaraux() +---------------------------------------------------------------------- + +local function searchvar(fs, n) + local bl = fs.bl + local locallist + if bl then + locallist = bl.locallist + while locallist do + if locallist[n] then return locallist[n] end -- found + bl = bl.prev + locallist = bl and bl.locallist + end + end + locallist = fs.locallist + return locallist[n] or -1 -- found or not found (-1) +end + +---------------------------------------------------------------------- +-- handle locals, globals and upvalues and related processing +-- * search mechanism is recursive, calls itself to search parents +-- * used only in singlevar() +---------------------------------------------------------------------- + +local function singlevaraux(fs, n, var) + if fs == nil then -- no more levels? + var.k = "VGLOBAL" -- default is global variable + return "VGLOBAL" + else + local v = searchvar(fs, n) -- look up at current level + if v >= 0 then + var.k = "VLOCAL" + var.id = v + -- codegen may need to deal with upvalue here + return "VLOCAL" + else -- not found at current level; try upper one + if singlevaraux(fs.prev, n, var) == "VGLOBAL" then + return "VGLOBAL" + end + -- else was LOCAL or UPVAL, handle here + var.k = "VUPVAL" -- upvalue in this level + return "VUPVAL" + end--if v + end--if fs +end + +---------------------------------------------------------------------- +-- consume a name token, creates a variable (global|local|upvalue) +-- * used in prefixexp(), funcname() +---------------------------------------------------------------------- + +local function singlevar(v) + local name = str_checkname() + singlevaraux(fs, name, v) + ------------------------------------------------------------------ + -- variable tracking + ------------------------------------------------------------------ + if v.k == "VGLOBAL" then + -- if global being accessed, keep track of it by creating an object + local id = globallookup[name] + if not id then + id = #globalinfo + 1 + globalinfo[id] = { -- new global variable object + name = name, -- global variable name + xref = { nameref }, -- xref, first value is declaration + } + globallookup[name] = id -- remember it + else + local obj = globalinfo[id].xref + obj[#obj + 1] = nameref -- add xref + end + else + -- local/upvalue is being accessed, keep track of it + local id = v.id + local obj = localinfo[id].xref + obj[#obj + 1] = nameref -- add xref + end +end + +--[[-------------------------------------------------------------------- +-- state management functions with open/close pairs +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- enters a code unit, initializes elements +---------------------------------------------------------------------- + +local function enterblock(isbreakable) + local bl = {} -- per-block state + bl.isbreakable = isbreakable + bl.prev = fs.bl + bl.locallist = {} + fs.bl = bl +end + +---------------------------------------------------------------------- +-- leaves a code unit, close any upvalues +---------------------------------------------------------------------- + +local function leaveblock() + local bl = fs.bl + removevars() + fs.bl = bl.prev +end + +---------------------------------------------------------------------- +-- opening of a function +-- * top_fs is only for anchoring the top fs, so that parser() can +-- return it to the caller function along with useful output +-- * used in parser() and body() +---------------------------------------------------------------------- + +local function open_func() + local new_fs -- per-function state + if not fs then -- top_fs is created early + new_fs = top_fs + else + new_fs = {} + end + new_fs.prev = fs -- linked list of function states + new_fs.bl = nil + new_fs.locallist = {} + fs = new_fs +end + +---------------------------------------------------------------------- +-- closing of a function +-- * used in parser() and body() +---------------------------------------------------------------------- + +local function close_func() + removevars() + fs = fs.prev +end + +--[[-------------------------------------------------------------------- +-- other parsing functions +-- * for table constructor, parameter list, argument list +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- parse a function name suffix, for function call specifications +-- * used in primaryexp(), funcname() +---------------------------------------------------------------------- + +local function field(v) + -- field -> ['.' | ':'] NAME + local key = {} + nextt() -- skip the dot or colon + checkname(key) + v.k = "VINDEXED" +end + +---------------------------------------------------------------------- +-- parse a table indexing suffix, for constructors, expressions +-- * used in recfield(), primaryexp() +---------------------------------------------------------------------- + +local function yindex(v) + -- index -> '[' expr ']' + nextt() -- skip the '[' + expr(v) + checknext("]") +end + +---------------------------------------------------------------------- +-- parse a table record (hash) field +-- * used in constructor() +---------------------------------------------------------------------- + +local function recfield(cc) + -- recfield -> (NAME | '['exp1']') = exp1 + local key, val = {}, {} + if tok == "<name>" then + checkname(key) + else-- tok == '[' + yindex(key) + end + checknext("=") + expr(val) +end + +---------------------------------------------------------------------- +-- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) +-- * note: retained in this skeleton because it modifies cc.v.k +-- * used in constructor() +---------------------------------------------------------------------- + +local function closelistfield(cc) + if cc.v.k == "VVOID" then return end -- there is no list item + cc.v.k = "VVOID" +end + +---------------------------------------------------------------------- +-- parse a table list (array) field +-- * used in constructor() +---------------------------------------------------------------------- + +local function listfield(cc) + expr(cc.v) +end + +---------------------------------------------------------------------- +-- parse a table constructor +-- * used in funcargs(), simpleexp() +---------------------------------------------------------------------- + +local function constructor(t) + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- field -> recfield | listfield + -- fieldsep -> ',' | ';' + local line = ln + local cc = {} + cc.v = {} + cc.t = t + t.k = "VRELOCABLE" + cc.v.k = "VVOID" + checknext("{") + repeat + if tok == "}" then break end + -- closelistfield(cc) here + local c = tok + if c == "<name>" then -- may be listfields or recfields + if lookahead() ~= "=" then -- look ahead: expression? + listfield(cc) + else + recfield(cc) + end + elseif c == "[" then -- constructor_item -> recfield + recfield(cc) + else -- constructor_part -> listfield + listfield(cc) + end + until not testnext(",") and not testnext(";") + check_match("}", "{", line) + -- lastlistfield(cc) here +end + +---------------------------------------------------------------------- +-- parse the arguments (parameters) of a function declaration +-- * used in body() +---------------------------------------------------------------------- + +local function parlist() + -- parlist -> [ param { ',' param } ] + local nparams = 0 + if tok ~= ")" then -- is 'parlist' not empty? + repeat + local c = tok + if c == "<name>" then -- param -> NAME + new_localvar(str_checkname()) + nparams = nparams + 1 + elseif c == "..." then + nextt() + fs.is_vararg = true + else + syntaxerror("<name> or '...' expected") + end + until fs.is_vararg or not testnext(",") + end--if + adjustlocalvars(nparams) +end + +---------------------------------------------------------------------- +-- parse the parameters of a function call +-- * contrast with parlist(), used in function declarations +-- * used in primaryexp() +---------------------------------------------------------------------- + +local function funcargs(f) + local args = {} + local line = ln + local c = tok + if c == "(" then -- funcargs -> '(' [ explist1 ] ')' + if line ~= lastln then + syntaxerror("ambiguous syntax (function call x new statement)") + end + nextt() + if tok == ")" then -- arg list is empty? + args.k = "VVOID" + else + explist1(args) + end + check_match(")", "(", line) + elseif c == "{" then -- funcargs -> constructor + constructor(args) + elseif c == "<string>" then -- funcargs -> STRING + codestring(args, seminfo) + nextt() -- must use 'seminfo' before 'next' + else + syntaxerror("function arguments expected") + return + end--if c + f.k = "VCALL" +end + +--[[-------------------------------------------------------------------- +-- mostly expression functions +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- parses an expression in parentheses or a single variable +-- * used in primaryexp() +---------------------------------------------------------------------- + +local function prefixexp(v) + -- prefixexp -> NAME | '(' expr ')' + local c = tok + if c == "(" then + local line = ln + nextt() + expr(v) + check_match(")", "(", line) + elseif c == "<name>" then + singlevar(v) + else + syntaxerror("unexpected symbol") + end--if c +end + +---------------------------------------------------------------------- +-- parses a prefixexp (an expression in parentheses or a single +-- variable) or a function call specification +-- * used in simpleexp(), assignment(), expr_stat() +---------------------------------------------------------------------- + +local function primaryexp(v) + -- primaryexp -> + -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + prefixexp(v) + while true do + local c = tok + if c == "." then -- field + field(v) + elseif c == "[" then -- '[' exp1 ']' + local key = {} + yindex(key) + elseif c == ":" then -- ':' NAME funcargs + local key = {} + nextt() + checkname(key) + funcargs(v) + elseif c == "(" or c == "<string>" or c == "{" then -- funcargs + funcargs(v) + else + return + end--if c + end--while +end + +---------------------------------------------------------------------- +-- parses general expression types, constants handled here +-- * used in subexpr() +---------------------------------------------------------------------- + +local function simpleexp(v) + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | + -- constructor | FUNCTION body | primaryexp + local c = tok + if c == "<number>" then + v.k = "VKNUM" + elseif c == "<string>" then + codestring(v, seminfo) + elseif c == "nil" then + v.k = "VNIL" + elseif c == "true" then + v.k = "VTRUE" + elseif c == "false" then + v.k = "VFALSE" + elseif c == "..." then -- vararg + check_condition(fs.is_vararg == true, + "cannot use '...' outside a vararg function"); + v.k = "VVARARG" + elseif c == "{" then -- constructor + constructor(v) + return + elseif c == "function" then + nextt() + body(v, false, ln) + return + else + primaryexp(v) + return + end--if c + nextt() +end + +------------------------------------------------------------------------ +-- Parse subexpressions. Includes handling of unary operators and binary +-- operators. A subexpr is given the rhs priority level of the operator +-- immediately left of it, if any (limit is -1 if none,) and if a binop +-- is found, limit is compared with the lhs priority level of the binop +-- in order to determine which executes first. +-- * recursively called +-- * used in expr() +------------------------------------------------------------------------ + +local function subexpr(v, limit) + -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } + -- * where 'binop' is any binary operator with a priority + -- higher than 'limit' + local op = tok + local uop = unopr[op] + if uop then + nextt() + subexpr(v, UNARY_PRIORITY) + else + simpleexp(v) + end + -- expand while operators have priorities higher than 'limit' + op = tok + local binop = binopr_left[op] + while binop and binop > limit do + local v2 = {} + nextt() + -- read sub-expression with higher priority + local nextop = subexpr(v2, binopr_right[op]) + op = nextop + binop = binopr_left[op] + end + return op -- return first untreated operator +end + +---------------------------------------------------------------------- +-- Expression parsing starts here. Function subexpr is entered with the +-- left operator (which is non-existent) priority of -1, which is lower +-- than all actual operators. Expr information is returned in parm v. +-- * used in cond(), explist1(), index(), recfield(), listfield(), +-- prefixexp(), while_stat(), exp1() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function expr(v) + -- expr -> subexpr + subexpr(v, 0) +end + +--[[-------------------------------------------------------------------- +-- third level parsing functions +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parse a variable assignment sequence +-- * recursively called +-- * used in expr_stat() +------------------------------------------------------------------------ + +local function assignment(v) + local e = {} + local c = v.v.k + check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" + or c == "VINDEXED", "syntax error") + if testnext(",") then -- assignment -> ',' primaryexp assignment + local nv = {} -- expdesc + nv.v = {} + primaryexp(nv.v) + -- lparser.c deals with some register usage conflict here + assignment(nv) + else -- assignment -> '=' explist1 + checknext("=") + explist1(e) + return -- avoid default + end + e.k = "VNONRELOC" +end + +---------------------------------------------------------------------- +-- parse a for loop body for both versions of the for loop +-- * used in fornum(), forlist() +---------------------------------------------------------------------- + +local function forbody(nvars, isnum) + -- forbody -> DO block + checknext("do") + enterblock(false) -- scope for declared variables + adjustlocalvars(nvars) + block() + leaveblock() -- end of scope for declared variables +end + +---------------------------------------------------------------------- +-- parse a numerical for loop, calls forbody() +-- * used in for_stat() +---------------------------------------------------------------------- + +local function fornum(varname) + -- fornum -> NAME = exp1, exp1 [, exp1] DO body + local line = line + new_localvarliteral("(for index)") + new_localvarliteral("(for limit)") + new_localvarliteral("(for step)") + new_localvar(varname) + checknext("=") + exp1() -- initial value + checknext(",") + exp1() -- limit + if testnext(",") then + exp1() -- optional step + else + -- default step = 1 + end + forbody(1, true) +end + +---------------------------------------------------------------------- +-- parse a generic for loop, calls forbody() +-- * used in for_stat() +---------------------------------------------------------------------- + +local function forlist(indexname) + -- forlist -> NAME {, NAME} IN explist1 DO body + local e = {} + -- create control variables + new_localvarliteral("(for generator)") + new_localvarliteral("(for state)") + new_localvarliteral("(for control)") + -- create declared variables + new_localvar(indexname) + local nvars = 1 + while testnext(",") do + new_localvar(str_checkname()) + nvars = nvars + 1 + end + checknext("in") + local line = line + explist1(e) + forbody(nvars, false) +end + +---------------------------------------------------------------------- +-- parse a function name specification +-- * used in func_stat() +---------------------------------------------------------------------- + +local function funcname(v) + -- funcname -> NAME {field} [':' NAME] + local needself = false + singlevar(v) + while tok == "." do + field(v) + end + if tok == ":" then + needself = true + field(v) + end + return needself +end + +---------------------------------------------------------------------- +-- parse the single expressions needed in numerical for loops +-- * used in fornum() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function exp1() + -- exp1 -> expr + local e = {} + expr(e) +end + +---------------------------------------------------------------------- +-- parse condition in a repeat statement or an if control structure +-- * used in repeat_stat(), test_then_block() +---------------------------------------------------------------------- + +local function cond() + -- cond -> expr + local v = {} + expr(v) -- read condition +end + +---------------------------------------------------------------------- +-- parse part of an if control structure, including the condition +-- * used in if_stat() +---------------------------------------------------------------------- + +local function test_then_block() + -- test_then_block -> [IF | ELSEIF] cond THEN block + nextt() -- skip IF or ELSEIF + cond() + checknext("then") + block() -- 'then' part +end + +---------------------------------------------------------------------- +-- parse a local function statement +-- * used in local_stat() +---------------------------------------------------------------------- + +local function localfunc() + -- localfunc -> NAME body + local v, b = {} + new_localvar(str_checkname()) + v.k = "VLOCAL" + adjustlocalvars(1) + body(b, false, ln) +end + +---------------------------------------------------------------------- +-- parse a local variable declaration statement +-- * used in local_stat() +---------------------------------------------------------------------- + +local function localstat() + -- localstat -> NAME {',' NAME} ['=' explist1] + local nvars = 0 + local e = {} + repeat + new_localvar(str_checkname()) + nvars = nvars + 1 + until not testnext(",") + if testnext("=") then + explist1(e) + else + e.k = "VVOID" + end + adjustlocalvars(nvars) +end + +---------------------------------------------------------------------- +-- parse a list of comma-separated expressions +-- * used in return_stat(), localstat(), funcargs(), assignment(), +-- forlist() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function explist1(e) + -- explist1 -> expr { ',' expr } + expr(e) + while testnext(",") do + expr(e) + end +end + +---------------------------------------------------------------------- +-- parse function declaration body +-- * used in simpleexp(), localfunc(), func_stat() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function body(e, needself, line) + -- body -> '(' parlist ')' chunk END + open_func() + checknext("(") + if needself then + new_localvarliteral("self", true) + adjustlocalvars(1) + end + parlist() + checknext(")") + chunk() + check_match("end", "function", line) + close_func() +end + +---------------------------------------------------------------------- +-- parse a code block or unit +-- * used in do_stat(), while_stat(), forbody(), test_then_block(), +-- if_stat() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function block() + -- block -> chunk + enterblock(false) + chunk() + leaveblock() +end + +--[[-------------------------------------------------------------------- +-- second level parsing functions, all with '_stat' suffix +-- * since they are called via a table lookup, they cannot be local +-- functions (a lookup table of local functions might be smaller...) +-- * stat() -> *_stat() +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- initial parsing for a for loop, calls fornum() or forlist() +-- * removed 'line' parameter (used to set debug information only) +-- * used in stat() +---------------------------------------------------------------------- + +local function for_stat() + -- stat -> for_stat -> FOR (fornum | forlist) END + local line = line + enterblock(true) -- scope for loop and control variables + nextt() -- skip 'for' + local varname = str_checkname() -- first variable name + local c = tok + if c == "=" then + fornum(varname) + elseif c == "," or c == "in" then + forlist(varname) + else + syntaxerror("'=' or 'in' expected") + end + check_match("end", "for", line) + leaveblock() -- loop scope (`break' jumps to this point) +end + +---------------------------------------------------------------------- +-- parse a while-do control structure, body processed by block() +-- * used in stat() +---------------------------------------------------------------------- + +local function while_stat() + -- stat -> while_stat -> WHILE cond DO block END + local line = line + nextt() -- skip WHILE + cond() -- parse condition + enterblock(true) + checknext("do") + block() + check_match("end", "while", line) + leaveblock() +end + +---------------------------------------------------------------------- +-- parse a repeat-until control structure, body parsed by chunk() +-- * originally, repeatstat() calls breakstat() too if there is an +-- upvalue in the scope block; nothing is actually lexed, it is +-- actually the common code in breakstat() for closing of upvalues +-- * used in stat() +---------------------------------------------------------------------- + +local function repeat_stat() + -- stat -> repeat_stat -> REPEAT block UNTIL cond + local line = line + enterblock(true) -- loop block + enterblock(false) -- scope block + nextt() -- skip REPEAT + chunk() + check_match("until", "repeat", line) + cond() + -- close upvalues at scope level below + leaveblock() -- finish scope + leaveblock() -- finish loop +end + +---------------------------------------------------------------------- +-- parse an if control structure +-- * used in stat() +---------------------------------------------------------------------- + +local function if_stat() + -- stat -> if_stat -> IF cond THEN block + -- {ELSEIF cond THEN block} [ELSE block] END + local line = line + local v = {} + test_then_block() -- IF cond THEN block + while tok == "elseif" do + test_then_block() -- ELSEIF cond THEN block + end + if tok == "else" then + nextt() -- skip ELSE + block() -- 'else' part + end + check_match("end", "if", line) +end + +---------------------------------------------------------------------- +-- parse a return statement +-- * used in stat() +---------------------------------------------------------------------- + +local function return_stat() + -- stat -> return_stat -> RETURN explist + local e = {} + nextt() -- skip RETURN + local c = tok + if block_follow[c] or c == ";" then + -- return no values + else + explist1(e) -- optional return values + end +end + +---------------------------------------------------------------------- +-- parse a break statement +-- * used in stat() +---------------------------------------------------------------------- + +local function break_stat() + -- stat -> break_stat -> BREAK + local bl = fs.bl + nextt() -- skip BREAK + while bl and not bl.isbreakable do -- find a breakable block + bl = bl.prev + end + if not bl then + syntaxerror("no loop to break") + end +end + +---------------------------------------------------------------------- +-- parse a function call with no returns or an assignment statement +-- * the struct with .prev is used for name searching in lparse.c, +-- so it is retained for now; present in assignment() also +-- * used in stat() +---------------------------------------------------------------------- + +local function expr_stat() + local id = tpos - 1 + -- stat -> expr_stat -> func | assignment + local v = {} + v.v = {} + primaryexp(v.v) + if v.v.k == "VCALL" then -- stat -> func + -- call statement uses no results + statinfo[id] = "call" + else -- stat -> assignment + v.prev = nil + assignment(v) + statinfo[id] = "assign" + end +end + +---------------------------------------------------------------------- +-- parse a function statement +-- * used in stat() +---------------------------------------------------------------------- + +local function function_stat() + -- stat -> function_stat -> FUNCTION funcname body + local line = line + local v, b = {}, {} + nextt() -- skip FUNCTION + local needself = funcname(v) + body(b, needself, line) +end + +---------------------------------------------------------------------- +-- parse a simple block enclosed by a DO..END pair +-- * used in stat() +---------------------------------------------------------------------- + +local function do_stat() + -- stat -> do_stat -> DO block END + local line = line + nextt() -- skip DO + block() + check_match("end", "do", line) +end + +---------------------------------------------------------------------- +-- parse a statement starting with LOCAL +-- * used in stat() +---------------------------------------------------------------------- + +local function local_stat() + -- stat -> local_stat -> LOCAL FUNCTION localfunc + -- -> LOCAL localstat + nextt() -- skip LOCAL + if testnext("function") then -- local function? + localfunc() + else + localstat() + end +end + +--[[-------------------------------------------------------------------- +-- main functions, top level parsing functions +-- * accessible functions are: init(lexer), parser() +-- * [entry] -> parser() -> chunk() -> stat() +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- initial parsing for statements, calls '_stat' suffixed functions +-- * used in chunk() +---------------------------------------------------------------------- + +local stat_call = { -- lookup for calls in stat() + ["if"] = if_stat, + ["while"] = while_stat, + ["do"] = do_stat, + ["for"] = for_stat, + ["repeat"] = repeat_stat, + ["function"] = function_stat, + ["local"] = local_stat, + ["return"] = return_stat, + ["break"] = break_stat, +} + +local function stat() + -- stat -> if_stat while_stat do_stat for_stat repeat_stat + -- function_stat local_stat return_stat break_stat + -- expr_stat + line = ln -- may be needed for error messages + local c = tok + local fn = stat_call[c] + -- handles: if while do for repeat function local return break + if fn then + statinfo[tpos - 1] = c + fn() + -- return or break must be last statement + if c == "return" or c == "break" then return true end + else + expr_stat() + end + return false +end + +---------------------------------------------------------------------- +-- parse a chunk, which consists of a bunch of statements +-- * used in parser(), body(), block(), repeat_stat() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function chunk() + -- chunk -> { stat [';'] } + local islast = false + while not islast and not block_follow[tok] do + islast = stat() + testnext(";") + end +end + +---------------------------------------------------------------------- +-- performs parsing, returns parsed data structure +---------------------------------------------------------------------- + +function parser() + open_func() + fs.is_vararg = true -- main func. is always vararg + nextt() -- read first token + chunk() + check("<eof>") + close_func() + return { -- return everything + globalinfo = globalinfo, + localinfo = localinfo, + statinfo = statinfo, + toklist = toklist, + seminfolist = seminfolist, + toklnlist = toklnlist, + xreflist = xreflist, + } +end + +---------------------------------------------------------------------- +-- initialization function +---------------------------------------------------------------------- + +function init(tokorig, seminfoorig, toklnorig) + tpos = 1 -- token position + top_fs = {} -- reset top level function state + ------------------------------------------------------------------ + -- set up grammar-only token tables; impedance-matching... + -- note that constants returned by the lexer is source-level, so + -- for now, fake(!) constant tokens (TK_NUMBER|TK_STRING|TK_LSTRING) + ------------------------------------------------------------------ + local j = 1 + toklist, seminfolist, toklnlist, xreflist = {}, {}, {}, {} + for i = 1, #tokorig do + local tok = tokorig[i] + local yep = true + if tok == "TK_KEYWORD" or tok == "TK_OP" then + tok = seminfoorig[i] + elseif tok == "TK_NAME" then + tok = "<name>" + seminfolist[j] = seminfoorig[i] + elseif tok == "TK_NUMBER" then + tok = "<number>" + seminfolist[j] = 0 -- fake! + elseif tok == "TK_STRING" or tok == "TK_LSTRING" then + tok = "<string>" + seminfolist[j] = "" -- fake! + elseif tok == "TK_EOS" then + tok = "<eof>" + else + -- non-grammar tokens; ignore them + yep = false + end + if yep then -- set rest of the information + toklist[j] = tok + toklnlist[j] = toklnorig[i] + xreflist[j] = i + j = j + 1 + end + end--for + ------------------------------------------------------------------ + -- initialize data structures for variable tracking + ------------------------------------------------------------------ + globalinfo, globallookup, localinfo = {}, {}, {} + ilocalinfo, ilocalrefs = {}, {} + statinfo = {} -- experimental +end +--end of inserted module +end + +-- preload function for module optlex +preload.optlex = +function() +--start of inserted module +module "optlex" + +local string = base.require "string" +local match = string.match +local sub = string.sub +local find = string.find +local rep = string.rep +local print + +------------------------------------------------------------------------ +-- variables and data structures +------------------------------------------------------------------------ + +-- error function, can override by setting own function into module +error = base.error + +warn = {} -- table for warning flags + +local stoks, sinfos, stoklns -- source lists + +local is_realtoken = { -- significant (grammar) tokens + TK_KEYWORD = true, + TK_NAME = true, + TK_NUMBER = true, + TK_STRING = true, + TK_LSTRING = true, + TK_OP = true, + TK_EOS = true, +} +local is_faketoken = { -- whitespace (non-grammar) tokens + TK_COMMENT = true, + TK_LCOMMENT = true, + TK_EOL = true, + TK_SPACE = true, +} + +local opt_details -- for extra information + +------------------------------------------------------------------------ +-- true if current token is at the start of a line +-- * skips over deleted tokens via recursion +------------------------------------------------------------------------ + +local function atlinestart(i) + local tok = stoks[i - 1] + if i <= 1 or tok == "TK_EOL" then + return true + elseif tok == "" then + return atlinestart(i - 1) + end + return false +end + +------------------------------------------------------------------------ +-- true if current token is at the end of a line +-- * skips over deleted tokens via recursion +------------------------------------------------------------------------ + +local function atlineend(i) + local tok = stoks[i + 1] + if i >= #stoks or tok == "TK_EOL" or tok == "TK_EOS" then + return true + elseif tok == "" then + return atlineend(i + 1) + end + return false +end + +------------------------------------------------------------------------ +-- counts comment EOLs inside a long comment +-- * in order to keep line numbering, EOLs need to be reinserted +------------------------------------------------------------------------ + +local function commenteols(lcomment) + local sep = #match(lcomment, "^%-%-%[=*%[") + local z = sub(lcomment, sep + 1, -(sep - 1)) -- remove delims + local i, c = 1, 0 + while true do + local p, q, r, s = find(z, "([\r\n])([\r\n]?)", i) + if not p then break end -- if no matches, done + i = p + 1 + c = c + 1 + if #s > 0 and r ~= s then -- skip CRLF or LFCR + i = i + 1 + end + end + return c +end + +------------------------------------------------------------------------ +-- compares two tokens (i, j) and returns the whitespace required +-- * see documentation for a reference table of interactions +-- * only two grammar/real tokens are being considered +-- * if "", no separation is needed +-- * if " ", then at least one whitespace (or EOL) is required +-- * NOTE: this doesn't work at the start or the end or for EOS! +------------------------------------------------------------------------ + +local function checkpair(i, j) + local match = match + local t1, t2 = stoks[i], stoks[j] + -------------------------------------------------------------------- + if t1 == "TK_STRING" or t1 == "TK_LSTRING" or + t2 == "TK_STRING" or t2 == "TK_LSTRING" then + return "" + -------------------------------------------------------------------- + elseif t1 == "TK_OP" or t2 == "TK_OP" then + if (t1 == "TK_OP" and (t2 == "TK_KEYWORD" or t2 == "TK_NAME")) or + (t2 == "TK_OP" and (t1 == "TK_KEYWORD" or t1 == "TK_NAME")) then + return "" + end + if t1 == "TK_OP" and t2 == "TK_OP" then + -- for TK_OP/TK_OP pairs, see notes in technotes.txt + local op, op2 = sinfos[i], sinfos[j] + if (match(op, "^%.%.?$") and match(op2, "^%.")) or + (match(op, "^[~=<>]$") and op2 == "=") or + (op == "[" and (op2 == "[" or op2 == "=")) then + return " " + end + return "" + end + -- "TK_OP" + "TK_NUMBER" case + local op = sinfos[i] + if t2 == "TK_OP" then op = sinfos[j] end + if match(op, "^%.%.?%.?$") then + return " " + end + return "" + -------------------------------------------------------------------- + else-- "TK_KEYWORD" | "TK_NAME" | "TK_NUMBER" then + return " " + -------------------------------------------------------------------- + end +end + +------------------------------------------------------------------------ +-- repack tokens, removing deletions caused by optimization process +------------------------------------------------------------------------ + +local function repack_tokens() + local dtoks, dinfos, dtoklns = {}, {}, {} + local j = 1 + for i = 1, #stoks do + local tok = stoks[i] + if tok ~= "" then + dtoks[j], dinfos[j], dtoklns[j] = tok, sinfos[i], stoklns[i] + j = j + 1 + end + end + stoks, sinfos, stoklns = dtoks, dinfos, dtoklns +end + +------------------------------------------------------------------------ +-- number optimization +-- * optimization using string formatting functions is one way of doing +-- this, but here, we consider all cases and handle them separately +-- (possibly an idiotic approach...) +-- * scientific notation being generated is not in canonical form, this +-- may or may not be a bad thing +-- * note: intermediate portions need to fit into a normal number range +-- * optimizations can be divided based on number patterns: +-- * hexadecimal: +-- (1) no need to remove leading zeros, just skip to (2) +-- (2) convert to integer if size equal or smaller +-- * change if equal size -> lose the 'x' to reduce entropy +-- (3) number is then processed as an integer +-- (4) note: does not make 0[xX] consistent +-- * integer: +-- (1) note: includes anything with trailing ".", ".0", ... +-- (2) remove useless fractional part, if present, e.g. 123.000 +-- (3) remove leading zeros, e.g. 000123 +-- (4) switch to scientific if shorter, e.g. 123000 -> 123e3 +-- * with fraction: +-- (1) split into digits dot digits +-- (2) if no integer portion, take as zero (can omit later) +-- (3) handle degenerate .000 case, after which the fractional part +-- must be non-zero (if zero, it's matched as an integer) +-- (4) remove trailing zeros for fractional portion +-- (5) p.q where p > 0 and q > 0 cannot be shortened any more +-- (6) otherwise p == 0 and the form is .q, e.g. .000123 +-- (7) if scientific shorter, convert, e.g. .000123 -> 123e-6 +-- * scientific: +-- (1) split into (digits dot digits) [eE] ([+-] digits) +-- (2) if significand has ".", shift it out so it becomes an integer +-- (3) if significand is zero, just use zero +-- (4) remove leading zeros for significand +-- (5) shift out trailing zeros for significand +-- (6) examine exponent and determine which format is best: +-- integer, with fraction, scientific +------------------------------------------------------------------------ + +local function do_number(i) + local before = sinfos[i] -- 'before' + local z = before -- working representation + local y -- 'after', if better + -------------------------------------------------------------------- + if match(z, "^0[xX]") then -- hexadecimal number + local v = base.tostring(base.tonumber(z)) + if #v <= #z then + z = v -- change to integer, AND continue + else + return -- no change; stick to hex + end + end + -------------------------------------------------------------------- + if match(z, "^%d+%.?0*$") then -- integer or has useless frac + z = match(z, "^(%d+)%.?0*$") -- int portion only + if z + 0 > 0 then + z = match(z, "^0*([1-9]%d*)$") -- remove leading zeros + local v = #match(z, "0*$") + local nv = base.tostring(v) + if v > #nv + 1 then -- scientific is shorter + z = sub(z, 1, #z - v).."e"..nv + end + y = z + else + y = "0" -- basic zero + end + -------------------------------------------------------------------- + elseif not match(z, "[eE]") then -- number with fraction part + local p, q = match(z, "^(%d*)%.(%d+)$") -- split + if p == "" then p = 0 end -- int part zero + if q + 0 == 0 and p == 0 then + y = "0" -- degenerate .000 case + else + -- now, q > 0 holds and p is a number + local v = #match(q, "0*$") -- remove trailing zeros + if v > 0 then + q = sub(q, 1, #q - v) + end + -- if p > 0, nothing else we can do to simplify p.q case + if p + 0 > 0 then + y = p.."."..q + else + y = "."..q -- tentative, e.g. .000123 + local v = #match(q, "^0*") -- # leading spaces + local w = #q - v -- # significant digits + local nv = base.tostring(#q) + -- e.g. compare 123e-6 versus .000123 + if w + 2 + #nv < 1 + #q then + y = sub(q, -w).."e-"..nv + end + end + end + -------------------------------------------------------------------- + else -- scientific number + local sig, ex = match(z, "^([^eE]+)[eE]([%+%-]?%d+)$") + ex = base.tonumber(ex) + -- if got ".", shift out fractional portion of significand + local p, q = match(sig, "^(%d*)%.(%d*)$") + if p then + ex = ex - #q + sig = p..q + end + if sig + 0 == 0 then + y = "0" -- basic zero + else + local v = #match(sig, "^0*") -- remove leading zeros + sig = sub(sig, v + 1) + v = #match(sig, "0*$") -- shift out trailing zeros + if v > 0 then + sig = sub(sig, 1, #sig - v) + ex = ex + v + end + -- examine exponent and determine which format is best + local nex = base.tostring(ex) + if ex == 0 then -- it's just an integer + y = sig + elseif ex > 0 and (ex <= 1 + #nex) then -- a number + y = sig..rep("0", ex) + elseif ex < 0 and (ex >= -#sig) then -- fraction, e.g. .123 + v = #sig + ex + y = sub(sig, 1, v).."."..sub(sig, v + 1) + elseif ex < 0 and (#nex >= -ex - #sig) then + -- e.g. compare 1234e-5 versus .01234 + -- gives: #sig + 1 + #nex >= 1 + (-ex - #sig) + #sig + -- -> #nex >= -ex - #sig + v = -ex - #sig + y = "."..rep("0", v)..sig + else -- non-canonical scientific representation + y = sig.."e"..ex + end + end--if sig + end + -------------------------------------------------------------------- + if y and y ~= sinfos[i] then + if opt_details then + print("<number> (line "..stoklns[i]..") "..sinfos[i].." -> "..y) + opt_details = opt_details + 1 + end + sinfos[i] = y + end +end + +------------------------------------------------------------------------ +-- string optimization +-- * note: works on well-formed strings only! +-- * optimizations on characters can be summarized as follows: +-- \a\b\f\n\r\t\v -- no change +-- \\ -- no change +-- \"\' -- depends on delim, other can remove \ +-- \[\] -- remove \ +-- \<char> -- general escape, remove \ +-- \<eol> -- normalize the EOL only +-- \ddd -- if \a\b\f\n\r\t\v, change to latter +-- if other < ascii 32, keep ddd but zap leading zeros +-- but cannot have following digits +-- if >= ascii 32, translate it into the literal, then also +-- do escapes for \\,\",\' cases +-- <other> -- no change +-- * switch delimiters if string becomes shorter +------------------------------------------------------------------------ + +local function do_string(I) + local info = sinfos[I] + local delim = sub(info, 1, 1) -- delimiter used + local ndelim = (delim == "'") and '"' or "'" -- opposite " <-> ' + local z = sub(info, 2, -2) -- actual string + local i = 1 + local c_delim, c_ndelim = 0, 0 -- "/' counts + -------------------------------------------------------------------- + while i <= #z do + local c = sub(z, i, i) + ---------------------------------------------------------------- + if c == "\\" then -- escaped stuff + local j = i + 1 + local d = sub(z, j, j) + local p = find("abfnrtv\\\n\r\"\'0123456789", d, 1, true) + ------------------------------------------------------------ + if not p then -- \<char> -- remove \ + z = sub(z, 1, i - 1)..sub(z, j) + i = i + 1 + ------------------------------------------------------------ + elseif p <= 8 then -- \a\b\f\n\r\t\v\\ + i = i + 2 -- no change + ------------------------------------------------------------ + elseif p <= 10 then -- \<eol> -- normalize EOL + local eol = sub(z, j, j + 1) + if eol == "\r\n" or eol == "\n\r" then + z = sub(z, 1, i).."\n"..sub(z, j + 2) + elseif p == 10 then -- \r case + z = sub(z, 1, i).."\n"..sub(z, j + 1) + end + i = i + 2 + ------------------------------------------------------------ + elseif p <= 12 then -- \"\' -- remove \ for ndelim + if d == delim then + c_delim = c_delim + 1 + i = i + 2 + else + c_ndelim = c_ndelim + 1 + z = sub(z, 1, i - 1)..sub(z, j) + i = i + 1 + end + ------------------------------------------------------------ + else -- \ddd -- various steps + local s = match(z, "^(%d%d?%d?)", j) + j = i + 1 + #s -- skip to location + local cv = s + 0 + local cc = string.char(cv) + local p = find("\a\b\f\n\r\t\v", cc, 1, true) + if p then -- special escapes + s = "\\"..sub("abfnrtv", p, p) + elseif cv < 32 then -- normalized \ddd + if match(sub(z, j, j), "%d") then + -- if a digit follows, \ddd cannot be shortened + s = "\\"..s + else + s = "\\"..cv + end + elseif cc == delim then -- \<delim> + s = "\\"..cc + c_delim = c_delim + 1 + elseif cc == "\\" then -- \\ + s = "\\\\" + else -- literal character + s = cc + if cc == ndelim then + c_ndelim = c_ndelim + 1 + end + end + z = sub(z, 1, i - 1)..s..sub(z, j) + i = i + #s + ------------------------------------------------------------ + end--if p + ---------------------------------------------------------------- + else-- c ~= "\\" -- <other> -- no change + i = i + 1 + if c == ndelim then -- count ndelim, for switching delimiters + c_ndelim = c_ndelim + 1 + end + ---------------------------------------------------------------- + end--if c + end--while + -------------------------------------------------------------------- + -- switching delimiters, a long-winded derivation: + -- (1) delim takes 2+2*c_delim bytes, ndelim takes c_ndelim bytes + -- (2) delim becomes c_delim bytes, ndelim becomes 2+2*c_ndelim bytes + -- simplifying the condition (1)>(2) --> c_delim > c_ndelim + if c_delim > c_ndelim then + i = 1 + while i <= #z do + local p, q, r = find(z, "([\'\"])", i) + if not p then break end + if r == delim then -- \<delim> -> <delim> + z = sub(z, 1, p - 2)..sub(z, p) + i = p + else-- r == ndelim -- <ndelim> -> \<ndelim> + z = sub(z, 1, p - 1).."\\"..sub(z, p) + i = p + 2 + end + end--while + delim = ndelim -- actually change delimiters + end + -------------------------------------------------------------------- + z = delim..z..delim + if z ~= sinfos[I] then + if opt_details then + print("<string> (line "..stoklns[I]..") "..sinfos[I].." -> "..z) + opt_details = opt_details + 1 + end + sinfos[I] = z + end +end + +------------------------------------------------------------------------ +-- long string optimization +-- * note: warning flagged if trailing whitespace found, not trimmed +-- * remove first optional newline +-- * normalize embedded newlines +-- * reduce '=' separators in delimiters if possible +------------------------------------------------------------------------ + +local function do_lstring(I) + local info = sinfos[I] + local delim1 = match(info, "^%[=*%[") -- cut out delimiters + local sep = #delim1 + local delim2 = sub(info, -sep, -1) + local z = sub(info, sep + 1, -(sep + 1)) -- lstring without delims + local y = "" + local i = 1 + -------------------------------------------------------------------- + while true do + local p, q, r, s = find(z, "([\r\n])([\r\n]?)", i) + -- deal with a single line + local ln + if not p then + ln = sub(z, i) + elseif p >= i then + ln = sub(z, i, p - 1) + end + if ln ~= "" then + -- flag a warning if there are trailing spaces, won't optimize! + if match(ln, "%s+$") then + warn.LSTRING = "trailing whitespace in long string near line "..stoklns[I] + end + y = y..ln + end + if not p then -- done if no more EOLs + break + end + -- deal with line endings, normalize them + i = p + 1 + if p then + if #s > 0 and r ~= s then -- skip CRLF or LFCR + i = i + 1 + end + -- skip first newline, which can be safely deleted + if not(i == 1 and i == p) then + y = y.."\n" + end + end + end--while + -------------------------------------------------------------------- + -- handle possible deletion of one or more '=' separators + if sep >= 3 then + local chk, okay = sep - 1 + -- loop to test ending delimiter with less of '=' down to zero + while chk >= 2 do + local delim = "%]"..rep("=", chk - 2).."%]" + if not match(y, delim) then okay = chk end + chk = chk - 1 + end + if okay then -- change delimiters + sep = rep("=", okay - 2) + delim1, delim2 = "["..sep.."[", "]"..sep.."]" + end + end + -------------------------------------------------------------------- + sinfos[I] = delim1..y..delim2 +end + +------------------------------------------------------------------------ +-- long comment optimization +-- * note: does not remove first optional newline +-- * trim trailing whitespace +-- * normalize embedded newlines +-- * reduce '=' separators in delimiters if possible +------------------------------------------------------------------------ + +local function do_lcomment(I) + local info = sinfos[I] + local delim1 = match(info, "^%-%-%[=*%[") -- cut out delimiters + local sep = #delim1 + local delim2 = sub(info, -(sep - 2), -1) + local z = sub(info, sep + 1, -(sep - 1)) -- comment without delims + local y = "" + local i = 1 + -------------------------------------------------------------------- + while true do + local p, q, r, s = find(z, "([\r\n])([\r\n]?)", i) + -- deal with a single line, extract and check trailing whitespace + local ln + if not p then + ln = sub(z, i) + elseif p >= i then + ln = sub(z, i, p - 1) + end + if ln ~= "" then + -- trim trailing whitespace if non-empty line + local ws = match(ln, "%s*$") + if #ws > 0 then ln = sub(ln, 1, -(ws + 1)) end + y = y..ln + end + if not p then -- done if no more EOLs + break + end + -- deal with line endings, normalize them + i = p + 1 + if p then + if #s > 0 and r ~= s then -- skip CRLF or LFCR + i = i + 1 + end + y = y.."\n" + end + end--while + -------------------------------------------------------------------- + -- handle possible deletion of one or more '=' separators + sep = sep - 2 + if sep >= 3 then + local chk, okay = sep - 1 + -- loop to test ending delimiter with less of '=' down to zero + while chk >= 2 do + local delim = "%]"..rep("=", chk - 2).."%]" + if not match(y, delim) then okay = chk end + chk = chk - 1 + end + if okay then -- change delimiters + sep = rep("=", okay - 2) + delim1, delim2 = "--["..sep.."[", "]"..sep.."]" + end + end + -------------------------------------------------------------------- + sinfos[I] = delim1..y..delim2 +end + +------------------------------------------------------------------------ +-- short comment optimization +-- * trim trailing whitespace +------------------------------------------------------------------------ + +local function do_comment(i) + local info = sinfos[i] + local ws = match(info, "%s*$") -- just look from end of string + if #ws > 0 then + info = sub(info, 1, -(ws + 1)) -- trim trailing whitespace + end + sinfos[i] = info +end + +------------------------------------------------------------------------ +-- returns true if string found in long comment +-- * this is a feature to keep copyright or license texts +------------------------------------------------------------------------ + +local function keep_lcomment(opt_keep, info) + if not opt_keep then return false end -- option not set + local delim1 = match(info, "^%-%-%[=*%[") -- cut out delimiters + local sep = #delim1 + local delim2 = sub(info, -sep, -1) + local z = sub(info, sep + 1, -(sep - 1)) -- comment without delims + if find(z, opt_keep, 1, true) then -- try to match + return true + end +end + +------------------------------------------------------------------------ +-- main entry point +-- * currently, lexer processing has 2 passes +-- * processing is done on a line-oriented basis, which is easier to +-- grok due to the next point... +-- * since there are various options that can be enabled or disabled, +-- processing is a little messy or convoluted +------------------------------------------------------------------------ + +function optimize(option, toklist, semlist, toklnlist) + -------------------------------------------------------------------- + -- set option flags + -------------------------------------------------------------------- + local opt_comments = option["opt-comments"] + local opt_whitespace = option["opt-whitespace"] + local opt_emptylines = option["opt-emptylines"] + local opt_eols = option["opt-eols"] + local opt_strings = option["opt-strings"] + local opt_numbers = option["opt-numbers"] + local opt_x = option["opt-experimental"] + local opt_keep = option.KEEP + opt_details = option.DETAILS and 0 -- upvalues for details display + print = print or base.print + if opt_eols then -- forced settings, otherwise won't work properly + opt_comments = true + opt_whitespace = true + opt_emptylines = true + elseif opt_x then + opt_whitespace = true + end + -------------------------------------------------------------------- + -- variable initialization + -------------------------------------------------------------------- + stoks, sinfos, stoklns -- set source lists + = toklist, semlist, toklnlist + local i = 1 -- token position + local tok, info -- current token + local prev -- position of last grammar token + -- on same line (for TK_SPACE stuff) + -------------------------------------------------------------------- + -- changes a token, info pair + -------------------------------------------------------------------- + local function settoken(tok, info, I) + I = I or i + stoks[I] = tok or "" + sinfos[I] = info or "" + end + -------------------------------------------------------------------- + -- experimental optimization for ';' operator + -------------------------------------------------------------------- + if opt_x then + while true do + tok, info = stoks[i], sinfos[i] + if tok == "TK_EOS" then -- end of stream/pass + break + elseif tok == "TK_OP" and info == ";" then + -- ';' operator found, since it is entirely optional, set it + -- as a space to let whitespace optimization do the rest + settoken("TK_SPACE", " ") + end + i = i + 1 + end + repack_tokens() + end + -------------------------------------------------------------------- + -- processing loop (PASS 1) + -------------------------------------------------------------------- + i = 1 + while true do + tok, info = stoks[i], sinfos[i] + ---------------------------------------------------------------- + local atstart = atlinestart(i) -- set line begin flag + if atstart then prev = nil end + ---------------------------------------------------------------- + if tok == "TK_EOS" then -- end of stream/pass + break + ---------------------------------------------------------------- + elseif tok == "TK_KEYWORD" or -- keywords, identifiers, + tok == "TK_NAME" or -- operators + tok == "TK_OP" then + -- TK_KEYWORD and TK_OP can't be optimized without a big + -- optimization framework; it would be more of an optimizing + -- compiler, not a source code compressor + -- TK_NAME that are locals needs parser to analyze/optimize + prev = i + ---------------------------------------------------------------- + elseif tok == "TK_NUMBER" then -- numbers + if opt_numbers then + do_number(i) -- optimize + end + prev = i + ---------------------------------------------------------------- + elseif tok == "TK_STRING" or -- strings, long strings + tok == "TK_LSTRING" then + if opt_strings then + if tok == "TK_STRING" then + do_string(i) -- optimize + else + do_lstring(i) -- optimize + end + end + prev = i + ---------------------------------------------------------------- + elseif tok == "TK_COMMENT" then -- short comments + if opt_comments then + if i == 1 and sub(info, 1, 1) == "#" then + -- keep shbang comment, trim whitespace + do_comment(i) + else + -- safe to delete, as a TK_EOL (or TK_EOS) always follows + settoken() -- remove entirely + end + elseif opt_whitespace then -- trim whitespace only + do_comment(i) + end + ---------------------------------------------------------------- + elseif tok == "TK_LCOMMENT" then -- long comments + if keep_lcomment(opt_keep, info) then + ------------------------------------------------------------ + -- if --keep, we keep a long comment if <msg> is found; + -- this is a feature to keep copyright or license texts + if opt_whitespace then -- trim whitespace only + do_lcomment(i) + end + prev = i + elseif opt_comments then + local eols = commenteols(info) + ------------------------------------------------------------ + -- prepare opt_emptylines case first, if a disposable token + -- follows, current one is safe to dump, else keep a space; + -- it is implied that the operation is safe for '-', because + -- current is a TK_LCOMMENT, and must be separate from a '-' + if is_faketoken[stoks[i + 1]] then + settoken() -- remove entirely + tok = "" + else + settoken("TK_SPACE", " ") + end + ------------------------------------------------------------ + -- if there are embedded EOLs to keep and opt_emptylines is + -- disabled, then switch the token into one or more EOLs + if not opt_emptylines and eols > 0 then + settoken("TK_EOL", rep("\n", eols)) + end + ------------------------------------------------------------ + -- if optimizing whitespaces, force reinterpretation of the + -- token to give a chance for the space to be optimized away + if opt_whitespace and tok ~= "" then + i = i - 1 -- to reinterpret + end + ------------------------------------------------------------ + else -- disabled case + if opt_whitespace then -- trim whitespace only + do_lcomment(i) + end + prev = i + end + ---------------------------------------------------------------- + elseif tok == "TK_EOL" then -- line endings + if atstart and opt_emptylines then + settoken() -- remove entirely + elseif info == "\r\n" or info == "\n\r" then + -- normalize the rest of the EOLs for CRLF/LFCR only + -- (note that TK_LCOMMENT can change into several EOLs) + settoken("TK_EOL", "\n") + end + ---------------------------------------------------------------- + elseif tok == "TK_SPACE" then -- whitespace + if opt_whitespace then + if atstart or atlineend(i) then + -- delete leading and trailing whitespace + settoken() -- remove entirely + else + ------------------------------------------------------------ + -- at this point, since leading whitespace have been removed, + -- there should be a either a real token or a TK_LCOMMENT + -- prior to hitting this whitespace; the TK_LCOMMENT case + -- only happens if opt_comments is disabled; so prev ~= nil + local ptok = stoks[prev] + if ptok == "TK_LCOMMENT" then + -- previous TK_LCOMMENT can abut with anything + settoken() -- remove entirely + else + -- prev must be a grammar token; consecutive TK_SPACE + -- tokens is impossible when optimizing whitespace + local ntok = stoks[i + 1] + if is_faketoken[ntok] then + -- handle special case where a '-' cannot abut with + -- either a short comment or a long comment + if (ntok == "TK_COMMENT" or ntok == "TK_LCOMMENT") and + ptok == "TK_OP" and sinfos[prev] == "-" then + -- keep token + else + settoken() -- remove entirely + end + else--is_realtoken + -- check a pair of grammar tokens, if can abut, then + -- delete space token entirely, otherwise keep one space + local s = checkpair(prev, i + 1) + if s == "" then + settoken() -- remove entirely + else + settoken("TK_SPACE", " ") + end + end + end + ------------------------------------------------------------ + end + end + ---------------------------------------------------------------- + else + error("unidentified token encountered") + end + ---------------------------------------------------------------- + i = i + 1 + end--while + repack_tokens() + -------------------------------------------------------------------- + -- processing loop (PASS 2) + -------------------------------------------------------------------- + if opt_eols then + i = 1 + -- aggressive EOL removal only works with most non-grammar tokens + -- optimized away because it is a rather simple scheme -- basically + -- it just checks 'real' token pairs around EOLs + if stoks[1] == "TK_COMMENT" then + -- first comment still existing must be shbang, skip whole line + i = 3 + end + while true do + tok, info = stoks[i], sinfos[i] + -------------------------------------------------------------- + if tok == "TK_EOS" then -- end of stream/pass + break + -------------------------------------------------------------- + elseif tok == "TK_EOL" then -- consider each TK_EOL + local t1, t2 = stoks[i - 1], stoks[i + 1] + if is_realtoken[t1] and is_realtoken[t2] then -- sanity check + local s = checkpair(i - 1, i + 1) + if s == "" or t2 == "TK_EOS" then + settoken() -- remove entirely + end + end + end--if tok + -------------------------------------------------------------- + i = i + 1 + end--while + repack_tokens() + end + -------------------------------------------------------------------- + if opt_details and opt_details > 0 then print() end -- spacing + return stoks, sinfos, stoklns +end +--end of inserted module +end + +-- preload function for module optparser +preload.optparser = +function() +--start of inserted module +module "optparser" + +local string = base.require "string" +local table = base.require "table" + +---------------------------------------------------------------------- +-- Letter frequencies for reducing symbol entropy (fixed version) +-- * Might help a wee bit when the output file is compressed +-- * See Wikipedia: http://en.wikipedia.org/wiki/Letter_frequencies +-- * We use letter frequencies according to a Linotype keyboard, plus +-- the underscore, and both lower case and upper case letters. +-- * The arrangement below (LC, underscore, %d, UC) is arbitrary. +-- * This is certainly not optimal, but is quick-and-dirty and the +-- process has no significant overhead +---------------------------------------------------------------------- + +local LETTERS = "etaoinshrdlucmfwypvbgkqjxz_ETAOINSHRDLUCMFWYPVBGKQJXZ" +local ALPHANUM = "etaoinshrdlucmfwypvbgkqjxz_0123456789ETAOINSHRDLUCMFWYPVBGKQJXZ" + +-- names or identifiers that must be skipped +-- * the first two lines are for keywords +local SKIP_NAME = {} +for v in string.gmatch([[ +and break do else elseif end false for function if in +local nil not or repeat return then true until while +self]], "%S+") do + SKIP_NAME[v] = true +end + +------------------------------------------------------------------------ +-- variables and data structures +------------------------------------------------------------------------ + +local toklist, seminfolist, -- token lists (lexer output) + tokpar, seminfopar, xrefpar, -- token lists (parser output) + globalinfo, localinfo, -- variable information tables + statinfo, -- statment type table + globaluniq, localuniq, -- unique name tables + var_new, -- index of new variable names + varlist -- list of output variables + +---------------------------------------------------------------------- +-- preprocess information table to get lists of unique names +---------------------------------------------------------------------- + +local function preprocess(infotable) + local uniqtable = {} + for i = 1, #infotable do -- enumerate info table + local obj = infotable[i] + local name = obj.name + -------------------------------------------------------------------- + if not uniqtable[name] then -- not found, start an entry + uniqtable[name] = { + decl = 0, token = 0, size = 0, + } + end + -------------------------------------------------------------------- + local uniq = uniqtable[name] -- count declarations, tokens, size + uniq.decl = uniq.decl + 1 + local xref = obj.xref + local xcount = #xref + uniq.token = uniq.token + xcount + uniq.size = uniq.size + xcount * #name + -------------------------------------------------------------------- + if obj.decl then -- if local table, create first,last pairs + obj.id = i + obj.xcount = xcount + if xcount > 1 then -- if ==1, means local never accessed + obj.first = xref[2] + obj.last = xref[xcount] + end + -------------------------------------------------------------------- + else -- if global table, add a back ref + uniq.id = i + end + -------------------------------------------------------------------- + end--for + return uniqtable +end + +---------------------------------------------------------------------- +-- calculate actual symbol frequencies, in order to reduce entropy +-- * this may help further reduce the size of compressed sources +-- * note that since parsing optimizations is put before lexing +-- optimizations, the frequency table is not exact! +-- * yes, this will miss --keep block comments too... +---------------------------------------------------------------------- + +local function recalc_for_entropy(option) + local byte = string.byte + local char = string.char + -- table of token classes to accept in calculating symbol frequency + local ACCEPT = { + TK_KEYWORD = true, TK_NAME = true, TK_NUMBER = true, + TK_STRING = true, TK_LSTRING = true, + } + if not option["opt-comments"] then + ACCEPT.TK_COMMENT = true + ACCEPT.TK_LCOMMENT = true + end + -------------------------------------------------------------------- + -- create a new table and remove any original locals by filtering + -------------------------------------------------------------------- + local filtered = {} + for i = 1, #toklist do + filtered[i] = seminfolist[i] + end + for i = 1, #localinfo do -- enumerate local info table + local obj = localinfo[i] + local xref = obj.xref + for j = 1, obj.xcount do + local p = xref[j] + filtered[p] = "" -- remove locals + end + end + -------------------------------------------------------------------- + local freq = {} -- reset symbol frequency table + for i = 0, 255 do freq[i] = 0 end + for i = 1, #toklist do -- gather symbol frequency + local tok, info = toklist[i], filtered[i] + if ACCEPT[tok] then + for j = 1, #info do + local c = byte(info, j) + freq[c] = freq[c] + 1 + end + end--if + end--for + -------------------------------------------------------------------- + -- function to re-sort symbols according to actual frequencies + -------------------------------------------------------------------- + local function resort(symbols) + local symlist = {} + for i = 1, #symbols do -- prepare table to sort + local c = byte(symbols, i) + symlist[i] = { c = c, freq = freq[c], } + end + table.sort(symlist, -- sort selected symbols + function(v1, v2) + return v1.freq > v2.freq + end + ) + local charlist = {} -- reconstitute the string + for i = 1, #symlist do + charlist[i] = char(symlist[i].c) + end + return table.concat(charlist) + end + -------------------------------------------------------------------- + LETTERS = resort(LETTERS) -- change letter arrangement + ALPHANUM = resort(ALPHANUM) +end + +---------------------------------------------------------------------- +-- returns a string containing a new local variable name to use, and +-- a flag indicating whether it collides with a global variable +-- * trapping keywords and other names like 'self' is done elsewhere +---------------------------------------------------------------------- + +local function new_var_name() + local var + local cletters, calphanum = #LETTERS, #ALPHANUM + local v = var_new + if v < cletters then -- single char + v = v + 1 + var = string.sub(LETTERS, v, v) + else -- longer names + local range, sz = cletters, 1 -- calculate # chars fit + repeat + v = v - range + range = range * calphanum + sz = sz + 1 + until range > v + local n = v % cletters -- left side cycles faster + v = (v - n) / cletters -- do first char first + n = n + 1 + var = string.sub(LETTERS, n, n) + while sz > 1 do + local m = v % calphanum + v = (v - m) / calphanum + m = m + 1 + var = var..string.sub(ALPHANUM, m, m) + sz = sz - 1 + end + end + var_new = var_new + 1 + return var, globaluniq[var] ~= nil +end + +---------------------------------------------------------------------- +-- calculate and print some statistics +-- * probably better in main source, put here for now +---------------------------------------------------------------------- + +local function stats_summary(globaluniq, localuniq, afteruniq, option) + local print = print or base.print + local fmt = string.format + local opt_details = option.DETAILS + if option.QUIET then return end + local uniq_g , uniq_li, uniq_lo, uniq_ti, uniq_to, -- stats needed + decl_g, decl_li, decl_lo, decl_ti, decl_to, + token_g, token_li, token_lo, token_ti, token_to, + size_g, size_li, size_lo, size_ti, size_to + = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + local function avg(c, l) -- safe average function + if c == 0 then return 0 end + return l / c + end + -------------------------------------------------------------------- + -- collect statistics (note: globals do not have declarations!) + -------------------------------------------------------------------- + for name, uniq in base.pairs(globaluniq) do + uniq_g = uniq_g + 1 + token_g = token_g + uniq.token + size_g = size_g + uniq.size + end + for name, uniq in base.pairs(localuniq) do + uniq_li = uniq_li + 1 + decl_li = decl_li + uniq.decl + token_li = token_li + uniq.token + size_li = size_li + uniq.size + end + for name, uniq in base.pairs(afteruniq) do + uniq_lo = uniq_lo + 1 + decl_lo = decl_lo + uniq.decl + token_lo = token_lo + uniq.token + size_lo = size_lo + uniq.size + end + uniq_ti = uniq_g + uniq_li + decl_ti = decl_g + decl_li + token_ti = token_g + token_li + size_ti = size_g + size_li + uniq_to = uniq_g + uniq_lo + decl_to = decl_g + decl_lo + token_to = token_g + token_lo + size_to = size_g + size_lo + -------------------------------------------------------------------- + -- detailed stats: global list + -------------------------------------------------------------------- + if opt_details then + local sorted = {} -- sort table of unique global names by size + for name, uniq in base.pairs(globaluniq) do + uniq.name = name + sorted[#sorted + 1] = uniq + end + table.sort(sorted, + function(v1, v2) + return v1.size > v2.size + end + ) + local tabf1, tabf2 = "%8s%8s%10s %s", "%8d%8d%10.2f %s" + local hl = string.rep("-", 44) + print("*** global variable list (sorted by size) ***\n"..hl) + print(fmt(tabf1, "Token", "Input", "Input", "Global")) + print(fmt(tabf1, "Count", "Bytes", "Average", "Name")) + print(hl) + for i = 1, #sorted do + local uniq = sorted[i] + print(fmt(tabf2, uniq.token, uniq.size, avg(uniq.token, uniq.size), uniq.name)) + end + print(hl) + print(fmt(tabf2, token_g, size_g, avg(token_g, size_g), "TOTAL")) + print(hl.."\n") + -------------------------------------------------------------------- + -- detailed stats: local list + -------------------------------------------------------------------- + local tabf1, tabf2 = "%8s%8s%8s%10s%8s%10s %s", "%8d%8d%8d%10.2f%8d%10.2f %s" + local hl = string.rep("-", 70) + print("*** local variable list (sorted by allocation order) ***\n"..hl) + print(fmt(tabf1, "Decl.", "Token", "Input", "Input", "Output", "Output", "Global")) + print(fmt(tabf1, "Count", "Count", "Bytes", "Average", "Bytes", "Average", "Name")) + print(hl) + for i = 1, #varlist do -- iterate according to order assigned + local name = varlist[i] + local uniq = afteruniq[name] + local old_t, old_s = 0, 0 + for j = 1, #localinfo do -- find corresponding old names and calculate + local obj = localinfo[j] + if obj.name == name then + old_t = old_t + obj.xcount + old_s = old_s + obj.xcount * #obj.oldname + end + end + print(fmt(tabf2, uniq.decl, uniq.token, old_s, avg(old_t, old_s), + uniq.size, avg(uniq.token, uniq.size), name)) + end + print(hl) + print(fmt(tabf2, decl_lo, token_lo, size_li, avg(token_li, size_li), + size_lo, avg(token_lo, size_lo), "TOTAL")) + print(hl.."\n") + end--if opt_details + -------------------------------------------------------------------- + -- display output + -------------------------------------------------------------------- + local tabf1, tabf2 = "%-16s%8s%8s%8s%8s%10s", "%-16s%8d%8d%8d%8d%10.2f" + local hl = string.rep("-", 58) + print("*** local variable optimization summary ***\n"..hl) + print(fmt(tabf1, "Variable", "Unique", "Decl.", "Token", "Size", "Average")) + print(fmt(tabf1, "Types", "Names", "Count", "Count", "Bytes", "Bytes")) + print(hl) + print(fmt(tabf2, "Global", uniq_g, decl_g, token_g, size_g, avg(token_g, size_g))) + print(hl) + print(fmt(tabf2, "Local (in)", uniq_li, decl_li, token_li, size_li, avg(token_li, size_li))) + print(fmt(tabf2, "TOTAL (in)", uniq_ti, decl_ti, token_ti, size_ti, avg(token_ti, size_ti))) + print(hl) + print(fmt(tabf2, "Local (out)", uniq_lo, decl_lo, token_lo, size_lo, avg(token_lo, size_lo))) + print(fmt(tabf2, "TOTAL (out)", uniq_to, decl_to, token_to, size_to, avg(token_to, size_to))) + print(hl.."\n") +end + +---------------------------------------------------------------------- +-- experimental optimization for f("string") statements +-- * safe to delete parentheses without adding whitespace, as both +-- kinds of strings can abut with anything else +---------------------------------------------------------------------- + +local function optimize_func1() + ------------------------------------------------------------------ + local function is_strcall(j) -- find f("string") pattern + local t1 = tokpar[j + 1] or "" + local t2 = tokpar[j + 2] or "" + local t3 = tokpar[j + 3] or "" + if t1 == "(" and t2 == "<string>" and t3 == ")" then + return true + end + end + ------------------------------------------------------------------ + local del_list = {} -- scan for function pattern, + local i = 1 -- tokens to be deleted are marked + while i <= #tokpar do + local id = statinfo[i] + if id == "call" and is_strcall(i) then -- found & mark () + del_list[i + 1] = true -- '(' + del_list[i + 3] = true -- ')' + i = i + 3 + end + i = i + 1 + end + ------------------------------------------------------------------ + -- delete a token and adjust all relevant tables + -- * currently invalidates globalinfo and localinfo (not updated), + -- so any other optimization is done after processing locals + -- (of course, we can also lex the source data again...) + -- * faster one-pass token deletion + ------------------------------------------------------------------ + local i, dst, idend = 1, 1, #tokpar + local del_list2 = {} + while dst <= idend do -- process parser tables + if del_list[i] then -- found a token to delete? + del_list2[xrefpar[i]] = true + i = i + 1 + end + if i > dst then + if i <= idend then -- shift table items lower + tokpar[dst] = tokpar[i] + seminfopar[dst] = seminfopar[i] + xrefpar[dst] = xrefpar[i] - (i - dst) + statinfo[dst] = statinfo[i] + else -- nil out excess entries + tokpar[dst] = nil + seminfopar[dst] = nil + xrefpar[dst] = nil + statinfo[dst] = nil + end + end + i = i + 1 + dst = dst + 1 + end + local i, dst, idend = 1, 1, #toklist + while dst <= idend do -- process lexer tables + if del_list2[i] then -- found a token to delete? + i = i + 1 + end + if i > dst then + if i <= idend then -- shift table items lower + toklist[dst] = toklist[i] + seminfolist[dst] = seminfolist[i] + else -- nil out excess entries + toklist[dst] = nil + seminfolist[dst] = nil + end + end + i = i + 1 + dst = dst + 1 + end +end + +---------------------------------------------------------------------- +-- local variable optimization +---------------------------------------------------------------------- + +local function optimize_locals(option) + var_new = 0 -- reset variable name allocator + varlist = {} + ------------------------------------------------------------------ + -- preprocess global/local tables, handle entropy reduction + ------------------------------------------------------------------ + globaluniq = preprocess(globalinfo) + localuniq = preprocess(localinfo) + if option["opt-entropy"] then -- for entropy improvement + recalc_for_entropy(option) + end + ------------------------------------------------------------------ + -- build initial declared object table, then sort according to + -- token count, this might help assign more tokens to more common + -- variable names such as 'e' thus possibly reducing entropy + -- * an object knows its localinfo index via its 'id' field + -- * special handling for "self" special local (parameter) here + ------------------------------------------------------------------ + local object = {} + for i = 1, #localinfo do + object[i] = localinfo[i] + end + table.sort(object, -- sort largest first + function(v1, v2) + return v1.xcount > v2.xcount + end + ) + ------------------------------------------------------------------ + -- the special "self" function parameters must be preserved + -- * the allocator below will never use "self", so it is safe to + -- keep those implicit declarations as-is + ------------------------------------------------------------------ + local temp, j, gotself = {}, 1, false + for i = 1, #object do + local obj = object[i] + if not obj.isself then + temp[j] = obj + j = j + 1 + else + gotself = true + end + end + object = temp + ------------------------------------------------------------------ + -- a simple first-come first-served heuristic name allocator, + -- note that this is in no way optimal... + -- * each object is a local variable declaration plus existence + -- * the aim is to assign short names to as many tokens as possible, + -- so the following tries to maximize name reuse + -- * note that we preserve sort order + ------------------------------------------------------------------ + local nobject = #object + while nobject > 0 do + local varname, gcollide + repeat + varname, gcollide = new_var_name() -- collect a variable name + until not SKIP_NAME[varname] -- skip all special names + varlist[#varlist + 1] = varname -- keep a list + local oleft = nobject + ------------------------------------------------------------------ + -- if variable name collides with an existing global, the name + -- cannot be used by a local when the name is accessed as a global + -- during which the local is alive (between 'act' to 'rem'), so + -- we drop objects that collides with the corresponding global + ------------------------------------------------------------------ + if gcollide then + -- find the xref table of the global + local gref = globalinfo[globaluniq[varname].id].xref + local ngref = #gref + -- enumerate for all current objects; all are valid at this point + for i = 1, nobject do + local obj = object[i] + local act, rem = obj.act, obj.rem -- 'live' range of local + -- if rem < 0, it is a -id to a local that had the same name + -- so follow rem to extend it; does this make sense? + while rem < 0 do + rem = localinfo[-rem].rem + end + local drop + for j = 1, ngref do + local p = gref[j] + if p >= act and p <= rem then drop = true end -- in range? + end + if drop then + obj.skip = true + oleft = oleft - 1 + end + end--for + end--if gcollide + ------------------------------------------------------------------ + -- now the first unassigned local (since it's sorted) will be the + -- one with the most tokens to rename, so we set this one and then + -- eliminate all others that collides, then any locals that left + -- can then reuse the same variable name; this is repeated until + -- all local declaration that can use this name is assigned + -- * the criteria for local-local reuse/collision is: + -- A is the local with a name already assigned + -- B is the unassigned local under consideration + -- => anytime A is accessed, it cannot be when B is 'live' + -- => to speed up things, we have first/last accesses noted + ------------------------------------------------------------------ + while oleft > 0 do + local i = 1 + while object[i].skip do -- scan for first object + i = i + 1 + end + ------------------------------------------------------------------ + -- first object is free for assignment of the variable name + -- [first,last] gives the access range for collision checking + ------------------------------------------------------------------ + oleft = oleft - 1 + local obja = object[i] + i = i + 1 + obja.newname = varname + obja.skip = true + obja.done = true + local first, last = obja.first, obja.last + local xref = obja.xref + ------------------------------------------------------------------ + -- then, scan all the rest and drop those colliding + -- if A was never accessed then it'll never collide with anything + -- otherwise trivial skip if: + -- * B was activated after A's last access (last < act) + -- * B was removed before A's first access (first > rem) + -- if not, see detailed skip below... + ------------------------------------------------------------------ + if first and oleft > 0 then -- must have at least 1 access + local scanleft = oleft + while scanleft > 0 do + while object[i].skip do -- next valid object + i = i + 1 + end + scanleft = scanleft - 1 + local objb = object[i] + i = i + 1 + local act, rem = objb.act, objb.rem -- live range of B + -- if rem < 0, extend range of rem thru' following local + while rem < 0 do + rem = localinfo[-rem].rem + end + -------------------------------------------------------- + if not(last < act or first > rem) then -- possible collision + -------------------------------------------------------- + -- B is activated later than A or at the same statement, + -- this means for no collision, A cannot be accessed when B + -- is alive, since B overrides A (or is a peer) + -------------------------------------------------------- + if act >= obja.act then + for j = 1, obja.xcount do -- ... then check every access + local p = xref[j] + if p >= act and p <= rem then -- A accessed when B live! + oleft = oleft - 1 + objb.skip = true + break + end + end--for + -------------------------------------------------------- + -- A is activated later than B, this means for no collision, + -- A's access is okay since it overrides B, but B's last + -- access need to be earlier than A's activation time + -------------------------------------------------------- + else + if objb.last and objb.last >= obja.act then + oleft = oleft - 1 + objb.skip = true + end + end + end + -------------------------------------------------------- + if oleft == 0 then break end + end + end--if first + ------------------------------------------------------------------ + end--while + ------------------------------------------------------------------ + -- after assigning all possible locals to one variable name, the + -- unassigned locals/objects have the skip field reset and the table + -- is compacted, to hopefully reduce iteration time + ------------------------------------------------------------------ + local temp, j = {}, 1 + for i = 1, nobject do + local obj = object[i] + if not obj.done then + obj.skip = false + temp[j] = obj + j = j + 1 + end + end + object = temp -- new compacted object table + nobject = #object -- objects left to process + ------------------------------------------------------------------ + end--while + ------------------------------------------------------------------ + -- after assigning all locals with new variable names, we can + -- patch in the new names, and reprocess to get 'after' stats + ------------------------------------------------------------------ + for i = 1, #localinfo do -- enumerate all locals + local obj = localinfo[i] + local xref = obj.xref + if obj.newname then -- if got new name, patch it in + for j = 1, obj.xcount do + local p = xref[j] -- xrefs indexes the token list + seminfolist[p] = obj.newname + end + obj.name, obj.oldname -- adjust names + = obj.newname, obj.name + else + obj.oldname = obj.name -- for cases like 'self' + end + end + ------------------------------------------------------------------ + -- deal with statistics output + ------------------------------------------------------------------ + if gotself then -- add 'self' to end of list + varlist[#varlist + 1] = "self" + end + local afteruniq = preprocess(localinfo) + stats_summary(globaluniq, localuniq, afteruniq, option) +end + + +---------------------------------------------------------------------- +-- main entry point +---------------------------------------------------------------------- + +function optimize(option, _toklist, _seminfolist, xinfo) + -- set tables + toklist, seminfolist -- from lexer + = _toklist, _seminfolist + tokpar, seminfopar, xrefpar -- from parser + = xinfo.toklist, xinfo.seminfolist, xinfo.xreflist + globalinfo, localinfo, statinfo -- from parser + = xinfo.globalinfo, xinfo.localinfo, xinfo.statinfo + ------------------------------------------------------------------ + -- optimize locals + ------------------------------------------------------------------ + if option["opt-locals"] then + optimize_locals(option) + end + ------------------------------------------------------------------ + -- other optimizations + ------------------------------------------------------------------ + if option["opt-experimental"] then -- experimental + optimize_func1() + -- WARNING globalinfo and localinfo now invalidated! + end +end +--end of inserted module +end + +-- preload function for module equiv +preload.equiv = +function() +--start of inserted module +module "equiv" + +local string = base.require "string" +local loadstring = base.loadstring +local sub = string.sub +local match = string.match +local dump = string.dump +local byte = string.byte + +--[[-------------------------------------------------------------------- +-- variable and data initialization +----------------------------------------------------------------------]] + +local is_realtoken = { -- significant (grammar) tokens + TK_KEYWORD = true, + TK_NAME = true, + TK_NUMBER = true, + TK_STRING = true, + TK_LSTRING = true, + TK_OP = true, + TK_EOS = true, +} + +local option, llex, warn + +--[[-------------------------------------------------------------------- +-- functions +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- initialization function +------------------------------------------------------------------------ + +function init(_option, _llex, _warn) + option = _option + llex = _llex + warn = _warn +end + +------------------------------------------------------------------------ +-- function to build lists containing a 'normal' lexer stream +------------------------------------------------------------------------ + +local function build_stream(s) + llex.init(s) + llex.llex() + local stok, sseminfo -- source list (with whitespace elements) + = llex.tok, llex.seminfo + local tok, seminfo -- processed list (real elements only) + = {}, {} + for i = 1, #stok do + local t = stok[i] + if is_realtoken[t] then + tok[#tok + 1] = t + seminfo[#seminfo + 1] = sseminfo[i] + end + end--for + return tok, seminfo +end + +------------------------------------------------------------------------ +-- test source (lexer stream) equivalence +------------------------------------------------------------------------ + +function source(z, dat) + -------------------------------------------------------------------- + -- function to return a dumped string for seminfo compares + -------------------------------------------------------------------- + local function dumpsem(s) + local sf = loadstring("return "..s, "z") + if sf then + return dump(sf) + end + end + -------------------------------------------------------------------- + -- mark and optionally report non-equivalence + -------------------------------------------------------------------- + local function bork(msg) + if option.DETAILS then base.print("SRCEQUIV: "..msg) end + warn.SRC_EQUIV = true + end + -------------------------------------------------------------------- + -- get lexer streams for both source strings, compare + -------------------------------------------------------------------- + local tok1, seminfo1 = build_stream(z) -- original + local tok2, seminfo2 = build_stream(dat) -- compressed + -------------------------------------------------------------------- + -- compare shbang lines ignoring EOL + -------------------------------------------------------------------- + local sh1 = match(z, "^(#[^\r\n]*)") + local sh2 = match(dat, "^(#[^\r\n]*)") + if sh1 or sh2 then + if not sh1 or not sh2 or sh1 ~= sh2 then + bork("shbang lines different") + end + end + -------------------------------------------------------------------- + -- compare by simple count + -------------------------------------------------------------------- + if #tok1 ~= #tok2 then + bork("count "..#tok1.." "..#tok2) + return + end + -------------------------------------------------------------------- + -- compare each element the best we can + -------------------------------------------------------------------- + for i = 1, #tok1 do + local t1, t2 = tok1[i], tok2[i] + local s1, s2 = seminfo1[i], seminfo2[i] + if t1 ~= t2 then -- by type + bork("type ["..i.."] "..t1.." "..t2) + break + end + if t1 == "TK_KEYWORD" or t1 == "TK_NAME" or t1 == "TK_OP" then + if t1 == "TK_NAME" and option["opt-locals"] then + -- can't compare identifiers of locals that are optimized + elseif s1 ~= s2 then -- by semantic info (simple) + bork("seminfo ["..i.."] "..t1.." "..s1.." "..s2) + break + end + elseif t1 == "TK_EOS" then + -- no seminfo to compare + else-- "TK_NUMBER" or "TK_STRING" or "TK_LSTRING" + -- compare 'binary' form, so dump a function + local s1b,s2b = dumpsem(s1), dumpsem(s2) + if not s1b or not s2b or s1b ~= s2b then + bork("seminfo ["..i.."] "..t1.." "..s1.." "..s2) + break + end + end + end--for + -------------------------------------------------------------------- + -- successful comparison if end is reached with no borks + -------------------------------------------------------------------- +end + +------------------------------------------------------------------------ +-- test binary chunk equivalence +------------------------------------------------------------------------ + +function binary(z, dat) + local TNIL = 0 + local TBOOLEAN = 1 + local TNUMBER = 3 + local TSTRING = 4 + -------------------------------------------------------------------- + -- mark and optionally report non-equivalence + -------------------------------------------------------------------- + local function bork(msg) + if option.DETAILS then base.print("BINEQUIV: "..msg) end + warn.BIN_EQUIV = true + end + -------------------------------------------------------------------- + -- function to remove shbang line so that loadstring runs + -------------------------------------------------------------------- + local function zap_shbang(s) + local shbang = match(s, "^(#[^\r\n]*\r?\n?)") + if shbang then -- cut out shbang + s = sub(s, #shbang + 1) + end + return s + end + -------------------------------------------------------------------- + -- attempt to compile, then dump to get binary chunk string + -------------------------------------------------------------------- + local cz = loadstring(zap_shbang(z), "z") + if not cz then + bork("failed to compile original sources for binary chunk comparison") + return + end + local cdat = loadstring(zap_shbang(dat), "z") + if not cdat then + bork("failed to compile compressed result for binary chunk comparison") + end + -- if loadstring() works, dump assuming string.dump() is error-free + local c1 = { i = 1, dat = dump(cz) } + c1.len = #c1.dat + local c2 = { i = 1, dat = dump(cdat) } + c2.len = #c2.dat + -------------------------------------------------------------------- + -- support functions to handle binary chunk reading + -------------------------------------------------------------------- + local endian, + sz_int, sz_sizet, -- sizes of data types + sz_inst, sz_number, + getint, getsizet + -------------------------------------------------------------------- + local function ensure(c, sz) -- check if bytes exist + if c.i + sz - 1 > c.len then return end + return true + end + -------------------------------------------------------------------- + local function skip(c, sz) -- skip some bytes + if not sz then sz = 1 end + c.i = c.i + sz + end + -------------------------------------------------------------------- + local function getbyte(c) -- return a byte value + local i = c.i + if i > c.len then return end + local d = sub(c.dat, i, i) + c.i = i + 1 + return byte(d) + end + -------------------------------------------------------------------- + local function getint_l(c) -- return an int value (little-endian) + local n, scale = 0, 1 + if not ensure(c, sz_int) then return end + for j = 1, sz_int do + n = n + scale * getbyte(c) + scale = scale * 256 + end + return n + end + -------------------------------------------------------------------- + local function getint_b(c) -- return an int value (big-endian) + local n = 0 + if not ensure(c, sz_int) then return end + for j = 1, sz_int do + n = n * 256 + getbyte(c) + end + return n + end + -------------------------------------------------------------------- + local function getsizet_l(c) -- return a size_t value (little-endian) + local n, scale = 0, 1 + if not ensure(c, sz_sizet) then return end + for j = 1, sz_sizet do + n = n + scale * getbyte(c) + scale = scale * 256 + end + return n + end + -------------------------------------------------------------------- + local function getsizet_b(c) -- return a size_t value (big-endian) + local n = 0 + if not ensure(c, sz_sizet) then return end + for j = 1, sz_sizet do + n = n * 256 + getbyte(c) + end + return n + end + -------------------------------------------------------------------- + local function getblock(c, sz) -- return a block (as a string) + local i = c.i + local j = i + sz - 1 + if j > c.len then return end + local d = sub(c.dat, i, j) + c.i = i + sz + return d + end + -------------------------------------------------------------------- + local function getstring(c) -- return a string + local n = getsizet(c) + if not n then return end + if n == 0 then return "" end + return getblock(c, n) + end + -------------------------------------------------------------------- + local function goodbyte(c1, c2) -- compare byte value + local b1, b2 = getbyte(c1), getbyte(c2) + if not b1 or not b2 or b1 ~= b2 then + return + end + return b1 + end + -------------------------------------------------------------------- + local function badbyte(c1, c2) -- compare byte value + local b = goodbyte(c1, c2) + if not b then return true end + end + -------------------------------------------------------------------- + local function goodint(c1, c2) -- compare int value + local i1, i2 = getint(c1), getint(c2) + if not i1 or not i2 or i1 ~= i2 then + return + end + return i1 + end + -------------------------------------------------------------------- + -- recursively-called function to compare function prototypes + -------------------------------------------------------------------- + local function getfunc(c1, c2) + -- source name (ignored) + if not getstring(c1) or not getstring(c2) then + bork("bad source name"); return + end + -- linedefined (ignored) + if not getint(c1) or not getint(c2) then + bork("bad linedefined"); return + end + -- lastlinedefined (ignored) + if not getint(c1) or not getint(c2) then + bork("bad lastlinedefined"); return + end + if not (ensure(c1, 4) and ensure(c2, 4)) then + bork("prototype header broken") + end + -- nups (compared) + if badbyte(c1, c2) then + bork("bad nups"); return + end + -- numparams (compared) + if badbyte(c1, c2) then + bork("bad numparams"); return + end + -- is_vararg (compared) + if badbyte(c1, c2) then + bork("bad is_vararg"); return + end + -- maxstacksize (compared) + if badbyte(c1, c2) then + bork("bad maxstacksize"); return + end + -- code (compared) + local ncode = goodint(c1, c2) + if not ncode then + bork("bad ncode"); return + end + local code1 = getblock(c1, ncode * sz_inst) + local code2 = getblock(c2, ncode * sz_inst) + if not code1 or not code2 or code1 ~= code2 then + bork("bad code block"); return + end + -- constants (compared) + local nconst = goodint(c1, c2) + if not nconst then + bork("bad nconst"); return + end + for i = 1, nconst do + local ctype = goodbyte(c1, c2) + if not ctype then + bork("bad const type"); return + end + if ctype == TBOOLEAN then + if badbyte(c1, c2) then + bork("bad boolean value"); return + end + elseif ctype == TNUMBER then + local num1 = getblock(c1, sz_number) + local num2 = getblock(c2, sz_number) + if not num1 or not num2 or num1 ~= num2 then + bork("bad number value"); return + end + elseif ctype == TSTRING then + local str1 = getstring(c1) + local str2 = getstring(c2) + if not str1 or not str2 or str1 ~= str2 then + bork("bad string value"); return + end + end + end + -- prototypes (compared recursively) + local nproto = goodint(c1, c2) + if not nproto then + bork("bad nproto"); return + end + for i = 1, nproto do + if not getfunc(c1, c2) then + bork("bad function prototype"); return + end + end + -- debug information (ignored) + -- lineinfo (ignored) + local sizelineinfo1 = getint(c1) + if not sizelineinfo1 then + bork("bad sizelineinfo1"); return + end + local sizelineinfo2 = getint(c2) + if not sizelineinfo2 then + bork("bad sizelineinfo2"); return + end + if not getblock(c1, sizelineinfo1 * sz_int) then + bork("bad lineinfo1"); return + end + if not getblock(c2, sizelineinfo2 * sz_int) then + bork("bad lineinfo2"); return + end + -- locvars (ignored) + local sizelocvars1 = getint(c1) + if not sizelocvars1 then + bork("bad sizelocvars1"); return + end + local sizelocvars2 = getint(c2) + if not sizelocvars2 then + bork("bad sizelocvars2"); return + end + for i = 1, sizelocvars1 do + if not getstring(c1) or not getint(c1) or not getint(c1) then + bork("bad locvars1"); return + end + end + for i = 1, sizelocvars2 do + if not getstring(c2) or not getint(c2) or not getint(c2) then + bork("bad locvars2"); return + end + end + -- upvalues (ignored) + local sizeupvalues1 = getint(c1) + if not sizeupvalues1 then + bork("bad sizeupvalues1"); return + end + local sizeupvalues2 = getint(c2) + if not sizeupvalues2 then + bork("bad sizeupvalues2"); return + end + for i = 1, sizeupvalues1 do + if not getstring(c1) then bork("bad upvalues1"); return end + end + for i = 1, sizeupvalues2 do + if not getstring(c2) then bork("bad upvalues2"); return end + end + return true + end + -------------------------------------------------------------------- + -- parse binary chunks to verify equivalence + -- * for headers, handle sizes to allow a degree of flexibility + -- * assume a valid binary chunk is generated, since it was not + -- generated via external means + -------------------------------------------------------------------- + if not (ensure(c1, 12) and ensure(c2, 12)) then + bork("header broken") + end + skip(c1, 6) -- skip signature(4), version, format + endian = getbyte(c1) -- 1 = little endian + sz_int = getbyte(c1) -- get data type sizes + sz_sizet = getbyte(c1) + sz_inst = getbyte(c1) + sz_number = getbyte(c1) + skip(c1) -- skip integral flag + skip(c2, 12) -- skip other header (assume similar) + if endian == 1 then -- set for endian sensitive data we need + getint = getint_l + getsizet = getsizet_l + else + getint = getint_b + getsizet = getsizet_b + end + getfunc(c1, c2) -- get prototype at root + if c1.i ~= c1.len + 1 then + bork("inconsistent binary chunk1"); return + elseif c2.i ~= c2.len + 1 then + bork("inconsistent binary chunk2"); return + end + -------------------------------------------------------------------- + -- successful comparison if end is reached with no borks + -------------------------------------------------------------------- +end +--end of inserted module +end + +-- preload function for module plugin/html +preload["plugin/html"] = +function() +--start of inserted module +module "plugin/html" + +local string = base.require "string" +local table = base.require "table" +local io = base.require "io" + +------------------------------------------------------------------------ +-- constants and configuration +------------------------------------------------------------------------ + +local HTML_EXT = ".html" +local ENTITIES = { + ["&"] = "&", ["<"] = "<", [">"] = ">", + ["'"] = "'", ["\""] = """, +} + +-- simple headers and footers +local HEADER = [[ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<title>%s</title> +<meta name="Generator" content="LuaSrcDiet"> +<style type="text/css"> +%s</style> +</head> +<body> +<pre class="code"> +]] +local FOOTER = [[ +</pre> +</body> +</html> +]] +-- for more, please see wikimain.css from the Lua wiki site +local STYLESHEET = [[ +BODY { + background: white; + color: navy; +} +pre.code { color: black; } +span.comment { color: #00a000; } +span.string { color: #009090; } +span.keyword { color: black; font-weight: bold; } +span.number { color: #993399; } +span.operator { } +span.name { } +span.global { color: #ff0000; font-weight: bold; } +span.local { color: #0000ff; font-weight: bold; } +]] + +------------------------------------------------------------------------ +-- option handling, plays nice with --quiet option +------------------------------------------------------------------------ + +local option -- local reference to list of options +local srcfl, destfl -- filenames +local toklist, seminfolist, toklnlist -- token data + +local function print(...) -- handle quiet option + if option.QUIET then return end + base.print(...) +end + +------------------------------------------------------------------------ +-- initialization +------------------------------------------------------------------------ + +function init(_option, _srcfl, _destfl) + option = _option + srcfl = _srcfl + local extb, exte = string.find(srcfl, "%.[^%.%\\%/]*$") + local basename, extension = srcfl, "" + if extb and extb > 1 then + basename = string.sub(srcfl, 1, extb - 1) + extension = string.sub(srcfl, extb, exte) + end + destfl = basename..HTML_EXT + if option.OUTPUT_FILE then + destfl = option.OUTPUT_FILE + end + if srcfl == destfl then + base.error("output filename identical to input filename") + end +end + +------------------------------------------------------------------------ +-- message display, post-load processing +------------------------------------------------------------------------ + +function post_load(z) + print([[ +HTML plugin module for LuaSrcDiet +]]) + print("Exporting: "..srcfl.." -> "..destfl.."\n") +end + +------------------------------------------------------------------------ +-- post-lexing processing, can work on lexer table output +------------------------------------------------------------------------ + +function post_lex(_toklist, _seminfolist, _toklnlist) + toklist, seminfolist, toklnlist + = _toklist, _seminfolist, _toklnlist +end + +------------------------------------------------------------------------ +-- escape the usual suspects for HTML/XML +------------------------------------------------------------------------ + +local function do_entities(z) + local i = 1 + while i <= #z do + local c = string.sub(z, i, i) + local d = ENTITIES[c] + if d then + c = d + z = string.sub(z, 1, i - 1)..c..string.sub(z, i + 1) + end + i = i + #c + end--while + return z +end + +------------------------------------------------------------------------ +-- save source code to file +------------------------------------------------------------------------ + +local function save_file(fname, dat) + local OUTF = io.open(fname, "wb") + if not OUTF then base.error("cannot open \""..fname.."\" for writing") end + local status = OUTF:write(dat) + if not status then base.error("cannot write to \""..fname.."\"") end + OUTF:close() +end + +------------------------------------------------------------------------ +-- post-parsing processing, gives globalinfo, localinfo +------------------------------------------------------------------------ + +function post_parse(globalinfo, localinfo) + local html = {} + local function add(s) -- html helpers + html[#html + 1] = s + end + local function span(class, s) + add('<span class="'..class..'">'..s..'</span>') + end + ---------------------------------------------------------------------- + for i = 1, #globalinfo do -- mark global identifiers as TK_GLOBAL + local obj = globalinfo[i] + local xref = obj.xref + for j = 1, #xref do + local p = xref[j] + toklist[p] = "TK_GLOBAL" + end + end--for + ---------------------------------------------------------------------- + for i = 1, #localinfo do -- mark local identifiers as TK_LOCAL + local obj = localinfo[i] + local xref = obj.xref + for j = 1, #xref do + local p = xref[j] + toklist[p] = "TK_LOCAL" + end + end--for + ---------------------------------------------------------------------- + add(string.format(HEADER, -- header and leading stuff + do_entities(srcfl), + STYLESHEET)) + for i = 1, #toklist do -- enumerate token list + local tok, info = toklist[i], seminfolist[i] + if tok == "TK_KEYWORD" then + span("keyword", info) + elseif tok == "TK_STRING" or tok == "TK_LSTRING" then + span("string", do_entities(info)) + elseif tok == "TK_COMMENT" or tok == "TK_LCOMMENT" then + span("comment", do_entities(info)) + elseif tok == "TK_GLOBAL" then + span("global", info) + elseif tok == "TK_LOCAL" then + span("local", info) + elseif tok == "TK_NAME" then + span("name", info) + elseif tok == "TK_NUMBER" then + span("number", info) + elseif tok == "TK_OP" then + span("operator", do_entities(info)) + elseif tok ~= "TK_EOS" then -- TK_EOL, TK_SPACE + add(info) + end + end--for + add(FOOTER) + save_file(destfl, table.concat(html)) + option.EXIT = true +end +--end of inserted module +end + +-- preload function for module plugin/sloc +preload["plugin/sloc"] = +function() +--start of inserted module +module "plugin/sloc" + +local string = base.require "string" +local table = base.require "table" + +------------------------------------------------------------------------ +-- initialization +------------------------------------------------------------------------ + +local option -- local reference to list of options +local srcfl -- source file name + +function init(_option, _srcfl, _destfl) + option = _option + option.QUIET = true + srcfl = _srcfl +end + +------------------------------------------------------------------------ +-- splits a block into a table of lines (minus EOLs) +------------------------------------------------------------------------ + +local function split(blk) + local lines = {} + local i, nblk = 1, #blk + while i <= nblk do + local p, q, r, s = string.find(blk, "([\r\n])([\r\n]?)", i) + if not p then + p = nblk + 1 + end + lines[#lines + 1] = string.sub(blk, i, p - 1) + i = p + 1 + if p < nblk and q > p and r ~= s then -- handle Lua-style CRLF, LFCR + i = i + 1 + end + end + return lines +end + +------------------------------------------------------------------------ +-- post-lexing processing, can work on lexer table output +------------------------------------------------------------------------ + +function post_lex(toklist, seminfolist, toklnlist) + local lnow, sloc = 0, 0 + local function chk(ln) -- if a new line, count it as an SLOC + if ln > lnow then -- new line # must be > old line # + sloc = sloc + 1; lnow = ln + end + end + for i = 1, #toklist do -- enumerate over all tokens + local tok, info, ln + = toklist[i], seminfolist[i], toklnlist[i] + -------------------------------------------------------------------- + if tok == "TK_KEYWORD" or tok == "TK_NAME" or -- significant + tok == "TK_NUMBER" or tok == "TK_OP" then + chk(ln) + -------------------------------------------------------------------- + -- Both TK_STRING and TK_LSTRING may be multi-line, hence, a loop + -- is needed in order to mark off lines one-by-one. Since llex.lua + -- currently returns the line number of the last part of the string, + -- we must subtract in order to get the starting line number. + -------------------------------------------------------------------- + elseif tok == "TK_STRING" then -- possible multi-line + local t = split(info) + ln = ln - #t + 1 + for j = 1, #t do + chk(ln); ln = ln + 1 + end + -------------------------------------------------------------------- + elseif tok == "TK_LSTRING" then -- possible multi-line + local t = split(info) + ln = ln - #t + 1 + for j = 1, #t do + if t[j] ~= "" then chk(ln) end + ln = ln + 1 + end + -------------------------------------------------------------------- + -- other tokens are comments or whitespace and are ignored + -------------------------------------------------------------------- + end + end--for + base.print(srcfl..": "..sloc) -- display result + option.EXIT = true +end +--end of inserted module +end + +-- support modules +local llex = require "llex" +local lparser = require "lparser" +local optlex = require "optlex" +local optparser = require "optparser" +local equiv = require "equiv" +local plugin + +--[[-------------------------------------------------------------------- +-- messages and textual data +----------------------------------------------------------------------]] + +local MSG_TITLE = [[ +LuaSrcDiet: Puts your Lua 5.1 source code on a diet +Version 0.12.1 (20120407) Copyright (c) 2012 Kein-Hong Man +The COPYRIGHT file describes the conditions under which this +software may be distributed. +]] + +local MSG_USAGE = [[ +usage: LuaSrcDiet [options] [filenames] + +example: + >LuaSrcDiet myscript.lua -o myscript_.lua + +options: + -v, --version prints version information + -h, --help prints usage information + -o <file> specify file name to write output + -s <suffix> suffix for output files (default '_') + --keep <msg> keep block comment with <msg> inside + --plugin <module> run <module> in plugin/ directory + - stop handling arguments + + (optimization levels) + --none all optimizations off (normalizes EOLs only) + --basic lexer-based optimizations only + --maximum maximize reduction of source + + (informational) + --quiet process files quietly + --read-only read file and print token stats only + --dump-lexer dump raw tokens from lexer to stdout + --dump-parser dump variable tracking tables from parser + --details extra info (strings, numbers, locals) + +features (to disable, insert 'no' prefix like --noopt-comments): +%s +default settings: +%s]] + +------------------------------------------------------------------------ +-- optimization options, for ease of switching on and off +-- * positive to enable optimization, negative (no) to disable +-- * these options should follow --opt-* and --noopt-* style for now +------------------------------------------------------------------------ + +local OPTION = [[ +--opt-comments,'remove comments and block comments' +--opt-whitespace,'remove whitespace excluding EOLs' +--opt-emptylines,'remove empty lines' +--opt-eols,'all above, plus remove unnecessary EOLs' +--opt-strings,'optimize strings and long strings' +--opt-numbers,'optimize numbers' +--opt-locals,'optimize local variable names' +--opt-entropy,'tries to reduce symbol entropy of locals' +--opt-srcequiv,'insist on source (lexer stream) equivalence' +--opt-binequiv,'insist on binary chunk equivalence' +--opt-experimental,'apply experimental optimizations' +]] + +-- preset configuration +local DEFAULT_CONFIG = [[ + --opt-comments --opt-whitespace --opt-emptylines + --opt-numbers --opt-locals + --opt-srcequiv --opt-binequiv +]] +-- override configurations +-- * MUST explicitly enable/disable everything for +-- total option replacement +local BASIC_CONFIG = [[ + --opt-comments --opt-whitespace --opt-emptylines + --noopt-eols --noopt-strings --noopt-numbers + --noopt-locals --noopt-entropy + --opt-srcequiv --opt-binequiv +]] +local MAXIMUM_CONFIG = [[ + --opt-comments --opt-whitespace --opt-emptylines + --opt-eols --opt-strings --opt-numbers + --opt-locals --opt-entropy + --opt-srcequiv --opt-binequiv +]] +local NONE_CONFIG = [[ + --noopt-comments --noopt-whitespace --noopt-emptylines + --noopt-eols --noopt-strings --noopt-numbers + --noopt-locals --noopt-entropy + --opt-srcequiv --opt-binequiv +]] + +local DEFAULT_SUFFIX = "_" -- default suffix for file renaming +local PLUGIN_SUFFIX = "plugin/" -- relative location of plugins + +--[[-------------------------------------------------------------------- +-- startup and initialize option list handling +----------------------------------------------------------------------]] + +-- simple error message handler; change to error if traceback wanted +local function die(msg) + print("LuaSrcDiet (error): "..msg); os.exit(1) +end +--die = error--DEBUG + +if not match(_VERSION, "5.1", 1, 1) then -- sanity check + die("requires Lua 5.1 to run") +end + +------------------------------------------------------------------------ +-- prepares text for list of optimizations, prepare lookup table +------------------------------------------------------------------------ + +local MSG_OPTIONS = "" +do + local WIDTH = 24 + local o = {} + for op, desc in gmatch(OPTION, "%s*([^,]+),'([^']+)'") do + local msg = " "..op + msg = msg..string.rep(" ", WIDTH - #msg)..desc.."\n" + MSG_OPTIONS = MSG_OPTIONS..msg + o[op] = true + o["--no"..sub(op, 3)] = true + end + OPTION = o -- replace OPTION with lookup table +end + +MSG_USAGE = string.format(MSG_USAGE, MSG_OPTIONS, DEFAULT_CONFIG) + +if p_embedded then -- embedded plugins + local EMBED_INFO = "\nembedded plugins:\n" + for i = 1, #p_embedded do + local p = p_embedded[i] + EMBED_INFO = EMBED_INFO.." "..plugin_info[p].."\n" + end + MSG_USAGE = MSG_USAGE..EMBED_INFO +end + +------------------------------------------------------------------------ +-- global variable initialization, option set handling +------------------------------------------------------------------------ + +local suffix = DEFAULT_SUFFIX -- file suffix +local option = {} -- program options +local stat_c, stat_l -- statistics tables + +-- function to set option lookup table based on a text list of options +-- note: additional forced settings for --opt-eols is done in optlex.lua +local function set_options(CONFIG) + for op in gmatch(CONFIG, "(%-%-%S+)") do + if sub(op, 3, 4) == "no" and -- handle negative options + OPTION["--"..sub(op, 5)] then + option[sub(op, 5)] = false + else + option[sub(op, 3)] = true + end + end +end + +--[[-------------------------------------------------------------------- +-- support functions +----------------------------------------------------------------------]] + +-- list of token types, parser-significant types are up to TTYPE_GRAMMAR +-- while the rest are not used by parsers; arranged for stats display +local TTYPES = { + "TK_KEYWORD", "TK_NAME", "TK_NUMBER", -- grammar + "TK_STRING", "TK_LSTRING", "TK_OP", + "TK_EOS", + "TK_COMMENT", "TK_LCOMMENT", -- non-grammar + "TK_EOL", "TK_SPACE", +} +local TTYPE_GRAMMAR = 7 + +local EOLTYPES = { -- EOL names for token dump + ["\n"] = "LF", ["\r"] = "CR", + ["\n\r"] = "LFCR", ["\r\n"] = "CRLF", +} + +------------------------------------------------------------------------ +-- read source code from file +------------------------------------------------------------------------ +local loaded_file_contents = "" +local saved_file_contents = "" + +local function load_file(fname) + local INF = io.open(fname, "rb") + if not INF then die('cannot open "'..fname..'" for reading') end + local dat = INF:read("*a") + if not dat then die('cannot read from "'..fname..'"') end + INF:close() + loaded_file_contents = dat + return dat +end + +------------------------------------------------------------------------ +-- save source code to file +------------------------------------------------------------------------ + +local function save_file(fname, dat) + saved_file_contents = dat +--[[ + local OUTF = io.open(fname, "wb") + if not OUTF then die('cannot open "'..fname..'" for writing') end + local status = OUTF:write(dat) + if not status then die('cannot write to "'..fname..'"') end + OUTF:close() + ]] +end + +------------------------------------------------------------------------ +-- functions to deal with statistics +------------------------------------------------------------------------ + +-- initialize statistics table +local function stat_init() + stat_c, stat_l = {}, {} + for i = 1, #TTYPES do + local ttype = TTYPES[i] + stat_c[ttype], stat_l[ttype] = 0, 0 + end +end + +-- add a token to statistics table +local function stat_add(tok, seminfo) + stat_c[tok] = stat_c[tok] + 1 + stat_l[tok] = stat_l[tok] + #seminfo +end + +-- do totals for statistics table, return average table +local function stat_calc() + local function avg(c, l) -- safe average function + if c == 0 then return 0 end + return l / c + end + local stat_a = {} + local c, l = 0, 0 + for i = 1, TTYPE_GRAMMAR do -- total grammar tokens + local ttype = TTYPES[i] + c = c + stat_c[ttype]; l = l + stat_l[ttype] + end + stat_c.TOTAL_TOK, stat_l.TOTAL_TOK = c, l + stat_a.TOTAL_TOK = avg(c, l) + c, l = 0, 0 + for i = 1, #TTYPES do -- total all tokens + local ttype = TTYPES[i] + c = c + stat_c[ttype]; l = l + stat_l[ttype] + stat_a[ttype] = avg(stat_c[ttype], stat_l[ttype]) + end + stat_c.TOTAL_ALL, stat_l.TOTAL_ALL = c, l + stat_a.TOTAL_ALL = avg(c, l) + return stat_a +end + +--[[-------------------------------------------------------------------- +-- main tasks +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- a simple token dumper, minimal translation of seminfo data +------------------------------------------------------------------------ + +local function dump_tokens(srcfl) + -------------------------------------------------------------------- + -- load file and process source input into tokens + -------------------------------------------------------------------- + local z = load_file(srcfl) + llex.init(z) + llex.llex() + local toklist, seminfolist = llex.tok, llex.seminfo + -------------------------------------------------------------------- + -- display output + -------------------------------------------------------------------- + for i = 1, #toklist do + local tok, seminfo = toklist[i], seminfolist[i] + if tok == "TK_OP" and string.byte(seminfo) < 32 then + seminfo = "(".. string.byte(seminfo)..")" + elseif tok == "TK_EOL" then + seminfo = EOLTYPES[seminfo] + else + seminfo = "'"..seminfo.."'" + end + print(tok.." "..seminfo) + end--for +end + +---------------------------------------------------------------------- +-- parser dump; dump globalinfo and localinfo tables +---------------------------------------------------------------------- + +local function dump_parser(srcfl) + local print = print + -------------------------------------------------------------------- + -- load file and process source input into tokens + -------------------------------------------------------------------- + local z = load_file(srcfl) + llex.init(z) + llex.llex() + local toklist, seminfolist, toklnlist + = llex.tok, llex.seminfo, llex.tokln + -------------------------------------------------------------------- + -- do parser optimization here + -------------------------------------------------------------------- + lparser.init(toklist, seminfolist, toklnlist) + local xinfo = lparser.parser() + local globalinfo, localinfo = + xinfo.globalinfo, xinfo.localinfo + -------------------------------------------------------------------- + -- display output + -------------------------------------------------------------------- + local hl = string.rep("-", 72) + print("*** Local/Global Variable Tracker Tables ***") + print(hl.."\n GLOBALS\n"..hl) + -- global tables have a list of xref numbers only + for i = 1, #globalinfo do + local obj = globalinfo[i] + local msg = "("..i..") '"..obj.name.."' -> " + local xref = obj.xref + for j = 1, #xref do msg = msg..xref[j].." " end + print(msg) + end + -- local tables have xref numbers and a few other special + -- numbers that are specially named: decl (declaration xref), + -- act (activation xref), rem (removal xref) + print(hl.."\n LOCALS (decl=declared act=activated rem=removed)\n"..hl) + for i = 1, #localinfo do + local obj = localinfo[i] + local msg = "("..i..") '"..obj.name.."' decl:"..obj.decl.. + " act:"..obj.act.." rem:"..obj.rem + if obj.isself then + msg = msg.." isself" + end + msg = msg.." -> " + local xref = obj.xref + for j = 1, #xref do msg = msg..xref[j].." " end + print(msg) + end + print(hl.."\n") +end + +------------------------------------------------------------------------ +-- reads source file(s) and reports some statistics +------------------------------------------------------------------------ + +local function read_only(srcfl) + local print = print + -------------------------------------------------------------------- + -- load file and process source input into tokens + -------------------------------------------------------------------- + local z = load_file(srcfl) + llex.init(z) + llex.llex() + local toklist, seminfolist = llex.tok, llex.seminfo + print(MSG_TITLE) + print("Statistics for: "..srcfl.."\n") + -------------------------------------------------------------------- + -- collect statistics + -------------------------------------------------------------------- + stat_init() + for i = 1, #toklist do + local tok, seminfo = toklist[i], seminfolist[i] + stat_add(tok, seminfo) + end--for + local stat_a = stat_calc() + -------------------------------------------------------------------- + -- display output + -------------------------------------------------------------------- + local fmt = string.format + local function figures(tt) + return stat_c[tt], stat_l[tt], stat_a[tt] + end + local tabf1, tabf2 = "%-16s%8s%8s%10s", "%-16s%8d%8d%10.2f" + local hl = string.rep("-", 42) + print(fmt(tabf1, "Lexical", "Input", "Input", "Input")) + print(fmt(tabf1, "Elements", "Count", "Bytes", "Average")) + print(hl) + for i = 1, #TTYPES do + local ttype = TTYPES[i] + print(fmt(tabf2, ttype, figures(ttype))) + if ttype == "TK_EOS" then print(hl) end + end + print(hl) + print(fmt(tabf2, "Total Elements", figures("TOTAL_ALL"))) + print(hl) + print(fmt(tabf2, "Total Tokens", figures("TOTAL_TOK"))) + print(hl.."\n") +end + +------------------------------------------------------------------------ +-- process source file(s), write output and reports some statistics +------------------------------------------------------------------------ + +local function process_file(srcfl, destfl) + local function print(...) -- handle quiet option + if option.QUIET then return end + _G.print(...) + end + if plugin and plugin.init then -- plugin init + option.EXIT = false + plugin.init(option, srcfl, destfl) + if option.EXIT then return end + end + print(MSG_TITLE) -- title message + -------------------------------------------------------------------- + -- load file and process source input into tokens + -------------------------------------------------------------------- + local z = load_file(srcfl) + if plugin and plugin.post_load then -- plugin post-load + z = plugin.post_load(z) or z + if option.EXIT then return end + end + llex.init(z) + llex.llex() + local toklist, seminfolist, toklnlist + = llex.tok, llex.seminfo, llex.tokln + if plugin and plugin.post_lex then -- plugin post-lex + plugin.post_lex(toklist, seminfolist, toklnlist) + if option.EXIT then return end + end + -------------------------------------------------------------------- + -- collect 'before' statistics + -------------------------------------------------------------------- + stat_init() + for i = 1, #toklist do + local tok, seminfo = toklist[i], seminfolist[i] + stat_add(tok, seminfo) + end--for + local stat1_a = stat_calc() + local stat1_c, stat1_l = stat_c, stat_l + -------------------------------------------------------------------- + -- do parser optimization here + -------------------------------------------------------------------- + optparser.print = print -- hack + lparser.init(toklist, seminfolist, toklnlist) + local xinfo = lparser.parser() + if plugin and plugin.post_parse then -- plugin post-parse + plugin.post_parse(xinfo.globalinfo, xinfo.localinfo) + if option.EXIT then return end + end + optparser.optimize(option, toklist, seminfolist, xinfo) + if plugin and plugin.post_optparse then -- plugin post-optparse + plugin.post_optparse() + if option.EXIT then return end + end + -------------------------------------------------------------------- + -- do lexer optimization here, save output file + -------------------------------------------------------------------- + local warn = optlex.warn -- use this as a general warning lookup + optlex.print = print -- hack + toklist, seminfolist, toklnlist + = optlex.optimize(option, toklist, seminfolist, toklnlist) + if plugin and plugin.post_optlex then -- plugin post-optlex + plugin.post_optlex(toklist, seminfolist, toklnlist) + if option.EXIT then return end + end + local dat = table.concat(seminfolist) + -- depending on options selected, embedded EOLs in long strings and + -- long comments may not have been translated to \n, tack a warning + if string.find(dat, "\r\n", 1, 1) or + string.find(dat, "\n\r", 1, 1) then + warn.MIXEDEOL = true + end + -------------------------------------------------------------------- + -- test source and binary chunk equivalence + -------------------------------------------------------------------- + equiv.init(option, llex, warn) + equiv.source(z, dat) + equiv.binary(z, dat) + local smsg = "before and after lexer streams are NOT equivalent!" + local bmsg = "before and after binary chunks are NOT equivalent!" + -- for reporting, die if option was selected, else just warn + if warn.SRC_EQUIV then + if option["opt-srcequiv"] then die(smsg) end + else + print("*** SRCEQUIV: token streams are sort of equivalent") + if option["opt-locals"] then + print("(but no identifier comparisons since --opt-locals enabled)") + end + print() + end + if warn.BIN_EQUIV then + if option["opt-binequiv"] then die(bmsg) end + else + print("*** BINEQUIV: binary chunks are sort of equivalent") + print() + end + -------------------------------------------------------------------- + -- save optimized source stream to output file + -------------------------------------------------------------------- + save_file(destfl, dat) + -------------------------------------------------------------------- + -- collect 'after' statistics + -------------------------------------------------------------------- + stat_init() + for i = 1, #toklist do + local tok, seminfo = toklist[i], seminfolist[i] + stat_add(tok, seminfo) + end--for + local stat_a = stat_calc() + -------------------------------------------------------------------- + -- display output + -------------------------------------------------------------------- + print("Statistics for: "..srcfl.." -> "..destfl.."\n") + local fmt = string.format + local function figures(tt) + return stat1_c[tt], stat1_l[tt], stat1_a[tt], + stat_c[tt], stat_l[tt], stat_a[tt] + end + local tabf1, tabf2 = "%-16s%8s%8s%10s%8s%8s%10s", + "%-16s%8d%8d%10.2f%8d%8d%10.2f" + local hl = string.rep("-", 68) + print("*** lexer-based optimizations summary ***\n"..hl) + print(fmt(tabf1, "Lexical", + "Input", "Input", "Input", + "Output", "Output", "Output")) + print(fmt(tabf1, "Elements", + "Count", "Bytes", "Average", + "Count", "Bytes", "Average")) + print(hl) + for i = 1, #TTYPES do + local ttype = TTYPES[i] + print(fmt(tabf2, ttype, figures(ttype))) + if ttype == "TK_EOS" then print(hl) end + end + print(hl) + print(fmt(tabf2, "Total Elements", figures("TOTAL_ALL"))) + print(hl) + print(fmt(tabf2, "Total Tokens", figures("TOTAL_TOK"))) + print(hl) + -------------------------------------------------------------------- + -- report warning flags from optimizing process + -------------------------------------------------------------------- + if warn.LSTRING then + print("* WARNING: "..warn.LSTRING) + elseif warn.MIXEDEOL then + print("* WARNING: ".."output still contains some CRLF or LFCR line endings") + elseif warn.SRC_EQUIV then + print("* WARNING: "..smsg) + elseif warn.BIN_EQUIV then + print("* WARNING: "..bmsg) + end + print() +end + +--[[-------------------------------------------------------------------- +-- main functions +----------------------------------------------------------------------]] + +--[[ +local arg = {...} -- program arguments +local fspec = {} +set_options(DEFAULT_CONFIG) -- set to default options at beginning + +------------------------------------------------------------------------ +-- per-file handling, ship off to tasks +------------------------------------------------------------------------ + +local function do_files(fspec) + for i = 1, #fspec do + local srcfl = fspec[i] + local destfl + ------------------------------------------------------------------ + -- find and replace extension for filenames + ------------------------------------------------------------------ + local extb, exte = string.find(srcfl, "%.[^%.%\\%/]*$") + local basename, extension = srcfl, "" + if extb and extb > 1 then + basename = sub(srcfl, 1, extb - 1) + extension = sub(srcfl, extb, exte) + end + destfl = basename..suffix..extension + if #fspec == 1 and option.OUTPUT_FILE then + destfl = option.OUTPUT_FILE + end + if srcfl == destfl then + die("output filename identical to input filename") + end + ------------------------------------------------------------------ + -- perform requested operations + ------------------------------------------------------------------ + if option.DUMP_LEXER then + dump_tokens(srcfl) + elseif option.DUMP_PARSER then + dump_parser(srcfl) + elseif option.READ_ONLY then + read_only(srcfl) + else + process_file(srcfl, destfl) + end + end--for +end + +------------------------------------------------------------------------ +-- main function (entry point is after this definition) +------------------------------------------------------------------------ + +local function main() + local argn, i = #arg, 1 + if argn == 0 then + option.HELP = true + end + -------------------------------------------------------------------- + -- handle arguments + -------------------------------------------------------------------- + while i <= argn do + local o, p = arg[i], arg[i + 1] + local dash = match(o, "^%-%-?") + if dash == "-" then -- single-dash options + if o == "-h" then + option.HELP = true; break + elseif o == "-v" then + option.VERSION = true; break + elseif o == "-s" then + if not p then die("-s option needs suffix specification") end + suffix = p + i = i + 1 + elseif o == "-o" then + if not p then die("-o option needs a file name") end + option.OUTPUT_FILE = p + i = i + 1 + elseif o == "-" then + break -- ignore rest of args + else + die("unrecognized option "..o) + end + elseif dash == "--" then -- double-dash options + if o == "--help" then + option.HELP = true; break + elseif o == "--version" then + option.VERSION = true; break + elseif o == "--keep" then + if not p then die("--keep option needs a string to match for") end + option.KEEP = p + i = i + 1 + elseif o == "--plugin" then + if not p then die("--plugin option needs a module name") end + if option.PLUGIN then die("only one plugin can be specified") end + option.PLUGIN = p + plugin = require(PLUGIN_SUFFIX..p) + i = i + 1 + elseif o == "--quiet" then + option.QUIET = true + elseif o == "--read-only" then + option.READ_ONLY = true + elseif o == "--basic" then + set_options(BASIC_CONFIG) + elseif o == "--maximum" then + set_options(MAXIMUM_CONFIG) + elseif o == "--none" then + set_options(NONE_CONFIG) + elseif o == "--dump-lexer" then + option.DUMP_LEXER = true + elseif o == "--dump-parser" then + option.DUMP_PARSER = true + elseif o == "--details" then + option.DETAILS = true + elseif OPTION[o] then -- lookup optimization options + set_options(o) + else + die("unrecognized option "..o) + end + else + fspec[#fspec + 1] = o -- potential filename + end + i = i + 1 + end--while + if option.HELP then + print(MSG_TITLE..MSG_USAGE); return true + elseif option.VERSION then + print(MSG_TITLE); return true + end + if #fspec > 0 then + if #fspec > 1 and option.OUTPUT_FILE then + die("with -o, only one source file can be specified") + end + do_files(fspec) + return true + else + die("nothing to do!") + end +end + +-- entry point -> main() -> do_files() +if not main() then + die("Please run with option -h or --help for usage information") +end +]] +-- end of script + +-- Start of premake4 customizations +function get_slim_luasrc(fname) + set_options(DEFAULT_CONFIG) + set_options(MAXIMUM_CONFIG) + option.OUTPUT_FILE = "-" + option.QUIET = true + process_file(fname, "-") + return saved_file_contents or "", loaded_file_contents +end diff --git a/scripts/luasrcdiet/README.LuaSrcDiet b/scripts/luasrcdiet/README.LuaSrcDiet new file mode 100644 index 0000000..950ceff --- /dev/null +++ b/scripts/luasrcdiet/README.LuaSrcDiet @@ -0,0 +1,140 @@ + + LuaSrcDiet + Compresses Lua source code by removing unnecessary characters. + + Copyright (c) 2005-2008,2011,2012 Kein-Hong Man <keinhong@gmail.com> + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + http://code.google.com/p/luasrcdiet/ + +======================================================================== + +WHAT'S NEW IN VERSION 0.12.1 +---------------------------- + +* Fixed a long comment glitch when using the --keep option. (Two + extra characters were duplicated before the ending brackets.) + +* Faster function call syntax sugar optimization using a one-pass + token deletion loop. + +WHAT'S NEW IN VERSION 0.12.0 +---------------------------- + +* Added single-file versions of LuaSrcDiet in various sizes. First + done by some other projects that packaged LuaSrcDiet, e.g. eLua. + +* BUG FIX: String optimization of "\ddd" type escape mechanism, + "\00101" was incorrectly optimized to "\101". + +* --opt-srcequiv: Source equivalence checking. Tries hard to compare + 'before' and 'after' lexer token streams for equivalence. + +* --opt-binequiv: Binary chunk equivalence checking. Tries hard to + compare 'before' and 'after' binary chunks for equivalence. + +* When using --opt-eols, the last EOL character is now removed. + +* --opt-experimental: Turns on a few experimental optimizations: + (a) ';' operator removal (deleted or turned into whitespace). + (b) f("string") f('string') f([[string]]) calls are turned + into their syntactic sugar equivalents, e.g. f"string" + +* Plugins are now embedded into single-file versions. + +* First release of completed documentation files. + +* New Makefile and numerous minor updates. + +* Old code for Lua 5.0 removed. + +BUGS +---- + +* Nothing in my list. See below for limitations... + +INCOMPLETE SUPPORT +------------------ + +* Locals optimization does NOT understand implicit 'arg' locals in + vararg functions (see option LUA_COMPAT_VARARG in the Lua sources). + +* NO support in lexer for decimal points other than '.'. + +* NO support in lexer for Lua 5.0.x nested long strings. + +EXPERIMENTAL SOFTWARE +--------------------- + +LuaSrcDiet is "experimental software". For LuaSrcDiet, this means that +it was coded for one user -- the coder. Although I may be able to help +LuaSrcDiet users, there should not be any expectation of 'support'. + +Don't hook this thing up to nuclear missiles. + +I don't have the time for steady maintenance or for building up and +cultivating a user base, so developers are welcome to fork LuaSrcDiet or +incorporate it into their own software, as long as authorship +attribution for LuaSrcDiet source code is maintained. Say if LuaSrcDiet +is called as a separate program, then it is simply an aggregation of +separate software and each program should stick to its own license. + +Programs you process using LuaSrcDiet are of course not affected at all +by LuaSrcDiet's license; it's just a text filter. See COPYRIGHT. If you +insist on extreme COPYRIGHT views, then better delete this whole thing +right away, then gouge your eyes out. :-p + +OLDER STUFF +----------- + +There has been some slash-and-burn going on. I'm inclined to move +forward, and not spend time maintaining older stuff forever. If you +still need the older stuff, they can be found in: + +* Lua 5.0.x old versions: last seen in version 0.11.2. + +* Lua 5.1.x old codebase: last seen in version 0.11.2. + +FUTURE PLANS +------------ + +Lua 5.1.x releases for LuaSrcDiet will pretty much stagnate at 0.12.1 +after implementation of a couple more experimental optimizations, and +effort will be shifted towards something for Lua 5.2.x. The timeline for +this is indeterminate. + +======================================================================== + +USING LUASRCDIET + +Now is a good time to take a look at the documentation. Start with +LuaSrcDiet.html in the doc directory. + +LuaSrcDiet is now packaged as a single-file Lua script for maximum +convenience. Just drop it in and splice something into your Makefile. + +New source stream and binary chunk equivalence checking minimizes the +possibility of LuaSrcDiet borking your stuff. + +======================================================================== + +ACKNOWLEDGEMENTS + +Coded using SciTE. Developed mostly under Cygwin with a generic Lua +5.1.4 binary. + +======================================================================== + +FEEDBACK + +Feedback and contributions are welcome. Your name will be acknowledged, +as long as you are willing to comply with COPYRIGHT. If your material is +self-contained, you can retain a copyright notice for those material in +your own name, as long as you use the same Lua 5/MIT-style copyright. + +Enjoy! + +Kein-Hong Man (esq.) +Kuala Lumpur +Malaysia 20120407 diff --git a/scripts/luasrcdiet/README.premake b/scripts/luasrcdiet/README.premake new file mode 100644 index 0000000..859d762 --- /dev/null +++ b/scripts/luasrcdiet/README.premake @@ -0,0 +1,12 @@ +This is a patched up version of LuaSrcDiet 0.12.1. + +The following changes were implemented: + +* added local variables 'loaded_file_contents' and 'saved_file_contents'. +* overriding load_file() to store the loaded file contents in above mentioned + variable. +* overriding save_file() to store trimmed down source in above mentioned + variable. + ATTENTION: there are multiple functions of that name! +* commented out the "main functions" (search for this text). +* added function get_slim_luasrc() to return trimmed down code. diff --git a/setvcvars.cmd b/setvcvars.cmd new file mode 100644 index 0000000..7d03038 --- /dev/null +++ b/setvcvars.cmd @@ -0,0 +1,237 @@ +@echo off
+@if not "%OS%"=="Windows_NT" @(echo This script requires Windows NT 4.0 or later to run properly! & goto :EOF)
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: 2009-2015, Oliver Schneider (assarbad.net) - PUBLIC DOMAIN/CC0
+::: Available from: <https://bitbucket.org/assarbad/scripts/>
+:::
+::: PURPOSE: This script can be used to run the vcvars32.bat/vcvarsall.bat
+::: from any of the existing Visual C++ versions starting with .NET
+::: (2002) through 2015 or versions (or a single version) given on
+::: the command line.
+::: The script will try to find the newest installed VC version by
+::: iterating over the space-separated (descending) list of versions
+::: in the variable SUPPORTED_VC below, by default.
+::: Call it from another script and after that you will have NMAKE,
+::: DEVENV.EXE and friends available without having to hardcode
+::: their paths into a script or makefile.
+:::
+::: DISCLAIMER: Disclaimer: This software is provided 'as-is', without any
+::: express or implied warranty. In no event will the author be
+::: held liable for any damages arising from the use of this
+::: software.
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:SCRIPT
+setlocal & pushd .
+:: Toolsets (potentially) supported
+set SUPPORTED_TSET=amd64 x86 ia64 x86_ia64 x86_amd64 amd64_x86 x86_arm amd64_arm
+if not "%~1" == "" @(
+ if "%~1" == "/?" popd&endlocal&goto :Help
+ if "%~1" == "-?" popd&endlocal&goto :Help
+ if "%~1" == "/h" popd&endlocal&goto :Help
+ if "%~1" == "-h" popd&endlocal&goto :Help
+ if "%~1" == "/help" popd&endlocal&goto :Help
+ if "%~1" == "--help" popd&endlocal&goto :Help
+)
+if defined VCVER_FRIENDLY echo This script expects a clean environment. Don't run it several times in the same instance of CMD! Or use setlocal and endlocal in your own script to limit the effect of this one.&goto :EOF
+set MIN_VC=7.0
+set MAX_VC=14.0
+set MIN_NICE=2002
+set MAX_NICE=2015
+:: Internal representation of the version number
+set SUPPORTED_VC=14.0 12.0 11.0 10.0 9.0 8.0 7.1 7.0
+:: Marketing name of the Visual Studio versions
+set SUPPORTED_NICE=2015 2013 2012 2010 2008 2005 2003 2002
+set DEFAULT_TSET=x86
+reg /? > NUL 2>&1 || echo "REG.EXE is a prerequisite but wasn't found!" && goto :EOF
+set SETVCV_ERROR=0
+:: First parameter may point to a particular toolset ...
+if not "%~1" == "" @(
+ for %%i in (%SUPPORTED_TSET%) do @(
+ if "%~1" == "%%i" shift & call :SetVar VCTGT_TOOLSET %%i
+ )
+)
+:: Fall back to x86 if not given
+if not defined VCTGT_TOOLSET set VCTGT_TOOLSET=%DEFAULT_TSET%
+:: Make the string appear a bit nicer, i.e. comma-separated
+set SUPPORTED_PP=%SUPPORTED_NICE: =, %
+:: Allow the version to be overridden on the command line
+:: ... else find the VC versions in the order given by SUPPORTED_VC
+if not "%~1" == "" @(
+ for %%i in (%~1) do @(
+ call :FindVC "%%i"
+ )
+) else @(
+ echo Trying to auto-detect supported MSVC version ^(%SUPPORTED_PP%^)
+ echo HINT: pass one ^(or several^) of %SUPPORTED_PP% on the command line.
+ echo alternatively one ^(or several^) of: %SUPPORTED_VC%
+ echo.
+ for %%i in (%SUPPORTED_VC%) do @(
+ call :FindVC "%%i"
+ )
+)
+:: Check result and quit with error if necessary
+if not defined VCVARS_PATH @(
+ if not "%~1" == "" @(
+ echo Requested version ^"%~1^" of Visual Studio not found.
+ ) else @(
+ echo Could not find any supported version ^(%SUPPORTED_PP%^) of Visual C++.
+ )
+ popd & endlocal & exit /b %SETVCV_ERROR%
+)
+:: Return and make sure the outside world sees the results (i.e. leave the scope)
+popd & endlocal & if not "%VCVARS_PATH%" == "" @(call "%VCVARS_PATH%" %VCTGT_TOOLSET%) & if not "%VCVER_FRIENDLY%" == "" set VCVER_FRIENDLY=%VCVER_FRIENDLY%
+goto :EOF
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: / FindVC subroutine
+::: Param1 == version identifier for VC
+:::
+::: Sets the global variable VCVARS_PATH if it finds the installation.
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:FindVC
+setlocal ENABLEEXTENSIONS & set VCVER=%~1
+:: We're not interested in overwriting an already existing value
+if defined VCVARS_PATH @( endlocal & goto :EOF )
+:: Now let's distinguish the "nice" version numbers (2002, ... 2015) from the internal ones
+set VCVER=%VCVER:vs=%
+if "%VCVER%" geq "%MIN_NICE%" call :NICE_%VCVER% > NUL 2>&1
+:: Figure out the set of supported toolsets
+set VCVERLBL=%VCVER:.=_%
+call :TSET_%VCVERLBL% > NUL 2>&1
+:: Jump over those "subs"
+goto :NICE_SET
+:NICE_2015
+ set VCVER=14.0
+ goto :EOF
+:NICE_2013
+ set VCVER=12.0
+ goto :EOF
+:NICE_2012
+ set VCVER=11.0
+ goto :EOF
+:NICE_2010
+ set VCVER=10.0
+ goto :EOF
+:NICE_2008
+ set VCVER=9.0
+ goto :EOF
+:NICE_2005
+ set VCVER=8.0
+ goto :EOF
+:NICE_2003
+ set VCVER=7.1
+ goto :EOF
+:NICE_2002
+ set VCVER=7.0
+ goto :EOF
+:TSET_14_0
+:TSET_12_0
+ set SUPPORTED_TSET=x86 amd64 arm x86_amd64 x86_arm amd64_x86 amd64_arm
+ goto :EOF
+:TSET_11_0
+ set SUPPORTED_TSET=x86 amd64 arm x86_amd64 x86_arm
+ goto :EOF
+:TSET_10_0
+:TSET_9_0
+:TSET_8_0
+ set SUPPORTED_TSET=x86 ia64 amd64 x86_amd64 x86_ia64
+ goto :EOF
+:NICE_SET
+:: This is where we intend to find the installation path in the registry
+set _VSINSTALLKEY=HKLM\SOFTWARE\Microsoft\VisualStudio\%VCVER%\Setup\VC
+echo Trying to locate Visual C++ %VCVER% ^(%VCTGT_TOOLSET%^)
+for /f "tokens=2*" %%i in ('reg query "%_VSINSTALLKEY%" /v ProductDir 2^> NUL') do @(
+ call :SetVar _VCINSTALLDIR "%%j"
+)
+set _VSINSTALLKEY=HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%VCVER%\Setup\VC
+:: If we haven't found it by now, try the WOW64 "Software" key
+if not defined _VCINSTALLDIR @(
+ for /f "tokens=2*" %%i in ('reg query "%_VSINSTALLKEY%" /v ProductDir 2^> NUL') do @(
+ call :SetVar _VCINSTALLDIR "%%j"
+ )
+)
+set TEMP_TOOLSET=%VCTGT_TOOLSET%
+set TEMP_SUPPORTED=
+if defined _VCINSTALLDIR @(
+ if EXIST "%_VCINSTALLDIR%\vcvarsall.bat" @(
+ call :SetVar VCVARS_PATH "%_VCINSTALLDIR%\vcvarsall.bat"
+ )
+ if not defined VCVARS_PATH if EXIST "%_VCINSTALLDIR%\bin\vcvars32.bat" @(
+ call :SetVar VCVARS_PATH "%_VCINSTALLDIR%\bin\vcvars32.bat"
+ call :SetVar VCTGT_TOOLSET
+ )
+)
+if not "%VCTGT_TOOLSET%" == "" @(
+ for %%i in (%SUPPORTED_TSET%) do @(
+ if "%VCTGT_TOOLSET%" == "%%i" call :SetVar TEMP_SUPPORTED yes
+ )
+)
+if not "%TEMP_SUPPORTED%" == "yes" @( echo ERROR: Invalid toolset %TEMP_TOOLSET% for version %VCVER% of Visual C++&endlocal&set SETVCV_ERROR=1&goto :EOF )
+set VCTGT_TOOLSET=%TEMP_TOOLSET%
+:: Return, in case nothing was found
+if not defined VCVARS_PATH @( endlocal&set SETVCV_ERROR=1&goto :EOF )
+:: Replace the . in the version by an underscore
+set VCVERLBL=%VCVER:.=_%
+:: Try to set a friendlier name for the Visual Studio version
+call :FRIENDLY_%VCVERLBL% > NUL 2>&1
+:: Jump over those "subs"
+goto :FRIENDLY_SET
+:FRIENDLY_14_0
+ set _VCVER=2015 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_12_0
+ set _VCVER=2013 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_11_0
+ set _VCVER=2012 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_10_0
+ set _VCVER=2010 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_9_0
+ set _VCVER=2008 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_8_0
+ set _VCVER=2005 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_7_1
+ set _VCVER=.NET 2003 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_7_0
+ set _VCVER=.NET 2002 ^[%TEMP_TOOLSET%^]
+ goto :EOF
+:FRIENDLY_SET
+if not defined _VCVER call :SetVar _VCVER "%VCVER%"
+echo -^> Found Visual C++ %_VCVER%
+endlocal & set VCVARS_PATH=%VCVARS_PATH%&set VCVER_FRIENDLY=Visual C++ %_VCVER%
+goto :EOF
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: \ FindVC subroutine
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: / Help subroutine
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:Help
+echo.
+echo Syntax: setvcvars ^[toolset^] ^[store^] ^[VS versions^]
+echo.
+echo The toolset can be one of %SUPPORTED_TSET% according to the version of Visual Studio.
+echo 'store' is the literal string store for Visual Studio 2015 and newer.
+exit /b 0
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: \ Help subroutine
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: / SetVar subroutine
+::: Param1 == name of the variable, Param2 == value to be set for the variable
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:SetVar
+:: Get the name of the variable we are working with
+setlocal ENABLEEXTENSIONS&set VAR_NAME=%1
+endlocal & set %VAR_NAME%=%~2
+goto :EOF
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::: \ SetVar subroutine
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
diff --git a/src/actions/vstudio/_vstudio.lua b/src/actions/vstudio/_vstudio.lua index 4976508..d0b75d4 100644 --- a/src/actions/vstudio/_vstudio.lua +++ b/src/actions/vstudio/_vstudio.lua @@ -142,17 +142,20 @@ local fname = premake.project.getfilename(prj, "%%") os.remove(fname .. ".vcproj") - os.remove(fname .. ".vcproj.user") os.remove(fname .. ".vcxproj") - os.remove(fname .. ".vcxproj.user") os.remove(fname .. ".vcxproj.filters") os.remove(fname .. ".csproj") - os.remove(fname .. ".csproj.user") os.remove(fname .. ".pidb") os.remove(fname .. ".sdf") + + if _OPTIONS.generate_user then + os.remove(fname .. ".vcproj.user") + os.remove(fname .. ".vcxproj.user") + os.remove(fname .. ".csproj.user") + end end function vstudio.cleantarget(name) @@ -222,10 +225,14 @@ onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2002.generate) - premake.generate(prj, "%%.csproj.user", vstudio.cs2002.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.csproj.user", vstudio.cs2002.generate_user) + end else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) - premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + end end end, @@ -263,10 +270,14 @@ onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2002.generate) - premake.generate(prj, "%%.csproj.user", vstudio.cs2002.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.csproj.user", vstudio.cs2002.generate_user) + end else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) - premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + end end end, @@ -304,10 +315,14 @@ onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) - premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + end else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) - premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + end end end, @@ -347,10 +362,14 @@ onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) - premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + end else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) - premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) + end end end, @@ -393,11 +412,15 @@ onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) - premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) + end else - premake.generate(prj, "%%.vcxproj", premake.vs2010_vcxproj) - premake.generate(prj, "%%.vcxproj.user", premake.vs2010_vcxproj_user) - premake.generate(prj, "%%.vcxproj.filters", vstudio.vc2010.generate_filters) + premake.generate(prj, "%%.vcxproj", premake.vs2010_vcxproj) + if _OPTIONS.generate_user then + premake.generate(prj, "%%.vcxproj.user", premake.vs2010_vcxproj_user) + end + premake.generate(prj, "%%.vcxproj.filters", vstudio.vc2010.generate_filters) end end, diff --git a/src/actions/vstudio/vs2005_csproj.lua b/src/actions/vstudio/vs2005_csproj.lua index 6b6238c..afa3710 100644 --- a/src/actions/vstudio/vs2005_csproj.lua +++ b/src/actions/vstudio/vs2005_csproj.lua @@ -38,7 +38,7 @@ local basename = fname:sub(1, -9)
local testname = basename .. ".xaml"
if premake.findfile(prj, testname) then
- return "SubTypeCode", path.getname(testname)
+ return "SubTypeCode", testname
end
else
-- is there a *.Designer.cs file?
@@ -207,23 +207,6 @@ end
end
---
--- Write the build events groups.
---
-
- function cs2005.buildevents(cfg)
- if #cfg.prebuildcommands > 0 then - _p(' <PropertyGroup>')
- _p(' <PreBuildEvent>%s</PreBuildEvent>', premake.esc(table.implode(cfg.prebuildcommands, "", "", "\r\n")))
- _p(' </PropertyGroup>')
- end - if #cfg.postbuildcommands > 0 then - _p(' <PropertyGroup>')
- _p(' <PostBuildEvent>%s</PostBuildEvent>', premake.esc(table.implode(cfg.postbuildcommands, "", "", "\r\n")))
- _p(' </PropertyGroup>')
- end - end
-
--
-- The main function: write the project file.
@@ -282,9 +265,6 @@ local msbuild = iif(_ACTION < "vs2012", "Bin", "Tools")
_p(' <Import Project="$(MSBuild%sPath)\\Microsoft.CSharp.targets" />', msbuild)
- -- build events
- cs2005.buildevents(prj)
-
_p(' <!-- To modify your build process, add your task inside one of the targets below and uncomment it.')
_p(' Other similar extension points exist, see Microsoft.Common.targets.')
_p(' <Target Name="BeforeBuild">')
diff --git a/src/base/cmdline.lua b/src/base/cmdline.lua index 592edff..5bfe02d 100644 --- a/src/base/cmdline.lua +++ b/src/base/cmdline.lua @@ -88,4 +88,10 @@ trigger = "version", description = "Display version information" } + + newoption + { + trigger = "generate_user", + description = "Generate (and remove when cleaning) .user VStudio files" + }
\ No newline at end of file diff --git a/src/host/os_match.c b/src/host/os_match.c index 5ccc04d..460bf5f 100644 --- a/src/host/os_match.c +++ b/src/host/os_match.c @@ -8,6 +8,17 @@ #include <string.h> #include "premake.h" +static int skip_dot_entries(const char* name) +{ + if (name[0] == '.') + { + if (name[1] == '\0') + return 1; + if (name[1] == '.' && name[2] == '\0') + return 1; + } + return 0; +} #if PLATFORM_WINDOWS @@ -25,7 +36,7 @@ int os_matchstart(lua_State* L) { const char* mask = luaL_checkstring(L, 1); MatchInfo* m = (MatchInfo*)malloc(sizeof(MatchInfo)); - m->handle = FindFirstFile(mask, &m->entry); + m->handle = FindFirstFile(mask, &m->entry); /* error handling happens in os_matchnext() below */ m->is_first = 1; lua_pushlightuserdata(L, m); return 1; @@ -57,10 +68,9 @@ int os_matchisfile(lua_State* L) int os_matchnext(lua_State* L) { MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1); - if (m->handle == INVALID_HANDLE_VALUE) { + if (m->handle == INVALID_HANDLE_VALUE) return 0; - } - + while (m) /* loop forever */ { if (!m->is_first) @@ -70,6 +80,10 @@ int os_matchnext(lua_State* L) } m->is_first = 0; + /* Ignore the directory entries for . and .. only */ + if (m->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + if (skip_dot_entries(m->entry.cFileName)) + continue; lua_pushboolean(L, 1); return 1; } @@ -153,7 +167,7 @@ int os_matchisfile(lua_State* L) lua_pushboolean(L, S_ISREG(info.st_mode)); return 1; } - + return 0; } @@ -162,16 +176,18 @@ 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 (fnmatch(m->mask, name, 0) == 0) - { - lua_pushboolean(L, 1); - return 1; - } + /* Ignore the directory entries for . and .. only */ + if (!skip_dot_entries(name)) + if (fnmatch(m->mask, name, 0) == 0) + { + lua_pushboolean(L, 1); + return 1; + } m->entry = readdir(m->handle); } diff --git a/src/host/premake.c b/src/host/premake.c index 9e30d50..8b9d550 100755 --- a/src/host/premake.c +++ b/src/host/premake.c @@ -12,8 +12,12 @@ #include <CoreFoundation/CFBundle.h> #endif - +#ifdef HAVE_HGTIP +# include "hgtip.h" +# define VERSION HG_TIP_ID ":" HG_TIP_REVNO +#else #define VERSION "HEAD" +#endif #define COPYRIGHT "Copyright (C) 2002-2013 Jason Perkins and the Premake Project" #define ERROR_MESSAGE "%s\n" @@ -374,9 +378,13 @@ static int load_builtin_scripts(lua_State* L) } } + /* in release mode, also show full traceback on all errors */ + lua_getglobal(L, "debug"); + lua_getfield(L, -1, "traceback"); + /* hand off control to the scripts */ lua_getglobal(L, "_premake_main"); - if (lua_pcall(L, 0, 1, 0) != OKAY) + if (lua_pcall(L, 0, 1, -2) != OKAY) { printf(ERROR_MESSAGE, lua_tostring(L, -1)); return !OKAY; diff --git a/src/host/premake4.ico b/src/host/premake4.ico Binary files differnew file mode 100644 index 0000000..22b2c30 --- /dev/null +++ b/src/host/premake4.ico diff --git a/src/host/premake4.rc b/src/host/premake4.rc new file mode 100644 index 0000000..147f80f --- /dev/null +++ b/src/host/premake4.rc @@ -0,0 +1,55 @@ +#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+#include <winnt.rh>
+#include <verrsrc.h>
+#ifdef HAVE_HGTIP
+# include "hgtip.h"
+#endif
+
+#ifndef IDR_MAINFRAME
+#define IDR_MAINFRAME 1
+#endif // IDR_MAINFRAME
+
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,4,0,0xFFFF
+ PRODUCTVERSION 4,4,0,0
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS VS_FF_PRERELEASE
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "WDS Team"
+ VALUE "FileDescription", "A build configuration tool"
+ VALUE "InternalName", "premake4-windirstat"
+#ifdef HAVE_HGTIP
+ VALUE "FileVersion", "4.4-wds-" HG_TIP_REVNO
+ VALUE "ProductVersion", "4.4-wds-" HG_TIP_REVNO
+ VALUE "OriginalFilename", "premake4.rev-" HG_TIP_REVNO "-" HG_TIP_ID ".exe"
+#else
+ VALUE "FileVersion", "4.4-wds"
+ VALUE "ProductVersion", "4.4-wds"
+ VALUE "OriginalFilename", "premake4.exe"
+#endif
+ VALUE "LegalCopyright", "Copyright (C) 2002-2013 by Jason Perkins, with minor customizations by WDS team"
+ VALUE "ProductName", "premake4"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+IDR_MAINFRAME ICON "premake4.ico"
diff --git a/src/host/scripts.c b/src/host/scripts.c new file mode 100644 index 0000000..b5fba27 --- /dev/null +++ b/src/host/scripts.c @@ -0,0 +1,301 @@ +/* Premake's Lua scripts, as static data buffers for release mode builds */ +/* DO NOT EDIT - this file is autogenerated - see BUILD.txt */ +/* To regenerate this file, run: premake4 embed */ + +const char* builtin_scripts[] = { + /* base/os.lua */ + "function os.executef(n,...)n=string.format(n,unpack(arg))return os.execute(n)end\nlocal function i(n)local e,t\nlocal o={}local n=io.open(n)if n==nil then\nreturn o\nend\nfor n in n:lines()do\ne=n:find(\"#\",1,true)if e~=nil then\nn=n:sub(1,e-1)end\nif n~=\"\"then\ne,t=n:find(\"include%s+\")if e~=nil then\nlocal n=n:sub(t+1)local n=os.matchfiles(n)for e,n in ipairs(n)do\no=table.join(o,i(n))end\nelse\ntable.insert(o,n)end\nend\nend\nreturn o\nend\nfunction os.findlib(e)local n,o\nif os.is(\"windows\")then\no={\"%s.dll\",\"%s\"}n=os.getenv(\"PATH\")elseif os.is(\"haiku\")then\no={\"lib%s.so\",\"%s.so\"}n=os.getenv(\"LIBRARY_PATH\")else\nif os.is(\"macosx\")then\no={\"lib%s.dylib\",\"%s.dylib\"}n=os.getenv(\"DYLD_LIBRARY_PATH\")else\no={\"lib%s.so\",\"%s.so\"}n=os.getenv(\"LD_LIBRARY_PATH\")or\"\"for e,o in ipairs(i(\"/etc/ld.so.conf\"))do\nn=n..\":\"..o\nend\nend\ntable.insert(o,\"%s\")n=n or\"\"if os.is64bit()then\nn=n..\":/lib64:/usr/lib64/:usr/local/lib64\"end\nn=n..\":/lib:/usr/lib:/usr/local/lib\"end\nfor " + "i,o in ipairs(o)do\nlocal o=string.format(o,e)local n=os.pathsearch(o,n)if n then return n end\nend\nend\nfunction os.get()return _OPTIONS.os or _OS\nend\nfunction os.is(n)return(os.get():lower()==n:lower())end\nlocal o={\"x86_64\",\"ia64\",\"amd64\",\"ppc64\",\"powerpc64\",\"sparc64\"}function os.is64bit()if(os._is64bit())then\nreturn true\nend\nlocal n\nif _OS==\"windows\"then\nn=os.getenv(\"PROCESSOR_ARCHITECTURE\")elseif _OS==\"macosx\"then\nn=os.outputof(\"echo $HOSTTYPE\")else\nn=os.outputof(\"uname -m\")end\nn=n:lower()for e,o in ipairs(o)do\nif n:find(o)then\nreturn true\nend\nend\nreturn false\nend\nlocal function l(l,n,i)if n:startswith(\"./\")then\nn=n:sub(3)end\nlocal e=n\nlocal o=n:find(\"%*\")if o then\ne=e:sub(1,o-1)end\ne=path.getdirectory(e)if(e==\".\")then e=\"\"end\nlocal a=n:find(\"**\",nil,true)n=path.wildcards(n)local function t(e)local s=path.join(e,\"*\")local o=os.matchstart(s)while(os.matchnext(o))do\nlocal t=os.matchisfile(o)if((i and t)or(not i and not t))then\nlocal i=os.matchname(" + "o)local o=path.join(e,i)if i~=\"..\"and o:match(n)==o then\ntable.insert(l,o)end\nend\nend\nos.matchdone(o)if a then\no=os.matchstart(s)while(os.matchnext(o))do\nif not os.matchisfile(o)then\nlocal n=os.matchname(o)if(not n:startswith(\".\"))then\nt(path.join(e,n))end\nend\nend\nos.matchdone(o)end\nend\nt(e)end\nfunction os.matchdirs(...)local n={}for e,o in ipairs(arg)do\nl(n,o,false)end\nreturn n\nend\nfunction os.matchfiles(...)local n={}for e,o in ipairs(arg)do\nl(n,o,true)end\nreturn n\nend\nlocal e=os.mkdir\nfunction os.mkdir(o)local n=iif(o:startswith(\"/\"),\"/\",\"\")for o in o:gmatch(\"[^/]+\")do\nn=n..o\nif(o~=\"\"and not path.isabsolute(o)and not os.isdir(n))then\nlocal n,o=e(n)if(not n)then\nreturn nil,o\nend\nend\nn=n..\"/\"end\nreturn true\nend\nfunction os.outputof(n)local n=io.popen(n)local o=n:read('*a')n:close()return o\nend\nlocal e=os.rmdir\nfunction os.rmdir(n)local o=os.matchdirs(n..\"/*\")for o,n in ipairs(o)do\nos.rmdir(n)end\nlocal o=os.matchfiles(n..\"/*\")for o,n in ipairs(o)do\nos." + "remove(n)end\ne(n)end", + + /* base/path.lua */ + "function path.getbasename(e)local e=path.getname(e)local n=e:findlast(\".\",true)if(n)then\nreturn e:sub(1,n-1)else\nreturn e\nend\nend\nfunction path.getdirectory(n)local e=n:findlast(\"/\",true)if(e)then\nif e>1 then e=e-1 end\nreturn n:sub(1,e)else\nreturn\".\"end\nend\nfunction path.getdrive(e)local n=e:sub(1,1)local e=e:sub(2,2)if e==\":\"then\nreturn n\nend\nend\nfunction path.getextension(e)local n=e:findlast(\".\",true)if(n)then\nreturn e:sub(n)else\nreturn\"\"end\nend\nfunction path.getname(e)local n=e:findlast(\"[/\\\\]\")if(n)then\nreturn e:sub(n+1)else\nreturn e\nend\nend\nfunction path.iscfile(e)local n={\".c\",\".s\",\".m\"}local e=path.getextension(e):lower()return table.contains(n,e)end\nfunction path.iscppfile(e)local n={\".cc\",\".cpp\",\".cxx\",\".c\",\".s\",\".m\",\".mm\"}local e=path.getextension(e):lower()return table.contains(n,e)end\nfunction path.iscppheader(e)local n={\".h\",\".hh\",\".hpp\",\".hxx\"}local e=path.getextension(e):lower()return table.contains(n,e)end\nfunction path.isre" + "sourcefile(e)local n={\".rc\"}local e=path.getextension(e):lower()return table.contains(n,e)end\nfunction path.rebase(e,t,n)e=path.getabsolute(path.join(t,e))e=path.getrelative(n,e)return e\nend\nlocal n=path.translate\nfunction path.translate(t,e)if not e then\nif os.is(\"windows\")then\ne=\"\\\\\"else\ne=\"/\"end\nend\nreturn n(t,e)end\nfunction path.wildcards(e)e=e:gsub(\"([%+%.%-%^%$%(%)%%])\",\"%%%1\")e=e:gsub(\"%*%*\",\"\\1\")e=e:gsub(\"%*\",\"\\2\")e=e:gsub(\"\\1\",\".*\")e=e:gsub(\"\\2\",\"[^/]*\")return e\nend", + + /* base/string.lua */ + "function string.explode(e,i,r)if(i=='')then return false end\nlocal n=0\nlocal t={}for r,i in function()return e:find(i,n,r)end do\ntable.insert(t,e:sub(n,r-1))n=i+1\nend\ntable.insert(t,e:sub(n))return t\nend\nfunction string.findlast(i,e,t)local n=0\nrepeat\nlocal t=i:find(e,n+1,t)if(t)then n=t end\nuntil(not t)if(n>0)then\nreturn n\nend\nend\nfunction string.startswith(n,t)return(n:find(t,1,true)==1)end", + + /* base/table.lua */ + "function table.contains(n,e)for t,n in pairs(n)do\nif(n==e)then\nreturn true\nend\nend\nreturn false\nend\nfunction table.extract(n,t)local e={}for i,n in ipairs(n)do\ntable.insert(e,n[t])end\nreturn e\nend\nfunction table.flatten(i)local n={}local function t(e)for i,e in ipairs(e)do\nif type(e)==\"table\"then\nt(e)else\ntable.insert(n,e)end\nend\nend\nt(i)return n\nend\nfunction table.implode(r,t,i,n)local e=\"\"for a,r in ipairs(r)do\nif(e~=\"\"and n)then\ne=e..n\nend\ne=e..t..r..i\nend\nreturn e\nend\nfunction table.insertflat(n,e)if type(e)==\"table\"then\nfor t,e in ipairs(e)do\ntable.insertflat(n,e)end\nelse\ntable.insert(n,e)end\nend\nfunction table.isempty(e)return next(e)==nil\nend\nfunction table.join(...)local e={}for t,n in ipairs(arg)do\nif type(n)==\"table\"then\nfor t,n in ipairs(n)do\ntable.insert(e,n)end\nelse\ntable.insert(e,n)end\nend\nreturn e\nend\nfunction table.keys(n)local e={}for n,t in pairs(n)do\ntable.insert(e,n)end\nreturn e\nend\nfunction table.merge(...)local n={}for t,e in ipair" + "s(arg)do\nif type(e)==\"table\"then\nfor e,t in pairs(e)do\nn[e]=t\nend\nelse\nerror(\"invalid value\")end\nend\nreturn n\nend\nfunction table.translate(e,n)local i={}for e,t in ipairs(e)do\nlocal e\nif type(n)==\"function\"then\ne=n(t)else\ne=n[t]end\nif(e)then\ntable.insert(i,e)end\nend\nreturn i\nend", + + /* base/io.lua */ + "function io.capture()io.captured=''end\nfunction io.endcapture()local e=io.captured\nio.captured=nil\nreturn e\nend\nlocal i=io.open\nfunction io.open(n,e)if(e)then\nif(e:find(\"w\"))then\nlocal e=path.getdirectory(n)ok,err=os.mkdir(e)if(not ok)then\nerror(err,0)end\nend\nend\nreturn i(n,e)end\nfunction io.printf(e,...)if not io.eol then\nio.eol=\"\\n\"end\nif not io.indent then\nio.indent=\"\\t\"end\nif type(e)==\"number\"then\ns=string.rep(io.indent,e)..string.format(unpack(arg))else\ns=string.format(e,unpack(arg))end\nif io.captured then\nio.captured=io.captured..s..io.eol\nelse\nio.write(s)io.write(io.eol)end\nend\n_p=io.printf", + + /* base/globals.lua */ + "premake={}premake.platforms={Native={cfgsuffix=\"\",},x32={cfgsuffix=\"32\",},x64={cfgsuffix=\"64\",},Universal={cfgsuffix=\"univ\",},Universal32={cfgsuffix=\"univ32\",},Universal64={cfgsuffix=\"univ64\",},PS3={cfgsuffix=\"ps3\",iscrosscompiler=true,nosharedlibs=true,namestyle=\"PS3\",},WiiDev={cfgsuffix=\"wii\",iscrosscompiler=true,namestyle=\"PS3\",},Xbox360={cfgsuffix=\"xbox360\",iscrosscompiler=true,namestyle=\"windows\",},}local n=dofile\nfunction dofile(e)local f=os.getcwd()local t=_SCRIPT\nif(not os.isfile(e))then\nlocal i=os.pathsearch(e,_OPTIONS[\"scripts\"],os.getenv(\"PREMAKE_PATH\"))if(i)then\ne=i..\"/\"..e\nend\nend\n_SCRIPT=path.getabsolute(e)local e=path.getdirectory(_SCRIPT)os.chdir(e)local o,r,n,i,s,e=n(_SCRIPT)_SCRIPT=t\nos.chdir(f)return o,r,n,i,s,e\nend\nfunction iif(i,e,n)if(i)then\nreturn e\nelse\nreturn n\nend\nend\nfunction include(e)return dofile(e..\"/premake4.lua\")end\nfunction printf(e,...)print(string.format(e,unpack(arg)))end\nlocal n=type\nfunction type(i)local e=getmetatable(i)" + "if(e)then\nif(e.__type)then\nreturn e.__type\nend\nend\nreturn n(i)end", + + /* base/action.lua */ + "premake.action={}premake.action.list={}function premake.action.add(e)local n\nfor i,t in ipairs({\"description\",\"trigger\"})do\nif(not e[t])then\nn=t\nend\nend\nif(n)then\nerror(\"action needs a \"..n,3)end\npremake.action.list[e.trigger]=e\nend\nfunction premake.action.call(e)local e=premake.action.list[e]for n in premake.solution.each()do\nif e.onsolution then\ne.onsolution(n)end\nfor n in premake.solution.eachproject(n)do\nif e.onproject then\ne.onproject(n)end\nend\nend\nif e.execute then\ne.execute()end\nend\nfunction premake.action.current()return premake.action.get(_ACTION)end\nfunction premake.action.get(e)return premake.action.list[e]end\nfunction premake.action.each()local n={}for t,e in pairs(premake.action.list)do\ntable.insert(n,e.trigger)end\ntable.sort(n)local e=0\nreturn function()e=e+1\nreturn premake.action.list[n[e]]end\nend\nfunction premake.action.set(e)_ACTION=e\nlocal e=premake.action.get(e)if e then\n_OS=e.os or _OS\nend\nend\nfunction premake.action.supports(e,n)if not e then\nreturn" + " false\nend\nif e.valid_languages then\nif table.contains(e.valid_languages,n)then\nreturn true\nend\nend\nif e.valid_kinds then\nif table.contains(e.valid_kinds,n)then\nreturn true\nend\nend\nreturn false\nend", + + /* base/option.lua */ + "premake.option={}premake.option.list={}function premake.option.add(e)local n\nfor t,o in ipairs({\"description\",\"trigger\"})do\nif(not e[o])then\nn=o\nend\nend\nif(n)then\nerror(\"option needs a \"..n,3)end\npremake.option.list[e.trigger]=e\nend\nfunction premake.option.get(e)return premake.option.list[e]end\nfunction premake.option.each()local e={}for o,n in pairs(premake.option.list)do\ntable.insert(e,n.trigger)end\ntable.sort(e)local n=0\nreturn function()n=n+1\nreturn premake.option.list[e[n]]end\nend\nfunction premake.option.validate(e)for n,o in pairs(e)do\nlocal e=premake.option.get(n)if(not e)then\nreturn false,\"invalid option '\"..n..\"'\"end\nif(e.value and o==\"\")then\nreturn false,\"no value specified for option '\"..n..\"'\"end\nif e.allowed then\nlocal t=false\nfor n,e in ipairs(e.allowed)do\nif e[1]==o then\nt=true\nbreak\nend\nend\nif not t then\nreturn false,string.format(\"invalid value '%s' for option '%s'\",o,n)end\nend\nend\nreturn true\nend", + + /* base/tree.lua */ + "premake.tree={}local t=premake.tree\nfunction premake.tree.new(e)local e={name=e,children={}}return e\nend\nfunction premake.tree.add(e,n,a)if n==\".\"then\nreturn e\nend\nlocal d=t.add(e,path.getdirectory(n),a)local r=path.getname(n)if r==\"..\"then\nreturn d\nend\nlocal e=d.children[r]if not e or e.path~=n then\ne=t.insert(d,t.new(r))e.path=n\nif a then\na(e)end\nend\nreturn e\nend\nfunction premake.tree.insert(n,e)table.insert(n.children,e)if e.name then\nn.children[e.name]=e\nend\ne.parent=n\nreturn e\nend\nfunction premake.tree.getlocalpath(e)if e.parent.path then\nreturn e.name\nelseif e.cfg then\nreturn e.cfg.name\nelse\nreturn e.path\nend\nend\nfunction premake.tree.remove(n)local e=n.parent.children\nfor t=1,#e do\nif e[t]==n then\ntable.remove(e,t)end\nend\nn.children={}end\nfunction premake.tree.sort(e)t.traverse(e,{onnode=function(e)table.sort(e.children,function(e,n)return e.name<n.name\nend)end},true)end\nfunction premake.tree.traverse(o,i,h,r)local d,a\nd=function(n,e,t)if n.isremoved then\nretu" + "rn\nend\nif e.onnode then\ne.onnode(n,t)end\nif#n.children>0 then\nif e.onbranchenter then\ne.onbranchenter(n,t)end\nif e.onbranch then\ne.onbranch(n,t)end\na(n,e,t+1)if e.onbranchexit then\ne.onbranchexit(n,t)end\nelse\nif e.onleaf then\ne.onleaf(n,t)end\nend\nend\na=function(n,a,r)local e=1\nwhile e<=#n.children do\nlocal t=n.children[e]d(t,a,r)if t==n.children[e]then\ne=e+1\nend\nend\nend\nif not r then\nr=0\nend\nif h then\nd(o,i,r)else\na(o,i,r)end\nend", + + /* base/solution.lua */ + "premake.solution={}premake.solution.list={}function premake.solution.new(n)local e={}table.insert(premake.solution.list,e)premake.solution.list[n]=e\nsetmetatable(e,{__type=\"solution\"})e.name=n\ne.basedir=os.getcwd()e.projects={}e.blocks={}e.configurations={}return e\nend\nfunction premake.solution.each()local e=0\nreturn function()e=e+1\nif e<=#premake.solution.list then\nreturn premake.solution.list[e]end\nend\nend\nfunction premake.solution.eachproject(n)local e=0\nreturn function()e=e+1\nif(e<=#n.projects)then\nreturn premake.solution.getproject(n,e)end\nend\nend\nfunction premake.solution.get(e)return premake.solution.list[e]end\nfunction premake.solution.getproject(n,e)local e=n.projects[e]local n=premake.getconfig(e)n.name=e.name\nreturn n\nend", + + /* base/project.lua */ + "premake.project={}function premake.project.buildsourcetree(e)local n=premake.tree.new(e.name)n.project=e\nlocal t\nlocal function a(e)e.isvpath=t\nend\nfor e in premake.project.eachfile(e)do\nt=(e.name~=e.vpath)local n=premake.tree.add(n,e.vpath,a)n.cfg=e\nend\npremake.tree.sort(n)return n\nend\nfunction premake.eachconfig(e,a)if e.project then e=e.project end\nlocal t=e.solution.configurations\nlocal n=0\nreturn function()n=n+1\nif n<=#t then\nreturn premake.getconfig(e,t[n],a)end\nend\nend\nfunction premake.project.eachfile(e)if not e.project then e=premake.getconfig(e)end\nlocal n=0\nlocal t=e.files\nreturn function()n=n+1\nif(n<=#t)then\nlocal n=e.__fileconfigs[t[n]]n.vpath=premake.project.getvpath(e,n.name)return n\nend\nend\nend\nfunction premake.esc(e)if(type(e)==\"table\")then\nlocal n={}for t,e in ipairs(e)do\ntable.insert(n,premake.esc(e))end\nreturn n\nelse\ne=e:gsub('&',\"&\")e=e:gsub('\"',\""\")e=e:gsub(\"'\",\"'\")e=e:gsub('<',\"<\")e=e:gsub('>',\">\")e=e:gsub('\\r',\"
\"" + ")e=e:gsub('\\n',\"
\")return e\nend\nend\nfunction premake.filterplatforms(n,t,r)local e={}local a={}if n.platforms then\nfor r,n in ipairs(n.platforms)do\nif t[n]and not table.contains(a,t[n])then\ntable.insert(e,n)table.insert(a,t[n])end\nend\nend\nif#e==0 and r then\ntable.insert(e,r)end\nreturn e\nend\nfunction premake.findproject(n)for e in premake.solution.each()do\nfor e in premake.solution.eachproject(e)do\nif(e.name==n)then\nreturn e\nend\nend\nend\nend\nfunction premake.findfile(e,n)for t,e in ipairs(e.files)do\nif e:endswith(n)then return e end\nend\nend\nfunction premake.getconfig(e,t,n)e=e.project or e\nif n==\"Native\"or not table.contains(e.solution.platforms or{},n)then\nn=nil\nend\nlocal t=(t or\"\")if n then t=t..n end\nreturn e.__configs[t]end\nfunction premake.getconfigname(e,n,t)if e then\nlocal e=e\nif n and n~=\"Native\"then\nif t then\ne=e..premake.platforms[n].cfgsuffix\nelse\ne=e..\"|\"..n\nend\nend\nreturn iif(t,e:lower(),e)end\nend\nfunction premake.getdependencies(e)e=e.projec" + "t or e\nlocal n={}for t,e in pairs(e.__configs)do\nfor t,e in ipairs(e.links)do\nlocal e=premake.findproject(e)if e and not table.contains(n,e)then\ntable.insert(n,e)end\nend\nend\nreturn n\nend\nfunction premake.project.getbasename(e,n)return n:gsub(\"%%%%\",e)end\nfunction premake.project.getfilename(n,e)local e=premake.project.getbasename(n.name,e)e=path.join(n.location,e)return path.getrelative(os.getcwd(),e)end\nfunction premake.getlinks(n,i,t)local l=iif(t==\"directory\"and i==\"all\",n.libdirs,{})local a=iif(n.name==n.project.name,\"\",n.name)local p=premake.getpathstyle(n)local d=premake.getnamestyle(n)local function c(n,e)if(e.kind~=\"SharedLib\"and e.kind~=\"StaticLib\")then\nreturn false\nend\nif premake.iscppproject(n)then\nreturn premake.iscppproject(e)elseif premake.isdotnetproject(n)then\nreturn premake.isdotnetproject(e)end\nend\nfor e,r in ipairs(n.links)do\nlocal e\nlocal o=premake.findproject(r)if o and i~=\"system\"then\nlocal a=premake.getconfig(o,a,n.platform)if i==\"dependencies\"or c(n," + "a)then\nif(t==\"directory\")then\ne=path.rebase(a.linktarget.directory,a.location,n.location)elseif(t==\"basename\")then\ne=a.linktarget.basename\nelseif(t==\"fullpath\")then\ne=path.rebase(a.linktarget.fullpath,a.location,n.location)elseif(t==\"object\")then\ne=a\nend\nend\nelseif not o and(i==\"system\"or i==\"all\")then\nif(t==\"directory\")then\ne=path.getdirectory(r)elseif(t==\"fullpath\")then\ne=r\nif d==\"windows\"then\nif premake.iscppproject(n)then\ne=e..\".lib\"elseif premake.isdotnetproject(n)then\ne=e..\".dll\"end\nend\nelseif t==\"name\"then\ne=path.getname(r)elseif t==\"basename\"then\ne=path.getbasename(r)else\ne=r\nend\nif e:find(\"/\",nil,true)then\ne=path.getrelative(n.project.location,e)end\nend\nif e then\nif p==\"windows\"and t~=\"object\"then\ne=path.translate(e,\"\\\\\")end\nif not table.contains(l,e)then\ntable.insert(l,e)end\nend\nend\nreturn l\nend\nfunction premake.getnamestyle(e)return premake.platforms[e.platform].namestyle or premake.gettool(e).namestyle or\"posix\"end\nfunction p" + "remake.getpathstyle(e)if premake.action.current().os==\"windows\"then\nreturn\"windows\"else\nreturn\"posix\"end\nend\nfunction premake.gettarget(e,t,f,i,r)if r==\"bsd\"or r==\"solaris\"then\nr=\"linux\"end\nlocal n=e.kind\nif premake.iscppproject(e)then\nif(i==\"windows\"or r==\"windows\")and n==\"SharedLib\"and t==\"link\"and not e.flags.NoImportLib\nthen\nn=\"StaticLib\"end\nif i==\"posix\"and r==\"windows\"and n~=\"StaticLib\"then\ni=\"windows\"end\nend\nlocal o=\"build\"if t==\"link\"and e.kind==\"SharedLib\"then\no=\"implib\"end\nlocal c=e[o..\"name\"]or e.targetname or e.project.name\nlocal d=e[o..\"dir\"]or e.targetdir or path.getrelative(e.location,e.basedir)local a=\"\"local l=\"\"local t=\"\"local p,s\nif i==\"windows\"then\nif n==\"ConsoleApp\"or n==\"WindowedApp\"then\nt=\".exe\"elseif n==\"SharedLib\"then\nt=\".dll\"elseif n==\"StaticLib\"then\nt=\".lib\"end\nelseif i==\"posix\"then\nif n==\"WindowedApp\"and r==\"macosx\"then\ns=c..\".app\"p=path.join(d,s)d=path.join(p,\"Contents/MacOS\")elseif n" + "==\"SharedLib\"then\na=\"lib\"t=iif(r==\"macosx\",\".dylib\",\".so\")elseif n==\"StaticLib\"then\na=\"lib\"t=\".a\"end\nelseif i==\"PS3\"then\nif n==\"ConsoleApp\"or n==\"WindowedApp\"then\nt=\".elf\"elseif n==\"StaticLib\"then\na=\"lib\"t=\".a\"end\nend\na=e[o..\"prefix\"]or e.targetprefix or a\nl=e[o..\"suffix\"]or e.targetsuffix or l\nt=e[o..\"extension\"]or e.targetextension or t\nlocal e={}e.basename=c..l\ne.name=a..c..l..t\ne.directory=d\ne.prefix=a\ne.suffix=l\ne.fullpath=path.join(e.directory,e.name)e.bundlepath=p or e.fullpath\nif f==\"windows\"then\ne.directory=path.translate(e.directory,\"\\\\\")e.fullpath=path.translate(e.fullpath,\"\\\\\")end\nreturn e\nend\nfunction premake.gettool(e)if premake.iscppproject(e)then\nif _OPTIONS.cc then\nreturn premake[_OPTIONS.cc]end\nlocal e=premake.action.current()if e.valid_tools then\nreturn premake[e.valid_tools.cc[1]]end\nreturn premake.gcc\nelse\nreturn premake.dotnet\nend\nend\nfunction premake.project.getvpath(e,t)local n=t\nlocal i=path.getname(t)local o" + "=t:len()-i:len()for r,e in pairs(e.vpaths or{})do\nfor a,e in ipairs(e)do\nlocal a=t:find(path.wildcards(e))if a==1 then\na=e:find(\"*\",1,true)or(e:len()+1)local e\nif a<o then\ne=t:sub(a)else\ne=i\nend\nif e:startswith(\"/\")then\ne=e:sub(2)end\nlocal t=\"\"if r:len()>0 then\nt,stars=r:gsub(\"%*\",\"\")if stars==0 then\ne=path.getname(e)end\nelse\ne=path.getname(e)end\nn=path.join(t,e)end\nend\nend\nlocal e\nrepeat\ne=true\nif n:startswith(\"./\")then\nn=n:sub(3)elseif n:startswith(\"../\")then\nn=n:sub(4)else\ne=false\nend\nuntil not e\nreturn n\nend\nfunction premake.hascppproject(e)for e in premake.solution.eachproject(e)do\nif premake.iscppproject(e)then\nreturn true\nend\nend\nend\nfunction premake.hasdotnetproject(e)for e in premake.solution.eachproject(e)do\nif premake.isdotnetproject(e)then\nreturn true\nend\nend\nend\nfunction premake.project.iscproject(e)return e.language==\"C\"end\nfunction premake.iscppproject(e)return(e.language==\"C\"or e.language==\"C++\")end\nfunction premake.isdotnetproject(" + "e)return(e.language==\"C#\")end", + + /* base/config.lua */ + "premake.config={}local i=premake.config\nfunction premake.config.isdebugbuild(e)if e.flags.Optimize or e.flags.OptimizeSize or e.flags.OptimizeSpeed then\nreturn false\nend\nif not e.flags.Symbols then\nreturn false\nend\nreturn true\nend\nfunction premake.config.isincrementallink(e)if e.kind==\"StaticLib\"or i.isoptimizedbuild(e.flags)or e.flags.NoIncrementalLink then\nreturn false\nend\nreturn true\nend\nfunction premake.config.isoptimizedbuild(e)return e.Optimize or e.OptimizeSize or e.OptimizeSpeed\nend", + + /* base/bake.lua */ + "premake.bake={}local p=premake.bake\nlocal l={blocks=true,keywords=true,projects=true,__configs=true,}local e={makesettings=true,}local a={basedir=true,location=true,}function premake.getactiveterms()local e={_action=_ACTION:lower(),os=os.get()}for o,n in pairs(_OPTIONS)do\nif n~=\"\"then\ntable.insert(e,n:lower())else\ntable.insert(e,o:lower())end\nend\nreturn e\nend\nfunction premake.iskeywordmatch(e,n)if e:startswith(\"not \")then\nreturn not premake.iskeywordmatch(e:sub(5),n)end\nfor e,o in ipairs(e:explode(\" or \"))do\nfor n,e in pairs(n)do\nif e:match(o)==e then\nreturn n\nend\nend\nend\nend\nfunction premake.iskeywordsmatch(o,e)local n=false\nfor i,o in ipairs(o)do\nlocal e=premake.iskeywordmatch(o,e)if not e then\nreturn false\nend\nif e==\"required\"then\nn=true\nend\nend\nif e.required and not n then\nreturn false\nelse\nreturn true\nend\nend\nlocal function d(r,i)function adjustpathlist(e)for n,o in ipairs(e)do\ne[n]=path.getrelative(r,o)end\nend\nfor o,n in pairs(i)do\nlocal e=premake.fields[o]if " + "e and n and not a[o]then\nif e.kind==\"path\"then\ni[o]=path.getrelative(r,n)elseif e.kind==\"dirlist\"or e.kind==\"filelist\"then\nadjustpathlist(n)elseif e.kind==\"keypath\"then\nfor n,e in pairs(n)do\nadjustpathlist(e)end\nend\nend\nend\nend\nlocal function t(o,e,n)local e=e or{}if o==\"keyvalue\"or o==\"keypath\"then\nfor n,o in pairs(n)do\ne[n]=t(\"list\",e[n],o)end\nelse\nfor o,n in ipairs(n)do\nif not e[n]then\ntable.insert(e,n)e[n]=n\nend\nend\nend\nreturn e\nend\nlocal function r(o,e)if not e then\nreturn\nend\nfor e,n in pairs(e)do\nif not l[e]then\nlocal i=premake.fields[e]if i then\nif type(n)==\"table\"then\no[e]=t(i.kind,o[e],n)else\no[e]=n\nend\nelse\no[e]=n\nend\nend\nend\nend\nlocal function l(s,t,l,n,a,o)local i=a or\"\"o=o or\"Native\"if o~=\"Native\"then\ni=i..o\nend\nn.config=(a or\"\"):lower()n.platform=o:lower()local e={}r(e,l[i])d(t.location,e)r(e,t)if(e.kind)then\nn['kind']=e.kind:lower()end\nfor i,o in ipairs(t.blocks)do\nif(premake.iskeywordsmatch(o.keywords,n))then\nr(e,o)if(e.kind " + "and not e.terms.kind)then\ne.terms['kind']=e.kind:lower()n['kind']=e.kind:lower()end\nend\nend\ne.name=a\ne.platform=o\nfor o,n in pairs(n)do\ne.terms[o]=n\nend\ns[i]=e\nend\nlocal function c(n,e)local o={}e=e or{}local r=n.solution or n\nlocal t=premake.getactiveterms()l(o,n,e,t)for i,a in ipairs(r.configurations)do\nlocal i={}for n,e in pairs(t)do i[n]=e end\nl(o,n,e,i,a,\"Native\")for t,r in ipairs(r.platforms or{})do\nif r~=\"Native\"then\nl(o,n,e,i,a,r)end\nend\nend\nreturn o\nend\nlocal function k()local r=4\nlocal i={}local o={}for e in premake.solution.each()do\nfor n,e in ipairs(e.projects)do\nfor n,e in pairs(e.__configs)do\nlocal n={}n[1]=path.getabsolute(path.join(e.location,e.objdir or e.project.objdir or\"obj\"))n[2]=path.join(n[1],iif(e.platform==\"Native\",\"\",e.platform))n[3]=path.join(n[2],e.name)n[4]=path.join(n[3],e.project.name)i[e]=n\nlocal e=iif(e.name,2,1)for e=e,r do\nlocal e=n[e]o[e]=(o[e]or 0)+1\nend\nend\nend\nend\nfor e in premake.solution.each()do\nfor n,e in ipairs(e.projects)do" + "\nfor n,e in pairs(e.__configs)do\nlocal n\nlocal t=iif(e.name,2,1)for r=t,r do\nn=i[e][r]if o[n]==1 then break end\nend\ne.objectsdir=path.getrelative(e.location,n)end\nend\nend\nend\nlocal function h()for e in premake.solution.each()do\nfor n,e in ipairs(e.projects)do\nfor n,e in pairs(e.__configs)do\nlocal n=premake.getpathstyle(e)local o=premake.getnamestyle(e)e.buildtarget=premake.gettarget(e,\"build\",n,o,e.system)e.linktarget=premake.gettarget(e,\"link\",n,o,e.system)if n==\"windows\"then\ne.objectsdir=path.translate(e.objectsdir,\"\\\\\")end\nend\nend\nend\nend\nlocal function s(e)if(e.kind)then\nreturn e.kind;end\nif(e.project.__configs[\"\"]and e.project.__configs[\"\"].kind)then\nreturn e.project.__configs[\"\"].kind;end\nreturn nil\nend\nlocal function t(d,r,n,a,i,l)if(not n)then return end\nlocal f={};for o,e in ipairs(n[i])do\nlocal e=e:lower();if((not r[e]))then\nlocal i=nil;local o=nil;for r,n in ipairs(n.project.solution.projects)do\nif(n.name:lower()==e)then\nif(n.usage)then\no=n;else\ni=n;en" + "d\nend\nend\nif(o)then\nr[e]=true;local n={name=e,proj=i,usageProj=o,bLinkageOnly=l,};d[e]=n;table.insert(f,o);end\nend\nend\nfor n,e in ipairs(f)do\nif((i~=\"links\")or(s(e.__configs[a])==\"StaticLib\"))then\nt(d,r,e.__configs[a],a,i,l);end\nend\nend\nlocal function f(i,o)local e={};local n={};n[i.project.name:lower()]=true;t(e,n,i,o,\"uses\",false);local i={};for r,e in pairs(e)do\nt(i,n,e.usageProj.__configs[o],o,\"links\",true);end\nfor o,n in pairs(i)do\ne[o]=n;end\nreturn e;end\nlocal function l(n,e)local o=n.project.solution;local n=e:lower();for o,e in ipairs(o.projects)do\nif(e.name:lower()==n)then\nreturn true;end\nend\nreturn false;end\nlocal function t(n,o,e)local r=premake.fields[e];local i=e;if type(n[e])==\"table\"then\nif(r.kind==\"dirlist\"or r.kind==\"filelist\")and(not a[e])then\nfor r,e in ipairs(n[e])do\ntable.insert(o[i],path.rebase(e,n.project.location,o.project.location))end\nelse\nif(e==\"links\")then\nfor r,e in ipairs(n[e])do\nif(not l(o,e))then\ntable.insert(o[i],e)else\nprintf(\"Fa" + "iled to copy '%s' from proj '%s'.\",e,n.project.name);end\nend\nelse\nfor n,e in ipairs(n[e])do\ntable.insert(o[i],e)end\nend\nend\nelse\nif(r.kind==\"path\"and(not a[e]))then\no[i]=path.rebase(n[e],prj.location,o.project.location);else\no[i]=n[e];end\nend\nend\nlocal function l(n,i,e)local o=n.project;local r=(s(n)==\"StaticLib\");for o,e in pairs(e)do\nlocal o=e.usageProj;local i=o.__configs[i];for o,a in pairs(premake.fields)do\nif(i[o])then\nif(a.usagecopy)then\nif(not e.bLinkageOnly)then\nt(i,n,o)end\nelseif(a.linkagecopy)then\nif((not r)and(not e.proj))then\nt(i,n,o)end\nend\nend\nend\nif((not r)and e.proj)then\ntable.insert(n.links,e.proj.name);end\nend\nend\nfunction premake.bake.buildconfigs()for n in premake.solution.each()do\nfor o,e in ipairs(n.projects)do\ne.location=e.location or n.location or e.basedir\nd(e.location,e)for o,n in ipairs(e.blocks)do\nd(e.location,n)end\nend\nn.location=n.location or n.basedir\nend\nfor e in premake.solution.each()do\nlocal n=c(e)for o,e in ipairs(e.projects)do\ne." + "__configs=c(e,n)for o,n in pairs(e.__configs)do\np.postprocess(e,n)end\nend\nend\nfor e in premake.solution.each()do\nfor n,e in ipairs(e.projects)do\nif(not e.usage)then\nfor n,e in pairs(e.__configs)do\nlocal o=f(e,n);l(e,n,o)end\nend\nend\nend\nfor n in premake.solution.each()do\nlocal e={};for n,o in ipairs(n.projects)do\nif(o.usage)then\ntable.insert(e,1,n);end\nend\nfor o,e in ipairs(e)do\ntable.remove(n.projects,e);end\nend\nk()h(cfg)end\nfunction premake.bake.postprocess(n,e)e.project=n\ne.shortname=premake.getconfigname(e.name,e.platform,true)e.longname=premake.getconfigname(e.name,e.platform)e.location=e.location or e.basedir\nlocal n=premake.platforms[e.platform]if n.iscrosscompiler then\ne.system=e.platform\nelse\ne.system=os.get()end\nif e.kind==\"SharedLib\"and n.nosharedlibs then\ne.kind=\"StaticLib\"end\nlocal o={}for n,i in ipairs(e.files)do\nlocal n=false\nfor o,e in ipairs(e.excludes)do\nn=(i==e)if(n)then break end\nend\nif(not n)then\ntable.insert(o,i)end\nend\ne.files=o\nfor n,o in pairs(p" + "remake.fields)do\nif o.isflags then\nlocal e=e[n]for o,n in ipairs(e)do e[n]=true end\nend\nend\ne.__fileconfigs={}for n,o in ipairs(e.files)do\ne.terms.required=o:lower()local n={}for i,o in ipairs(e.project.blocks)do\nif(premake.iskeywordsmatch(o.keywords,e.terms))then\nr(n,o)end\nend\nn.name=o\ne.__fileconfigs[o]=n\ntable.insert(e.__fileconfigs,n)end\nend", + + /* base/api.lua */ + "premake.fields={basedir={kind=\"path\",scope=\"container\",},buildaction={kind=\"string\",scope=\"config\",allowed={\"Compile\",\"Copy\",\"Embed\",\"None\"}},buildoptions={kind=\"list\",scope=\"config\",},configurations={kind=\"list\",scope=\"solution\",},debugargs={kind=\"list\",scope=\"config\",},debugdir={kind=\"path\",scope=\"config\",},debugenvs={kind=\"list\",scope=\"config\",},defines={kind=\"list\",scope=\"config\",},deploymentoptions={kind=\"list\",scope=\"config\",usagecopy=true,},excludes={kind=\"filelist\",scope=\"config\",},files={kind=\"filelist\",scope=\"config\",},flags={kind=\"list\",scope=\"config\",isflags=true,usagecopy=true,allowed=function(e)local n={ATL=1,DebugEnvsDontMerge=1,DebugEnvsInherit=1,EnableSSE=1,EnableSSE2=1,ExtraWarnings=1,FatalWarnings=1,FloatFast=1,FloatStrict=1,Managed=1,MFC=1,NativeWChar=1,No64BitChecks=1,NoEditAndContinue=1,NoExceptions=1,NoFramePointer=1,NoImportLib=1,NoIncrementalLink=1,NoManifest=1,NoMinimalRebuild=1,NoNativeWChar=1,NoPCH=1,NoRTTI=1,Optimize=1,Optimiz" + "eSize=1,OptimizeSpeed=1,SEH=1,StaticATL=1,StaticRuntime=1,Symbols=1,Unicode=1,Unsafe=1,WinMain=1}local t={optimise='optimize',optimisesize='optimizesize',optimisespeed='optimizespeed',}local e=e:lower()e=t[e]or e\nfor n,t in pairs(n)do\nif n:lower()==e then\nreturn n\nend\nend\nreturn nil,\"invalid flag\"end,},framework={kind=\"string\",scope=\"container\",allowed={\"1.0\",\"1.1\",\"2.0\",\"3.0\",\"3.5\",\"4.0\",\"4.5\",}},imagepath={kind=\"path\",scope=\"config\",},imageoptions={kind=\"list\",scope=\"config\",},implibdir={kind=\"path\",scope=\"config\",},implibextension={kind=\"string\",scope=\"config\",},implibname={kind=\"string\",scope=\"config\",},implibprefix={kind=\"string\",scope=\"config\",},implibsuffix={kind=\"string\",scope=\"config\",},includedirs={kind=\"dirlist\",scope=\"config\",usagecopy=true,},kind={kind=\"string\",scope=\"config\",allowed={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"}},language={kind=\"string\",scope=\"container\",allowed={\"C\",\"C++\",\"C#\"}},libdirs={kind=" + "\"dirlist\",scope=\"config\",linkagecopy=true,},linkoptions={kind=\"list\",scope=\"config\",},links={kind=\"list\",scope=\"config\",allowed=function(e)if e:find('/',nil,true)then\ne=path.getabsolute(e)end\nreturn e\nend,linkagecopy=true,},location={kind=\"path\",scope=\"container\",},makesettings={kind=\"list\",scope=\"config\",},objdir={kind=\"path\",scope=\"config\",},pchheader={kind=\"string\",scope=\"config\",},pchsource={kind=\"path\",scope=\"config\",},platforms={kind=\"list\",scope=\"solution\",allowed=table.keys(premake.platforms),},postbuildcommands={kind=\"list\",scope=\"config\",},prebuildcommands={kind=\"list\",scope=\"config\",},prelinkcommands={kind=\"list\",scope=\"config\",},resdefines={kind=\"list\",scope=\"config\",},resincludedirs={kind=\"dirlist\",scope=\"config\",},resoptions={kind=\"list\",scope=\"config\",},targetdir={kind=\"path\",scope=\"config\",},targetextension={kind=\"string\",scope=\"config\",},targetname={kind=\"string\",scope=\"config\",},targetprefix={kind=\"string\",scope=\"co" + "nfig\",},targetsuffix={kind=\"string\",scope=\"config\",},trimpaths={kind=\"dirlist\",scope=\"config\",},uuid={kind=\"string\",scope=\"container\",allowed=function(e)local n=true\nif(#e~=36)then n=false end\nfor t=1,36 do\nlocal e=e:sub(t,t)if(not e:find(\"[ABCDEFabcdef0123456789-]\"))then n=false end\nend\nif(e:sub(9,9)~=\"-\")then n=false end\nif(e:sub(14,14)~=\"-\")then n=false end\nif(e:sub(19,19)~=\"-\")then n=false end\nif(e:sub(24,24)~=\"-\")then n=false end\nif(not n)then\nreturn nil,\"invalid UUID\"end\nreturn e:upper()end},uses={kind=\"list\",scope=\"config\",},vpaths={kind=\"keypath\",scope=\"container\",},}function premake.checkvalue(e,n)if(n)then\nif(type(n)==\"function\")then\nreturn n(e)else\nfor t,n in ipairs(n)do\nif(e:lower()==n:lower())then\nreturn n\nend\nend\nreturn nil,\"invalid value '\"..e..\"'\"end\nelse\nreturn e\nend\nend\nfunction premake.getobject(n)local e\nif(n==\"container\"or n==\"solution\")then\ne=premake.CurrentContainer\nelse\ne=premake.CurrentConfiguration\nend\nif n==\"so" + "lution\"then\nif type(e)==\"project\"then\ne=e.solution\nend\nif type(e)~=\"solution\"then\ne=nil\nend\nend\nlocal t\nif(not e)then\nif(n==\"container\")then\nt=\"no active solution or project\"elseif(n==\"solution\")then\nt=\"no active solution\"else\nt=\"no active solution, project, or configuration\"end\nend\nreturn e,t\nend\nfunction premake.setarray(e,t,a,s)local n,i=premake.getobject(e)if(not n)then\nerror(i,4)end\nif(not n[t])then\nn[t]={}end\nlocal function r(e,o)if(type(e)==\"table\")then\nfor n,e in ipairs(e)do\nr(e,o+1)end\nelse\ne,i=premake.checkvalue(e,s)if(not e)then\nerror(i,o)end\ntable.insert(n[t],e)end\nend\nif(a)then\nr(a,5)end\nreturn n[t]end\nlocal function i(i,r,o,a)local t={}function makeabsolute(e,n)if(type(e)==\"table\")then\nfor t,e in ipairs(e)do\nmakeabsolute(e,n+1)end\nelseif type(e)==\"string\"then\nif e:find(\"*\")then\nmakeabsolute(a(e),n+1)else\ntable.insert(t,path.getabsolute(e))end\nelse\nerror(\"Invalid value in list: expected string, got \"..type(e),n)end\nend\nmakeabsolute" + "(o,3)return premake.setarray(i,r,t)end\nfunction premake.setdirarray(n,e,t)return i(n,e,t,os.matchdirs)end\nfunction premake.setfilearray(t,e,n)return i(t,e,n,os.matchfiles)end\nfunction premake.setkeyvalue(e,n,t)local e,i=premake.getobject(e)if not e then\nerror(i,4)end\nif not e[n]then\ne[n]={}end\nif type(t)~=\"table\"then\nerror(\"invalid value; table expected\",4)end\nlocal e=e[n]for n,t in pairs(t)do\nif not e[n]then\ne[n]={}end\ntable.insertflat(e[n],t)end\nreturn e\nend\nfunction premake.setstring(n,i,e,r)local n,t=premake.getobject(n)if(not n)then\nerror(t,4)end\nif(e)then\ne,t=premake.checkvalue(e,r)if(not e)then\nerror(t,4)end\nn[i]=e\nend\nreturn n[i]end\nlocal function o(n,e)local t=premake.fields[n].kind\nlocal i=premake.fields[n].scope\nlocal r=premake.fields[n].allowed\nif(t==\"string\"or t==\"path\")and e then\nif type(e)~=\"string\"then\nerror(\"string value expected\",3)end\nend\nif t==\"string\"then\nreturn premake.setstring(i,n,e,r)elseif t==\"path\"then\nif e then e=path.getabsolute(e)end" + "\nreturn premake.setstring(i,n,e)elseif t==\"list\"then\nreturn premake.setarray(i,n,e,r)elseif t==\"dirlist\"then\nreturn premake.setdirarray(i,n,e)elseif t==\"filelist\"then\nreturn premake.setfilearray(i,n,e)elseif t==\"keyvalue\"or t==\"keypath\"then\nreturn premake.setkeyvalue(i,n,e)end\nend\nfor e,n in pairs(premake.fields)do\n_G[e]=function(n)return o(e,n)end\nend\nfunction configuration(t)if not t then\nreturn premake.CurrentConfiguration\nend\nlocal n,e=premake.getobject(\"container\")if(not n)then\nerror(e,2)end\nlocal e={}e.terms=table.flatten({t})table.insert(n.blocks,e)premake.CurrentConfiguration=e\ne.keywords={}for t,n in ipairs(e.terms)do\ntable.insert(e.keywords,path.wildcards(n):lower())end\nfor t,n in pairs(premake.fields)do\nif(n.kind~=\"string\"and n.kind~=\"path\")then\ne[t]={}end\nend\nreturn e\nend\nlocal function r(t,n,i)local e={}setmetatable(e,{__type=\"project\",})table.insert(n.projects,e)if(i)then\nif(n.projects[t])then\nn.projects[t].usageProj=e;else\nn.projects[t]=e\nend\nelse\n" + "if(n.projects[t])then\ne.usageProj=n.projects[t];end\nn.projects[t]=e\nend\ne.solution=n\ne.name=t\ne.basedir=os.getcwd()e.uuid=os.uuid()e.blocks={}e.usage=i;return e;end\nfunction usage(n)if(not n)then\nif(type(premake.CurrentContainer)~=\"project\")then return nil end\nif(not premake.CurrentContainer.usage)then return nil end\nreturn premake.CurrentContainer\nend\nlocal e\nif(type(premake.CurrentContainer)==\"project\")then\ne=premake.CurrentContainer.solution\nelse\ne=premake.CurrentContainer\nend\nif(type(e)~=\"solution\")then\nerror(\"no active solution\",2)end\nif((not e.projects[n])or((not e.projects[n].usage)and(not e.projects[n].usageProj)))then\npremake.CurrentContainer=r(n,e,true)else\npremake.CurrentContainer=iff(e.projects[n].usage,e.projects[n],e.projects[n].usageProj)end\nconfiguration{}return premake.CurrentContainer\nend\nfunction project(n)if(not n)then\nif(type(premake.CurrentContainer)~=\"project\")then return nil end\nif(premake.CurrentContainer.usage)then return nil end\nreturn premake.Cu" + "rrentContainer\nend\nlocal e\nif(type(premake.CurrentContainer)==\"project\")then\ne=premake.CurrentContainer.solution\nelse\ne=premake.CurrentContainer\nend\nif(type(e)~=\"solution\")then\nerror(\"no active solution\",2)end\nif((not e.projects[n])or e.projects[n].usage)then\npremake.CurrentContainer=r(n,e)else\npremake.CurrentContainer=e.projects[n];end\nconfiguration{}return premake.CurrentContainer\nend\nfunction solution(e)if not e then\nif type(premake.CurrentContainer)==\"project\"then\nreturn premake.CurrentContainer.solution\nelse\nreturn premake.CurrentContainer\nend\nend\npremake.CurrentContainer=premake.solution.get(e)if(not premake.CurrentContainer)then\npremake.CurrentContainer=premake.solution.new(e)end\nconfiguration{}return premake.CurrentContainer\nend\nfunction newaction(e)premake.action.add(e)end\nfunction newoption(e)premake.option.add(e)end", + + /* base/cmdline.lua */ + "newoption{trigger=\"cc\",value=\"VALUE\",description=\"Choose a C/C++ compiler set\",allowed={{\"gcc\",\"GNU GCC (gcc/g++)\"},{\"ow\",\"OpenWatcom\"},}}newoption{trigger=\"dotnet\",value=\"VALUE\",description=\"Choose a .NET compiler set\",allowed={{\"msnet\",\"Microsoft .NET (csc)\"},{\"mono\",\"Novell Mono (mcs)\"},{\"pnet\",\"Portable.NET (cscc)\"},}}newoption{trigger=\"file\",value=\"FILE\",description=\"Read FILE as a Premake script; default is 'premake4.lua'\"}newoption{trigger=\"help\",description=\"Display this information\"}newoption{trigger=\"os\",value=\"VALUE\",description=\"Generate files for a different operating system\",allowed={{\"bsd\",\"OpenBSD, NetBSD, or FreeBSD\"},{\"haiku\",\"Haiku\"},{\"linux\",\"Linux\"},{\"macosx\",\"Apple Mac OS X\"},{\"solaris\",\"Solaris\"},{\"windows\",\"Microsoft Windows\"},}}newoption{trigger=\"platform\",value=\"VALUE\",description=\"Add target architecture (if supported by action)\",allowed={{\"x32\",\"32-bit\"},{\"x64\",\"64-bit\"},{\"universal\",\"Mac OS X U" + "niversal, 32- and 64-bit\"},{\"universal32\",\"Mac OS X Universal, 32-bit only\"},{\"universal64\",\"Mac OS X Universal, 64-bit only\"},{\"ps3\",\"Playstation 3 (experimental)\"},{\"xbox360\",\"Xbox 360 (experimental)\"},}}newoption{trigger=\"scripts\",value=\"path\",description=\"Search for additional scripts on the given path\"}newoption{trigger=\"version\",description=\"Display version information\"}newoption{trigger=\"generate_user\",description=\"Generate (and remove when cleaning) .user VStudio files\"}", + + /* tools/dotnet.lua */ + "premake.dotnet={}premake.dotnet.namestyle=\"windows\"local t={FatalWarning=\"/warnaserror\",Optimize=\"/optimize\",OptimizeSize=\"/optimize\",OptimizeSpeed=\"/optimize\",Symbols=\"/debug\",Unsafe=\"/unsafe\"}function premake.dotnet.getbuildaction(e)local n=path.getextension(e.name):lower()if e.buildaction==\"Compile\"or n==\".cs\"then\nreturn\"Compile\"elseif e.buildaction==\"Embed\"or n==\".resx\"then\nreturn\"EmbeddedResource\"elseif e.buildaction==\"Copy\"or n==\".asax\"or n==\".aspx\"then\nreturn\"Content\"elseif e.buildaction==\"Page\"or n==\".xaml\"then\nif(path.getname(e.name)==\"App.xaml\")then\nreturn\"ApplicationDefinition\"else\nreturn\"Page\"end\nelse\nreturn\"None\"end\nend\nfunction premake.dotnet.getcompilervar(e)if(_OPTIONS.dotnet==\"msnet\")then\nreturn\"csc\"elseif(_OPTIONS.dotnet==\"mono\")then\nif(e.framework<=\"1.1\")then\nreturn\"mcs\"elseif(e.framework>=\"4.0\")then\nreturn\"dmcs\"else\nreturn\"gmcs\"end\nelse\nreturn\"cscc\"end\nend\nfunction premake.dotnet.getflags(e)local e=table.tran" + "slate(e.flags,t)return e\nend\nfunction premake.dotnet.getkind(e)if(e.kind==\"ConsoleApp\")then\nreturn\"Exe\"elseif(e.kind==\"WindowedApp\")then\nreturn\"WinExe\"elseif(e.kind==\"SharedLib\")then\nreturn\"Library\"end\nend", + + /* tools/gcc.lua */ + "premake.gcc={}premake.gcc.cc=\"gcc\"premake.gcc.cxx=\"g++\"premake.gcc.ar=\"ar\"local n={EnableSSE=\"-msse\",EnableSSE2=\"-msse2\",ExtraWarnings=\"-Wall -Wextra\",FatalWarnings=\"-Werror\",FloatFast=\"-ffast-math\",FloatStrict=\"-ffloat-store\",NoFramePointer=\"-fomit-frame-pointer\",Optimize=\"-O2\",OptimizeSize=\"-Os\",OptimizeSpeed=\"-O3\",Symbols=\"-g\",}local l={NoExceptions=\"-fno-exceptions\",NoRTTI=\"-fno-rtti\",}premake.gcc.platforms={Native={cppflags=\"-MMD\",},x32={cppflags=\"-MMD\",flags=\"-m32\",ldflags=\"-L/usr/lib32\",},x64={cppflags=\"-MMD\",flags=\"-m64\",ldflags=\"-L/usr/lib64\",},Universal={cppflags=\"\",flags=\"-arch i386 -arch x86_64 -arch ppc -arch ppc64\",},Universal32={cppflags=\"\",flags=\"-arch i386 -arch ppc\",},Universal64={cppflags=\"\",flags=\"-arch x86_64 -arch ppc64\",},PS3={cc=\"ppu-lv2-g++\",cxx=\"ppu-lv2-g++\",ar=\"ppu-lv2-ar\",cppflags=\"-MMD\",},WiiDev={cppflags=\"-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)\",ldflags=\"-L$(LIBOGC_LIB) $(MACHDEP)\",cfgsettings=[[\n ifeq ($(strip $(" + "DEVKITPPC)),)\n $(error \"DEVKITPPC environment variable is not set\")'\n endif\n include $(DEVKITPPC)/wii_rules']],},}local t=premake.gcc.platforms\nfunction premake.gcc.getcppflags(a)local e={}table.insert(e,t[a.platform].cppflags)if e[1]:startswith(\"-MMD\")and a.system~=\"haiku\"then\ntable.insert(e,\"-MP\")end\nreturn e\nend\nfunction premake.gcc.getcflags(e)local a=table.translate(e.flags,n)table.insert(a,t[e.platform].flags)if e.system~=\"windows\"and e.kind==\"SharedLib\"then\ntable.insert(a,\"-fPIC\")end\nreturn a\nend\nfunction premake.gcc.getcxxflags(e)local e=table.translate(e.flags,l)return e\nend\nfunction premake.gcc.getldflags(e)local a={}if not e.flags.Symbols then\nif e.system==\"macosx\"then\ntable.insert(a,\"-Wl,-x\")else\ntable.insert(a,\"-s\")end\nend\nif e.kind==\"SharedLib\"then\nif e.system==\"macosx\"then\ntable.insert(a,\"-dynamiclib\")else\ntable.insert(a,\"-shared\")end\nif e.system==\"windows\"and not e.flags.NoImportLib then\ntable.insert(a,'-Wl,--out-implib=\"'..e.linktarge" + "t.fullpath..'\"')end\nend\nif e.kind==\"WindowedApp\"and e.system==\"windows\"then\ntable.insert(a,\"-mwindows\")end\nlocal e=t[e.platform]table.insert(a,e.flags)table.insert(a,e.ldflags)return a\nend\nfunction premake.gcc.getlibdirflags(a)local e={}for t,a in ipairs(premake.getlinks(a,\"all\",\"directory\"))do\ntable.insert(e,'-L'.._MAKE.esc(a))end\nreturn e\nend\nfunction premake.gcc.getlinkflags(a)local e={}for t,a in ipairs(premake.getlinks(a,\"system\",\"name\"))do\nif path.getextension(a)==\".framework\"then\ntable.insert(e,'-framework '.._MAKE.esc(path.getbasename(a)))else\ntable.insert(e,'-l'.._MAKE.esc(a))end\nend\nreturn e\nend\nfunction premake.gcc.getdefines(a)local e={}for t,a in ipairs(a)do\ntable.insert(e,'-D'..a)end\nreturn e\nend\nfunction premake.gcc.getincludedirs(a)local e={}for t,a in ipairs(a)do\ntable.insert(e,\"-I\".._MAKE.esc(a))end\nreturn e\nend\nfunction premake.gcc.getcfgsettings(e)return t[e.platform].cfgsettings\nend", + + /* tools/msc.lua */ + "premake.msc={}premake.msc.namestyle=\"windows\"", + + /* tools/ow.lua */ + "premake.ow={}premake.ow.namestyle=\"windows\"premake.ow.cc=\"WCL386\"premake.ow.cxx=\"WCL386\"premake.ow.ar=\"ar\"local e={ExtraWarnings=\"-wx\",FatalWarning=\"-we\",FloatFast=\"-omn\",FloatStrict=\"-op\",Optimize=\"-ox\",OptimizeSize=\"-os\",OptimizeSpeed=\"-ot\",Symbols=\"-d2\",}local n={NoExceptions=\"-xd\",NoRTTI=\"-xr\",}premake.ow.platforms={Native={flags=\"\"},}function premake.ow.getcppflags(e)return{}end\nfunction premake.ow.getcflags(a)local e=table.translate(a.flags,e)if(a.flags.Symbols)then\ntable.insert(e,\"-hw\")end\nreturn e\nend\nfunction premake.ow.getcxxflags(e)local e=table.translate(e.flags,n)return e\nend\nfunction premake.ow.getldflags(a)local e={}if(a.flags.Symbols)then\ntable.insert(e,\"op symf\")end\nreturn e\nend\nfunction premake.ow.getlinkflags(e)local e={}return e\nend\nfunction premake.ow.getdefines(a)local e={}for n,a in ipairs(a)do\ntable.insert(e,'-D'..a)end\nreturn e\nend\nfunction premake.ow.getincludedirs(a)local e={}for n,a in ipairs(a)do\ntable.insert(e,'-I \"'..a..'\"')en" + "d\nreturn e\nend", + + /* tools/snc.lua */ + "premake.snc={}premake.snc.cc=\"snc\"premake.snc.cxx=\"g++\"premake.snc.ar=\"ar\"local n={ExtraWarnings=\"-Xdiag=2\",FatalWarnings=\"-Xquit=2\",}local t={NoExceptions=\"\",NoRTTI=\"-Xc-=rtti\",}premake.snc.platforms={PS3={cc=\"ppu-lv2-g++\",cxx=\"ppu-lv2-g++\",ar=\"ppu-lv2-ar\",cppflags=\"-MMD -MP\",}}local a=premake.snc.platforms\nfunction premake.snc.getcppflags(n)local e={}table.insert(e,a[n.platform].cppflags)return e\nend\nfunction premake.snc.getcflags(e)local n=table.translate(e.flags,n)table.insert(n,a[e.platform].flags)if e.kind==\"SharedLib\"then\ntable.insert(n,\"-fPIC\")end\nreturn n\nend\nfunction premake.snc.getcxxflags(e)local e=table.translate(e.flags,t)return e\nend\nfunction premake.snc.getldflags(n)local e={}if not n.flags.Symbols then\ntable.insert(e,\"-s\")end\nif n.kind==\"SharedLib\"then\ntable.insert(e,\"-shared\")if not n.flags.NoImportLib then\ntable.insert(e,'-Wl,--out-implib=\"'..n.linktarget.fullpath..'\"')end\nend\nlocal n=a[n.platform]table.insert(e,n.flags)table.insert(e,n.ldflag" + "s)return e\nend\nfunction premake.snc.getlibdirflags(n)local e={}for a,n in ipairs(premake.getlinks(n,\"all\",\"directory\"))do\ntable.insert(e,'-L'.._MAKE.esc(n))end\nreturn e\nend\nfunction premake.snc.getlinkflags(n)local e={}for a,n in ipairs(premake.getlinks(n,\"system\",\"name\"))do\ntable.insert(e,'-l'.._MAKE.esc(n))end\nreturn e\nend\nfunction premake.snc.getdefines(n)local e={}for a,n in ipairs(n)do\ntable.insert(e,'-D'..n)end\nreturn e\nend\nfunction premake.snc.getincludedirs(n)local e={}for a,n in ipairs(n)do\ntable.insert(e,\"-I\".._MAKE.esc(n))end\nreturn e\nend", + + /* base/validate.lua */ + "function premake.checkprojects()local n=premake.action.current()for e in premake.solution.each()do\nif(#e.projects==0)then\nreturn nil,\"solution '\"..e.name..\"' needs at least one project\"end\nif(#e.configurations==0)then\nreturn nil,\"solution '\"..e.name..\"' needs configurations\"end\nfor e in premake.solution.eachproject(e)do\nif(not e.language)then\nreturn nil,\"project '\"..e.name..\"' needs a language\"end\nif(n.valid_languages)then\nif(not table.contains(n.valid_languages,e.language))then\nreturn nil,\"the \"..n.shortname..\" action does not support \"..e.language..\" projects\"end\nend\nfor t in premake.eachconfig(e)do\nif(not t.kind)then\nreturn nil,\"project '\"..e.name..\"' needs a kind in configuration '\"..t.name..\"'\"end\nif(n.valid_kinds)then\nif(not table.contains(n.valid_kinds,t.kind))then\nreturn nil,\"the \"..n.shortname..\" action does not support \"..t.kind..\" projects\"end\nend\nend\nif n.oncheckproject then\nn.oncheckproject(e)end\nend\nend\nreturn true\nend\nfunction premake.check" + "tools()local e=premake.action.current()if(not e.valid_tools)then\nreturn true\nend\nfor n,t in pairs(e.valid_tools)do\nif(_OPTIONS[n])then\nif(not table.contains(t,_OPTIONS[n]))then\nreturn nil,\"the \"..e.shortname..\" action does not support /\"..n..\"=\".._OPTIONS[n]..\" (yet)\"end\nelse\n_OPTIONS[n]=t[1]end\nend\nreturn true\nend", + + /* base/help.lua */ + "function premake.showhelp()printf(\"Premake %s, a build script generator\",_PREMAKE_VERSION)printf(_PREMAKE_COPYRIGHT)printf(\"%s %s\",_VERSION,_COPYRIGHT)printf(\"\")printf(\"Usage: premake4 [options] action [arguments]\")printf(\"\")printf(\"OPTIONS\")printf(\"\")for n in premake.option.each()do\nlocal i=n.trigger\nlocal e=n.description\nif(n.value)then i=i..\"=\"..n.value end\nif(n.allowed)then e=e..\"; one of:\"end\nprintf(\" --%-15s %s\",i,e)if(n.allowed)then\nfor i,n in ipairs(n.allowed)do\nprintf(\" %-14s %s\",n[1],n[2])end\nend\nprintf(\"\")end\nprintf(\"ACTIONS\")printf(\"\")for n in premake.action.each()do\nprintf(\" %-17s %s\",n.trigger,n.description)end\nprintf(\"\")printf(\"For additional information, see http://industriousone.com/premake\")end", + + /* base/premake.lua */ + "function premake.generate(n,e,t)e=premake.project.getfilename(n,e)printf(\"Generating %s...\",e)local e,o=io.open(e,\"wb\")if(not e)then\nerror(o,0)end\nio.output(e)t(n)e:close()end", + + /* actions/codeblocks/_codeblocks.lua */ + "premake.codeblocks={}newaction{trigger=\"codeblocks\",shortname=\"Code::Blocks\",description=\"Generate Code::Blocks project files\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\"},valid_tools={cc={\"gcc\",\"ow\"},},onsolution=function(e)premake.generate(e,\"%%.workspace\",premake.codeblocks.workspace)end,onproject=function(e)premake.generate(e,\"%%.cbp\",premake.codeblocks.cbp)end,oncleansolution=function(e)premake.clean.file(e,\"%%.workspace\")end,oncleanproject=function(e)premake.clean.file(e,\"%%.cbp\")premake.clean.file(e,\"%%.depend\")premake.clean.file(e,\"%%.layout\")end}", + + /* actions/codeblocks/codeblocks_workspace.lua */ + "function premake.codeblocks.workspace(e)_p('<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>')_p('<CodeBlocks_workspace_file>')_p(1,'<Workspace title=\"%s\">',e.name)for o in premake.solution.eachproject(e)do\nlocal p=path.join(path.getrelative(e.location,o.location),o.name)local a=iif(o.project==e.projects[1],' active=\"1\"','')_p(2,'<Project filename=\"%s.cbp\"%s>',p,a)for a,o in ipairs(premake.getdependencies(o))do\n_p(3,'<Depends filename=\"%s.cbp\" />',path.join(path.getrelative(e.location,o.location),o.name))end\n_p(2,'</Project>')end\n_p(1,'</Workspace>')_p('</CodeBlocks_workspace_file>')end", + + /* actions/codeblocks/codeblocks_cbp.lua */ + "local p=premake.codeblocks\nfunction p.files(e)local o\nif(e.pchheader)then\no=path.getrelative(e.location,e.pchheader)end\nfor i in premake.project.eachfile(e)do\n_p(2,'<Unit filename=\"%s\">',premake.esc(i.name))if i.name~=i.vpath then\n_p(3,'<Option virtualFolder=\"%s\" />',path.getdirectory(i.vpath))end\nif path.isresourcefile(i.name)then\n_p(3,'<Option compilerVar=\"WINDRES\" />')elseif path.iscfile(i.name)and e.language==\"C++\"then\n_p(3,'<Option compilerVar=\"CC\" />')end\nif not e.flags.NoPCH and i.name==o then\n_p(3,'<Option compilerVar=\"%s\" />',iif(e.language==\"C\",\"CC\",\"CPP\"))_p(3,'<Option compile=\"1\" />')_p(3,'<Option weight=\"0\" />')_p(3,'<Add option=\"-x c++-header\" />')end\n_p(2,'</Unit>')end\nend\nfunction premake.codeblocks.debugenvs(i)if premake.gettool(i)==premake.gcc then\n_p(3,'<debugger>')_p(4,'<remote_debugging target=\"%s\">',premake.esc(i.longname))local e=''local n=#i.debugenvs\nfor o,i in ipairs(i.debugenvs)do\ne=e..'set env '..i\nif n~=o then e=e..'
'end\nend\n_p(5," + "'<options additional_cmds_before=\"%s\" />',e)_p(4,'</remote_debugging>')_p(3,'</debugger>')else\nerror('Sorry at this moment there is no support for debug environment variables with this debugger and codeblocks')end\nend\nfunction premake.codeblocks.cbp(i)local o=premake.gettool(i)_p('<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>')_p('<CodeBlocks_project_file>')_p(1,'<FileVersion major=\"1\" minor=\"6\" />')_p(1,'<Project>')_p(2,'<Option title=\"%s\" />',premake.esc(i.name))_p(2,'<Option pch_mode=\"2\" />')_p(2,'<Option compiler=\"%s\" />',_OPTIONS.cc)local n=premake.filterplatforms(i.solution,o.platforms,\"Native\")for e=#n,1,-1 do\nif premake.platforms[n[e]].iscrosscompiler then\ntable.remove(n,e)end\nend\n_p(2,'<Build>')for n,e in ipairs(n)do\nfor e in premake.eachconfig(i,e)do\n_p(3,'<Target title=\"%s\">',premake.esc(e.longname))_p(4,'<Option output=\"%s\" prefix_auto=\"0\" extension_auto=\"0\" />',premake.esc(e.buildtarget.fullpath))if e.debugdir then\n_p(4,'<Option working_dir=\"%s\" /" + ">',premake.esc(e.debugdir))end\n_p(4,'<Option object_output=\"%s\" />',premake.esc(e.objectsdir))local i={WindowedApp=0,ConsoleApp=1,StaticLib=2,SharedLib=3}_p(4,'<Option type=\"%d\" />',i[e.kind])_p(4,'<Option compiler=\"%s\" />',_OPTIONS.cc)if(e.kind==\"SharedLib\")then\n_p(4,'<Option createDefFile=\"0\" />')_p(4,'<Option createStaticLib=\"%s\" />',iif(e.flags.NoImportLib,0,1))end\n_p(4,'<Compiler>')for i,e in ipairs(table.join(o.getcflags(e),o.getcxxflags(e),o.getdefines(e.defines),e.buildoptions))do\n_p(5,'<Add option=\"%s\" />',premake.esc(e))end\nif not e.flags.NoPCH and e.pchheader then\n_p(5,'<Add option=\"-Winvalid-pch\" />')_p(5,'<Add option=\"-include "%s"\" />',premake.esc(e.pchheader))end\nfor i,e in ipairs(e.includedirs)do\n_p(5,'<Add directory=\"%s\" />',premake.esc(e))end\n_p(4,'</Compiler>')_p(4,'<Linker>')for i,e in ipairs(table.join(o.getldflags(e),e.linkoptions))do\n_p(5,'<Add option=\"%s\" />',premake.esc(e))end\nfor i,e in ipairs(premake.getlinks(e,\"all\",\"directory\"))do\n_p(" + "5,'<Add directory=\"%s\" />',premake.esc(e))end\nfor i,e in ipairs(premake.getlinks(e,\"all\",\"basename\"))do\n_p(5,'<Add library=\"%s\" />',premake.esc(e))end\n_p(4,'</Linker>')if premake.findfile(e,\".rc\")then\n_p(4,'<ResourceCompiler>')for i,e in ipairs(e.includedirs)do\n_p(5,'<Add directory=\"%s\" />',premake.esc(e))end\nfor i,e in ipairs(e.resincludedirs)do\n_p(5,'<Add directory=\"%s\" />',premake.esc(e))end\n_p(4,'</ResourceCompiler>')end\nif#e.prebuildcommands>0 or#e.postbuildcommands>0 then\n_p(4,'<ExtraCommands>')for i,e in ipairs(e.prebuildcommands)do\n_p(5,'<Add before=\"%s\" />',premake.esc(e))end\nfor i,e in ipairs(e.postbuildcommands)do\n_p(5,'<Add after=\"%s\" />',premake.esc(e))end\n_p(4,'</ExtraCommands>')end\n_p(3,'</Target>')end\nend\n_p(2,'</Build>')p.files(i)_p(2,'<Extensions>')for o,e in ipairs(n)do\nfor e in premake.eachconfig(i,e)do\nif e.debugenvs and#e.debugenvs>0 then\npremake.codeblocks.debugenvs(e)end\nend\nend\n_p(2,'</Extensions>')_p(1,'</Project>')_p('</CodeBlocks_project_file" + ">')_p('')end", + + /* actions/codelite/_codelite.lua */ + "premake.codelite={}newaction{trigger=\"codelite\",shortname=\"CodeLite\",description=\"Generate CodeLite project files\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\"},valid_tools={cc={\"gcc\"},},onsolution=function(e)premake.generate(e,\"%%.workspace\",premake.codelite.workspace)end,onproject=function(e)premake.generate(e,\"%%.project\",premake.codelite.project)end,oncleansolution=function(e)premake.clean.file(e,\"%%.workspace\")premake.clean.file(e,\"%%_wsp.mk\")premake.clean.file(e,\"%%.tags\")end,oncleanproject=function(e)premake.clean.file(e,\"%%.project\")premake.clean.file(e,\"%%.mk\")premake.clean.file(e,\"%%.list\")premake.clean.file(e,\"%%.out\")end}", + + /* actions/codelite/codelite_workspace.lua */ + "function premake.codelite.workspace(e)_p('<?xml version=\"1.0\" encoding=\"utf-8\"?>')_p('<CodeLite_Workspace Name=\"%s\" Database=\"./%s.tags\">',premake.esc(e.name),premake.esc(e.name))for o,a in ipairs(e.projects)do\nlocal i=premake.esc(a.name)local a=path.join(path.getrelative(e.location,a.location),a.name)local e=iif(o==1,\"Yes\",\"No\")_p(' <Project Name=\"%s\" Path=\"%s.project\" Active=\"%s\" />',i,a,e)end\nlocal a=premake.filterplatforms(e,premake[_OPTIONS.cc].platforms,\"Native\")for e=#a,1,-1 do\nif premake.platforms[a[e]].iscrosscompiler then\ntable.remove(a,e)end\nend\n_p(' <BuildMatrix>')for a,o in ipairs(a)do\nfor i,a in ipairs(e.configurations)do\nlocal a=premake.getconfigname(a,o):gsub(\"|\",\"_\")_p(' <WorkspaceConfiguration Name=\"%s\" Selected=\"yes\">',a)for o,e in ipairs(e.projects)do\n_p(' <Project Name=\"%s\" ConfigName=\"%s\"/>',e.name,a)end\n_p(' </WorkspaceConfiguration>')end\nend\n_p(' </BuildMatrix>')_p('</CodeLite_Workspace>')end", + + /* actions/codelite/codelite_project.lua */ + "local e=premake.codelite\nlocal i=premake.tree\nfunction e.files(e)local e=premake.project.buildsourcetree(e)i.traverse(e,{onbranchenter=function(i,e)_p(e,'<VirtualDirectory Name=\"%s\">',i.name)end,onbranchexit=function(i,e)_p(e,'</VirtualDirectory>')end,onleaf=function(i,e)_p(e,'<File Name=\"%s\"/>',i.cfg.name)end,},true,1)end\nfunction premake.codelite.project(i)io.indent=\" \"_p('<?xml version=\"1.0\" encoding=\"utf-8\"?>')_p('<CodeLite_Project Name=\"%s\">',premake.esc(i.name))e.files(i)local n={ConsoleApp=\"Executable\",WindowedApp=\"Executable\",StaticLib=\"Static Library\",SharedLib=\"Dynamic Library\",}_p(' <Settings Type=\"%s\">',n[i.kind])local o=premake.filterplatforms(i.solution,premake[_OPTIONS.cc].platforms,\"Native\")for e=#o,1,-1 do\nif premake.platforms[o[e]].iscrosscompiler then\ntable.remove(o,e)end\nend\nfor o,e in ipairs(o)do\nfor e in premake.eachconfig(i,e)do\nlocal o=premake.esc(e.longname):gsub(\"|\",\"_\")local i=iif(e.language==\"C\",\"gcc\",\"g++\")_p(' <Configuration Name=\"%" + "s\" CompilerType=\"gnu %s\" DebuggerType=\"GNU gdb debugger\" Type=\"%s\">',o,i,n[e.kind])local r=premake.esc(e.buildtarget.fullpath)local l=premake.esc(e.objectsdir)local n=e.buildtarget.name\nlocal o=e.debugdir or e.buildtarget.directory\nlocal i=table.concat(e.debugargs,\" \")local a=iif(e.kind==\"WindowedApp\",\"no\",\"yes\")_p(' <General OutputFile=\"%s\" IntermediateDirectory=\"%s\" Command=\"./%s\" CommandArguments=\"%s\" WorkingDirectory=\"%s\" PauseExecWhenProcTerminates=\"%s\"/>',r,l,n,i,o,a)local i=premake.esc(table.join(premake.gcc.getcflags(e),premake.gcc.getcxxflags(e),e.buildoptions))_p(' <Compiler Required=\"yes\" Options=\"%s\">',table.concat(i,\";\"))for i,e in ipairs(e.includedirs)do\n_p(' <IncludePath Value=\"%s\"/>',premake.esc(e))end\nfor i,e in ipairs(e.defines)do\n_p(' <Preprocessor Value=\"%s\"/>',premake.esc(e))end\n_p(' </Compiler>')i=premake.esc(table.join(premake.gcc.getldflags(e),e.linkoptions))_p(' <Linker Required=\"yes\" Options=\"%s\">',table." + "concat(i,\";\"))for i,e in ipairs(premake.getlinks(e,\"all\",\"directory\"))do\n_p(' <LibraryPath Value=\"%s\" />',premake.esc(e))end\nfor i,e in ipairs(premake.getlinks(e,\"siblings\",\"basename\"))do\n_p(' <Library Value=\"%s\" />',premake.esc(e))end\nfor i,e in ipairs(premake.getlinks(e,\"system\",\"name\"))do\n_p(' <Library Value=\"%s\" />',premake.esc(e))end\n_p(' </Linker>')if premake.findfile(e,\".rc\")then\nlocal i=table.implode(table.join(e.defines,e.resdefines),\"-D\",\";\",\"\")local o=table.concat(e.resoptions,\";\")_p(' <ResourceCompiler Required=\"yes\" Options=\"%s%s\">',i,o)for i,e in ipairs(table.join(e.includedirs,e.resincludedirs))do\n_p(' <IncludePath Value=\"%s\"/>',premake.esc(e))end\n_p(' </ResourceCompiler>')else\n_p(' <ResourceCompiler Required=\"no\" Options=\"\"/>')end\nif#e.prebuildcommands>0 then\n_p(' <PreBuild>')for i,e in ipairs(e.prebuildcommands)do\n_p(' <Command Enabled=\"yes\">%s</Command>',premake.esc(e))end\n_p(' " + " </PreBuild>')end\nif#e.postbuildcommands>0 then\n_p(' <PostBuild>')for i,e in ipairs(e.postbuildcommands)do\n_p(' <Command Enabled=\"yes\">%s</Command>',premake.esc(e))end\n_p(' </PostBuild>')end\n_p(' <CustomBuild Enabled=\"no\">')_p(' <CleanCommand></CleanCommand>')_p(' <BuildCommand></BuildCommand>')_p(' <SingleFileCommand></SingleFileCommand>')_p(' <MakefileGenerationCommand></MakefileGenerationCommand>')_p(' <ThirdPartyToolName>None</ThirdPartyToolName>')_p(' <WorkingDirectory></WorkingDirectory>')_p(' </CustomBuild>')_p(' <AdditionalRules>')_p(' <CustomPostBuild></CustomPostBuild>')_p(' <CustomPreBuild></CustomPreBuild>')_p(' </AdditionalRules>')_p(' </Configuration>')end\nend\n_p(' </Settings>')for o,e in ipairs(o)do\nfor e in premake.eachconfig(i,e)do\n_p(' <Dependencies name=\"%s\">',e.longname:gsub(\"|\",\"_\"))for i,e in ipairs(premake.getdependencies(i))do\n_p(' <Project Name=\"%s\"/>',e.name)e" + "nd\n_p(' </Dependencies>')end\nend\n_p('</CodeLite_Project>')end", + + /* actions/make/_make.lua */ + "_MAKE={}premake.make={}local t=premake.make\nfunction _MAKE.esc(n)local e\nif(type(n)==\"table\")then\ne={}for t,n in ipairs(n)do\ntable.insert(e,_MAKE.esc(n))end\nreturn e\nelse\ne=n:gsub(\"\\\\\",\"\\\\\\\\\")e=e:gsub(\" \",\"\\\\ \")e=e:gsub(\"%(\",\"\\\\%(\")e=e:gsub(\"%)\",\"\\\\%)\")e=e:gsub(\"$\\\\%((.-)\\\\%)\",\"$%(%1%)\")return e\nend\nend\nfunction premake.make_copyrule(n,e)_p('%s: %s',e,n)_p('\\t@echo Copying $(notdir %s)',e)_p('ifeq (posix,$(SHELLTYPE))')_p('\\t$(SILENT) cp -fR %s %s',n,e)_p('else')_p('\\t$(SILENT) copy /Y $(subst /,\\\\\\\\,%s) $(subst /,\\\\\\\\,%s)',n,e)_p('endif')end\nfunction premake.make_mkdirrule(e)_p('\\t@echo Creating %s',e)_p('ifeq (posix,$(SHELLTYPE))')_p('\\t$(SILENT) mkdir -p %s',e)_p('else')_p('\\t$(SILENT) mkdir $(subst /,\\\\\\\\,%s)',e)_p('endif')_p('')end\nfunction t.list(e)if#e>0 then\nreturn\" \"..table.concat(e,\" \")else\nreturn\"\"end\nend\nfunction _MAKE.getmakefilename(n,a)local e=0\nfor t in premake.solution.each()do\nif(t.location==n.location)then e=e+1 " + "end\nif(a)then\nfor a,t in ipairs(t.projects)do\nif(t.location==n.location)then e=e+1 end\nend\nend\nend\nif(e==1)then\nreturn\"Makefile\"else\nreturn n.name..\".make\"end\nend\nfunction _MAKE.getnames(e)local e=table.extract(e,\"name\")for t,n in pairs(e)do\ne[t]=_MAKE.esc(n)end\nreturn e\nend\nfunction t.settings(e,n)if#e.makesettings>0 then\nfor n,e in ipairs(e.makesettings)do\n_p(e)end\nend\nlocal e=n.platforms[e.platform].cfgsettings\nif e then\n_p(e)end\nend\nnewaction{trigger=\"gmake\",shortname=\"GNU Make\",description=\"Generate GNU makefiles for POSIX, MinGW, and Cygwin\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"gcc\"},dotnet={\"mono\",\"msnet\",\"pnet\"},},onsolution=function(e)premake.generate(e,_MAKE.getmakefilename(e,false),premake.make_solution)end,onproject=function(e)local n=_MAKE.getmakefilename(e,true)if premake.isdotnetproject(e)then\npremake.generate(e,n,premake.make_csharp)else\npremake.generate(e,n," + "premake.make_cpp)end\nend,oncleansolution=function(e)premake.clean.file(e,_MAKE.getmakefilename(e,false))end,oncleanproject=function(e)premake.clean.file(e,_MAKE.getmakefilename(e,true))end}", + + /* actions/make/make_solution.lua */ + "function premake.make_solution(e)local o=premake[_OPTIONS.cc]local a=premake.filterplatforms(e,o.platforms,\"Native\")_p('# %s solution makefile autogenerated by Premake',premake.action.current().shortname)_p('# Type \"make help\" for usage help')_p('')_p('ifndef config')_p(' config=%s',_MAKE.esc(premake.getconfigname(e.configurations[1],a[1],true)))_p('endif')_p('export config')_p('')_p('PROJECTS := %s',table.concat(_MAKE.esc(table.extract(e.projects,\"name\")),\" \"))_p('')_p('.PHONY: all clean help $(PROJECTS)')_p('')_p('all: $(PROJECTS)')_p('')for a,o in ipairs(e.projects)do\n_p('%s: %s',_MAKE.esc(o.name),table.concat(_MAKE.esc(table.extract(premake.getdependencies(o),\"name\")),\" \"))_p('\\t@echo \"==== Building %s ($(config)) ====\"',o.name)_p('\\t@${MAKE} --no-print-directory -C %s -f %s',_MAKE.esc(path.getrelative(e.location,o.location)),_MAKE.esc(_MAKE.getmakefilename(o,true)))_p('')end\n_p('clean:')for a,o in ipairs(e.projects)do\n_p('\\t@${MAKE} --no-print-directory -C %s -f %s clean',_MAKE.esc(pa" + "th.getrelative(e.location,o.location)),_MAKE.esc(_MAKE.getmakefilename(o,true)))end\n_p('')_p('help:')_p(1,'@echo \"Usage: make [config=name] [target]\"')_p(1,'@echo \"\"')_p(1,'@echo \"CONFIGURATIONS:\"')local o={}for a,o in ipairs(a)do\nfor a,e in ipairs(e.configurations)do\n_p(1,'@echo \" %s\"',premake.getconfigname(e,o,true))end\nend\n_p(1,'@echo \"\"')_p(1,'@echo \"TARGETS:\"')_p(1,'@echo \" all (default)\"')_p(1,'@echo \" clean\"')for o,e in ipairs(e.projects)do\n_p(1,'@echo \" %s\"',e.name)end\n_p(1,'@echo \"\"')_p(1,'@echo \"For more information, see http://industriousone.com/premake/quick-start\"')end", + + /* actions/make/make_cpp.lua */ + "premake.make.cpp={}local p=premake.make.cpp\nlocal i=premake.make\nfunction premake.make_cpp(e)local i=premake.gettool(e)local n=premake.filterplatforms(e.solution,i.platforms,\"Native\")premake.gmake_cpp_header(e,i,n)for n,p in ipairs(n)do\nfor e in premake.eachconfig(e,p)do\npremake.gmake_cpp_config(e,i)end\nend\n_p('OBJECTS := \\\\')for p,e in ipairs(e.files)do\nif path.iscppfile(e)then\n_p('\\t$(OBJDIR)/%s.o \\\\',_MAKE.esc(path.getbasename(e)))end\nend\n_p('')_p('RESOURCES := \\\\')for p,e in ipairs(e.files)do\nif path.isresourcefile(e)then\n_p('\\t$(OBJDIR)/%s.res \\\\',_MAKE.esc(path.getbasename(e)))end\nend\n_p('')_p('SHELLTYPE := msdos')_p('ifeq (,$(ComSpec)$(COMSPEC))')_p(' SHELLTYPE := posix')_p('endif')_p('ifeq (/bin,$(findstring /bin,$(SHELL)))')_p(' SHELLTYPE := posix')_p('endif')_p('')_p('.PHONY: clean prebuild prelink')_p('')if os.is(\"MacOSX\")and e.kind==\"WindowedApp\"then\n_p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET) $(dir $(TARGETDIR))PkgInfo $(dir $(TARGETDIR))Info.plist')" + "else\n_p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)')end\n_p('\\t@:')_p('')_p('$(TARGET): $(GCH) $(OBJECTS) $(LDDEPS) $(RESOURCES)')_p('\\t@echo Linking %s',e.name)_p('\\t$(SILENT) $(LINKCMD)')_p('\\t$(POSTBUILDCMDS)')_p('')_p('$(TARGETDIR):')premake.make_mkdirrule(\"$(TARGETDIR)\")_p('$(OBJDIR):')premake.make_mkdirrule(\"$(OBJDIR)\")if os.is(\"MacOSX\")and e.kind==\"WindowedApp\"then\n_p('$(dir $(TARGETDIR))PkgInfo:')_p('$(dir $(TARGETDIR))Info.plist:')_p('')end\n_p('clean:')_p('\\t@echo Cleaning %s',e.name)_p('ifeq (posix,$(SHELLTYPE))')_p('\\t$(SILENT) rm -f $(TARGET)')_p('\\t$(SILENT) rm -rf $(OBJDIR)')_p('else')_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,$(TARGET)) del $(subst /,\\\\\\\\,$(TARGET))')_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\\\\\,$(OBJDIR))')_p('endif')_p('')_p('prebuild:')_p('\\t$(PREBUILDCMDS)')_p('')_p('prelink:')_p('\\t$(PRELINKCMDS)')_p('')p.pchrules(e)p.fileRules(e)_p('-include $(OBJECTS:%%.o=%%.d)')_p('ifneq (,$(PCH))')_p(' -in" + "clude $(OBJDIR)/$(notdir $(PCH)).d')_p('endif')end\nfunction premake.gmake_cpp_header(p,e,i)_p('# %s project makefile autogenerated by Premake',premake.action.current().shortname)_p('ifndef config')_p(' config=%s',_MAKE.esc(premake.getconfigname(p.solution.configurations[1],i[1],true)))_p('endif')_p('')_p('ifndef verbose')_p(' SILENT = @')_p('endif')_p('')_p('CC = %s',e.cc)_p('CXX = %s',e.cxx)_p('AR = %s',e.ar)_p('')_p('ifndef RESCOMP')_p(' ifdef WINDRES')_p(' RESCOMP = $(WINDRES)')_p(' else')_p(' RESCOMP = windres')_p(' endif')_p('endif')_p('')end\nfunction premake.gmake_cpp_config(e,n)_p('ifeq ($(config),%s)',_MAKE.esc(e.shortname))p.platformtools(e,n)_p(' OBJDIR = %s',_MAKE.esc(e.objectsdir))_p(' TARGETDIR = %s',_MAKE.esc(e.buildtarget.directory))_p(' TARGET = $(TARGETDIR)/%s',_MAKE.esc(e.buildtarget.name))_p(' DEFINES +=%s',i.list(n.getdefines(e.defines)))_p(' INCLUDES +=%s',i.list(n.getincludedirs(e.includedirs)))p.pchconfig(e)p.flags(e,n)p.linker(e,n)_p(' define PREBUILDCMDS'" + ")if#e.prebuildcommands>0 then\n_p('\\t@echo Running pre-build commands')_p('\\t%s',table.implode(e.prebuildcommands,\"\",\"\",\"\\n\\t\"))end\n_p(' endef')_p(' define PRELINKCMDS')if#e.prelinkcommands>0 then\n_p('\\t@echo Running pre-link commands')_p('\\t%s',table.implode(e.prelinkcommands,\"\",\"\",\"\\n\\t\"))end\n_p(' endef')_p(' define POSTBUILDCMDS')if#e.postbuildcommands>0 then\n_p('\\t@echo Running post-build commands')_p('\\t%s',table.implode(e.postbuildcommands,\"\",\"\",\"\\n\\t\"))end\n_p(' endef')i.settings(e,n)_p('endif')_p('')end\nfunction p.platformtools(e,p)local e=p.platforms[e.platform]if e.cc then\n_p(' CC = %s',e.cc)end\nif e.cxx then\n_p(' CXX = %s',e.cxx)end\nif e.ar then\n_p(' AR = %s',e.ar)end\nend\nfunction p.flags(e,p)if e.pchheader and not e.flags.NoPCH then\n_p(' FORCE_INCLUDE += -include $(OBJDIR)/$(notdir $(PCH))')end\n_p(' ALL_CPPFLAGS += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)',table.concat(p.getcppflags(e),\" \"))_p(' ALL_CFLAGS += $(CFLAGS)" + " $(ALL_CPPFLAGS)%s',i.list(table.join(p.getcflags(e),e.buildoptions)))_p(' ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS)%s',i.list(p.getcxxflags(e)))_p(' ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',i.list(table.join(p.getdefines(e.resdefines),p.getincludedirs(e.resincludedirs),e.resoptions)))end\nfunction p.linker(e,p)_p(' ALL_LDFLAGS += $(LDFLAGS)%s',i.list(table.join(p.getlibdirflags(e),p.getldflags(e),e.linkoptions)))_p(' LDDEPS +=%s',i.list(_MAKE.esc(premake.getlinks(e,\"siblings\",\"fullpath\"))))_p(' LIBS += $(LDDEPS)%s',i.list(p.getlinkflags(e)))if e.kind==\"StaticLib\"then\nif e.platform:startswith(\"Universal\")then\n_p(' LINKCMD = libtool -o $(TARGET) $(OBJECTS)')else\n_p(' LINKCMD = $(AR) -rcs $(TARGET) $(OBJECTS)')end\nelse\nlocal e=iif(e.language==\"C\",\"CC\",\"CXX\")_p(' LINKCMD = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)',e)end\nend\nfunction p.pchconfig(e)if not e.pchheader or e.flags.NoPCH then\nreturn\nend\nlocal p=e.pchheader\nfor n" + ",i in ipairs(e.includedirs)do\nlocal i=path.getabsolute(path.join(e.project.location,i))local i=path.join(i,p)if os.isfile(i)then\np=path.getrelative(e.location,i)break\nend\nend\n_p(' PCH = %s',_MAKE.esc(p))_p(' GCH = $(OBJDIR)/$(notdir $(PCH)).gch')end\nfunction p.pchrules(e)_p('ifneq (,$(PCH))')_p('.NOTPARALLEL: $(GCH) $(PCH)')_p('$(GCH): $(PCH)')_p('\\t@echo $(notdir $<)')local e=iif(e.language==\"C\",\"$(CC) -x c-header $(ALL_CFLAGS)\",\"$(CXX) -x c++-header $(ALL_CXXFLAGS)\")_p('\\t$(SILENT) %s -MMD -MP $(DEFINES) $(INCLUDES) -o \"$@\" -MF \"$(@:%%.gch=%%.d)\" -c \"$<\"',e)_p('endif')_p('')end\nfunction p.fileRules(e)for i,e in ipairs(e.files or{})do\nif path.iscppfile(e)then\n_p('$(OBJDIR)/%s.o: %s',_MAKE.esc(path.getbasename(e)),_MAKE.esc(e))_p('\\t@echo $(notdir $<)')p.buildcommand(path.iscfile(e),\"o\")_p('')elseif(path.getextension(e)==\".rc\")then\n_p('$(OBJDIR)/%s.res: %s',_MAKE.esc(path.getbasename(e)),_MAKE.esc(e))_p('\\t@echo $(notdir $<)')_p('\\t$(SILENT) $(RESCOMP) $< -O coff " + "-o \"$@\" $(ALL_RESFLAGS)')_p('')end\nend\nend\nfunction p.buildcommand(e,p)local e=iif(e,'$(CC) $(ALL_CFLAGS)','$(CXX) $(ALL_CXXFLAGS)')_p('\\t$(SILENT) %s $(FORCE_INCLUDE) -o \"$@\" -MF \"$(@:%%.%s=%%.d)\" -c \"$<\"',e,p)end", + + /* actions/make/make_csharp.lua */ + "local function o(n,e)if path.getextension(e)==\".resx\"then\nlocal n=n.buildtarget.basename..\".\"local i=path.getdirectory(e)if i~=\".\"then\nn=n..path.translate(i,\".\")..\".\"end\nreturn\"$(OBJDIR)/\".._MAKE.esc(n..path.getbasename(e))..\".resources\"else\nreturn e\nend\nend\nfunction premake.make_csharp(e)local p=premake.dotnet\nlocal s={}local i={}local l\nfor e in premake.eachconfig(e)do\nl=e\ns[e]=premake.getlinks(e,\"siblings\",\"fullpath\")i[e]={}for p,n in ipairs(s[e])do\nif path.getdirectory(n)~=e.buildtarget.directory then\ni[e][\"$(TARGETDIR)/\".._MAKE.esc(path.getname(n))]=_MAKE.esc(n)end\nend\nend\nlocal r={}local a={}local n={}for e in premake.project.eachfile(e)do\nlocal i=p.getbuildaction(e)if i==\"Compile\"then\ntable.insert(r,e.name)elseif i==\"EmbeddedResource\"then\ntable.insert(a,e.name)elseif i==\"Content\"then\nn[\"$(TARGETDIR)/\".._MAKE.esc(path.getname(e.name))]=_MAKE.esc(e.name)elseif path.getname(e.name):lower()==\"app.config\"then\nn[\"$(TARGET).config\"]=_MAKE.esc(e.name)end\nend" + "\nlocal t=table.translate(e.libdirs,function(n)return path.join(e.basedir,n)end)t=table.join({e.basedir},t)for p,i in ipairs(premake.getlinks(e,\"system\",\"fullpath\"))do\nlocal p=os.pathsearch(i..\".dll\",unpack(t))if(p)then\nlocal t=\"$(TARGETDIR)/\".._MAKE.esc(path.getname(i))local e=path.getrelative(e.basedir,path.join(p,i))..\".dll\"n[t]=_MAKE.esc(e)end\nend\n_p('# %s project makefile autogenerated by Premake',premake.action.current().shortname)_p('')_p('ifndef config')_p(' config=%s',_MAKE.esc(e.configurations[1]:lower()))_p('endif')_p('')_p('ifndef verbose')_p(' SILENT = @')_p('endif')_p('')_p('ifndef CSC')_p(' CSC=%s',p.getcompilervar(e))_p('endif')_p('')_p('ifndef RESGEN')_p(' RESGEN=resgen')_p('endif')_p('')local t=premake.filterplatforms(e.solution,premake[_OPTIONS.cc].platforms)table.insert(t,1,\"\")for e in premake.eachconfig(e)do\npremake.gmake_cs_config(e,p,s)end\n_p('# To maintain compatibility with VS.NET, these values must be set at the project level')_p('TARGET := $(TARGETDIR)/%s',_" + "MAKE.esc(e.buildtarget.name))_p('FLAGS += /t:%s %s',p.getkind(e):lower(),table.implode(_MAKE.esc(e.libdirs),\"/lib:\",\"\",\" \"))_p('REFERENCES += %s',table.implode(_MAKE.esc(premake.getlinks(e,\"system\",\"basename\")),\"/r:\",\".dll\",\" \"))_p('')_p('SOURCES := \\\\')for n,e in ipairs(r)do\n_p('\\t%s \\\\',_MAKE.esc(path.translate(e)))end\n_p('')_p('EMBEDFILES := \\\\')for i,n in ipairs(a)do\n_p('\\t%s \\\\',o(e,n))end\n_p('')_p('COPYFILES += \\\\')for e,n in pairs(i[l])do\n_p('\\t%s \\\\',e)end\nfor e,n in pairs(n)do\n_p('\\t%s \\\\',e)end\n_p('')_p('SHELLTYPE := msdos')_p('ifeq (,$(ComSpec)$(COMSPEC))')_p(' SHELLTYPE := posix')_p('endif')_p('ifeq (/bin,$(findstring /bin,$(SHELL)))')_p(' SHELLTYPE := posix')_p('endif')_p('')_p('.PHONY: clean prebuild prelink')_p('')_p('all: $(TARGETDIR) $(OBJDIR) prebuild $(EMBEDFILES) $(COPYFILES) prelink $(TARGET)')_p('')_p('$(TARGET): $(SOURCES) $(EMBEDFILES) $(DEPENDS)')_p('\\t$(SILENT) $(CSC) /nologo /out:$@ $(FLAGS) $(REFERENCES) $(SOURCES) $(patsubst %%,/res" + "ource:%%,$(EMBEDFILES))')_p('\\t$(POSTBUILDCMDS)')_p('')_p('$(TARGETDIR):')premake.make_mkdirrule(\"$(TARGETDIR)\")_p('$(OBJDIR):')premake.make_mkdirrule(\"$(OBJDIR)\")_p('clean:')_p('\\t@echo Cleaning %s',e.name)_p('ifeq (posix,$(SHELLTYPE))')_p('\\t$(SILENT) rm -f $(TARGETDIR)/%s.* $(COPYFILES)',e.buildtarget.basename)_p('\\t$(SILENT) rm -rf $(OBJDIR)')_p('else')_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,$(TARGETDIR)/%s.*) del $(subst /,\\\\\\\\,$(TARGETDIR)/%s.*)',e.buildtarget.basename,e.buildtarget.basename)for e,n in pairs(i[l])do\n_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,%s) del $(subst /,\\\\\\\\,%s)',e,e)end\nfor e,n in pairs(n)do\n_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,%s) del $(subst /,\\\\\\\\,%s)',e,e)end\n_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\\\\\,$(OBJDIR))')_p('endif')_p('')_p('prebuild:')_p('\\t$(PREBUILDCMDS)')_p('')_p('prelink:')_p('\\t$(PRELINKCMDS)')_p('')_p('# Per-configuration copied file rules')for e in premake.eachconfig(e)do\n_p(" + "'ifneq (,$(findstring %s,$(config)))',_MAKE.esc(e.name:lower()))for e,n in pairs(i[e])do\npremake.make_copyrule(n,e)end\n_p('endif')_p('')end\n_p('# Copied file rules')for e,n in pairs(n)do\npremake.make_copyrule(n,e)end\n_p('# Embedded file rules')for i,n in ipairs(a)do\nif path.getextension(n)==\".resx\"then\n_p('%s: %s',o(e,n),_MAKE.esc(n))_p('\\t$(SILENT) $(RESGEN) $^ $@')end\n_p('')end\nend\nfunction premake.gmake_cs_config(e,i,n)_p('ifneq (,$(findstring %s,$(config)))',_MAKE.esc(e.name:lower()))_p(' TARGETDIR := %s',_MAKE.esc(e.buildtarget.directory))_p(' OBJDIR := %s',_MAKE.esc(e.objectsdir))_p(' DEPENDS := %s',table.concat(_MAKE.esc(premake.getlinks(e,\"dependencies\",\"fullpath\")),\" \"))_p(' REFERENCES := %s',table.implode(_MAKE.esc(n[e]),\"/r:\",\"\",\" \"))_p(' FLAGS += %s %s',table.implode(e.defines,\"/d:\",\"\",\" \"),table.concat(table.join(i.getflags(e),e.buildoptions),\" \"))_p(' define PREBUILDCMDS')if#e.prebuildcommands>0 then\n_p('\\t@echo Running pre-build commands')_p(" + "'\\t%s',table.implode(e.prebuildcommands,\"\",\"\",\"\\n\\t\"))end\n_p(' endef')_p(' define PRELINKCMDS')if#e.prelinkcommands>0 then\n_p('\\t@echo Running pre-link commands')_p('\\t%s',table.implode(e.prelinkcommands,\"\",\"\",\"\\n\\t\"))end\n_p(' endef')_p(' define POSTBUILDCMDS')if#e.postbuildcommands>0 then\n_p('\\t@echo Running post-build commands')_p('\\t%s',table.implode(e.postbuildcommands,\"\",\"\",\"\\n\\t\"))end\n_p(' endef')_p('endif')_p('')end", + + /* actions/vstudio/_vstudio.lua */ + "premake.vstudio={}local e=premake.vstudio\ne.platforms={any=\"Any CPU\",mixed=\"Mixed Platforms\",Native=\"Win32\",x86=\"x86\",x32=\"Win32\",x64=\"x64\",PS3=\"PS3\",Xbox360=\"Xbox 360\",}function e.arch(e)if(e.language==\"C#\")then\nif(_ACTION<\"vs2005\")then\nreturn\".NET\"else\nreturn\"Any CPU\"end\nelse\nreturn\"Win32\"end\nend\nfunction e.buildconfigs(r)local s={}local n=premake.filterplatforms(r,e.platforms,\"Native\")local o=premake.hascppproject(r)local a=premake.hasdotnetproject(r)if a and(_ACTION>\"vs2008\"or o)then\ntable.insert(n,1,\"mixed\")end\nif a and(_ACTION<\"vs2010\"or not o)then\ntable.insert(n,1,\"any\")end\nif _ACTION>\"vs2008\"then\nlocal r={}for s,t in ipairs(n)do\nif e.platforms[t]==\"Win32\"then\nif o then\ntable.insert(r,t)end\nif a then\ntable.insert(r,\"x86\")end\nelse\ntable.insert(r,t)end\nend\nn=r\nend\nfor r,o in ipairs(r.configurations)do\nfor n,r in ipairs(n)do\nlocal n={}n.src_buildcfg=o\nn.src_platform=r\nif r~=\"PS3\"or _ACTION>\"vs2008\"then\nn.buildcfg=o\nn.platform=e.pla" + "tforms[r]else\nn.buildcfg=r..\" \"..o\nn.platform=\"Win32\"end\nn.name=n.buildcfg..\"|\"..n.platform\nn.isreal=(r~=\"any\"and r~=\"mixed\")table.insert(s,n)end\nend\nreturn s\nend\nfunction e.cleansolution(e)premake.clean.file(e,\"%%.sln\")premake.clean.file(e,\"%%.suo\")premake.clean.file(e,\"%%.ncb\")premake.clean.file(e,\"%%.userprefs\")premake.clean.file(e,\"%%.usertasks\")end\nfunction e.cleanproject(e)local e=premake.project.getfilename(e,\"%%\")os.remove(e..\".vcproj\")os.remove(e..\".vcxproj\")os.remove(e..\".vcxproj.filters\")os.remove(e..\".csproj\")os.remove(e..\".pidb\")os.remove(e..\".sdf\")if _OPTIONS.generate_user then\nos.remove(e..\".vcproj.user\")os.remove(e..\".vcxproj.user\")os.remove(e..\".csproj.user\")end\nend\nfunction e.cleantarget(e)os.remove(e..\".pdb\")os.remove(e..\".idb\")os.remove(e..\".ilk\")os.remove(e..\".vshost.exe\")os.remove(e..\".exe.manifest\")end\nfunction e.projectfile(n)local e\nif n.language==\"C#\"then\ne=\"%%.csproj\"else\ne=iif(_ACTION>\"vs2008\",\"%%.vcxproj\",\"%" + "%.vcproj\")end\nlocal e=premake.project.getbasename(n.name,e)e=path.join(n.location,e)return e\nend\nfunction e.tool(e)if(e.language==\"C#\")then\nreturn\"FAE04EC0-301F-11D3-BF4B-00C04F79EFBC\"else\nreturn\"8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942\"end\nend\nnewaction{trigger=\"vs2002\",shortname=\"Visual Studio 2002\",description=\"Generate Microsoft Visual Studio 2002 project files\",os=\"windows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(n)premake.generate(n,\"%%.sln\",e.sln2002.generate)end,onproject=function(n)if premake.isdotnetproject(n)then\npremake.generate(n,\"%%.csproj\",e.cs2002.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.csproj.user\",e.cs2002.generate_user)end\nelse\npremake.generate(n,\"%%.vcproj\",e.vc200x.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.vcproj.user\",e.vc200x.generate_user)end\nend\nend,oncleansolution=premak" + "e.vstudio.cleansolution,oncleanproject=premake.vstudio.cleanproject,oncleantarget=premake.vstudio.cleantarget,vstudio={}}newaction{trigger=\"vs2003\",shortname=\"Visual Studio 2003\",description=\"Generate Microsoft Visual Studio 2003 project files\",os=\"windows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(n)premake.generate(n,\"%%.sln\",e.sln2003.generate)end,onproject=function(n)if premake.isdotnetproject(n)then\npremake.generate(n,\"%%.csproj\",e.cs2002.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.csproj.user\",e.cs2002.generate_user)end\nelse\npremake.generate(n,\"%%.vcproj\",e.vc200x.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.vcproj.user\",e.vc200x.generate_user)end\nend\nend,oncleansolution=premake.vstudio.cleansolution,oncleanproject=premake.vstudio.cleanproject,oncleantarget=premake.vstudio.cleantarget,vstudio={}}newaction{tri" + "gger=\"vs2005\",shortname=\"Visual Studio 2005\",description=\"Generate Microsoft Visual Studio 2005 project files\",os=\"windows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(n)premake.generate(n,\"%%.sln\",e.sln2005.generate)end,onproject=function(n)if premake.isdotnetproject(n)then\npremake.generate(n,\"%%.csproj\",e.cs2005.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.csproj.user\",e.cs2005.generate_user)end\nelse\npremake.generate(n,\"%%.vcproj\",e.vc200x.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.vcproj.user\",e.vc200x.generate_user)end\nend\nend,oncleansolution=e.cleansolution,oncleanproject=e.cleanproject,oncleantarget=e.cleantarget,vstudio={productVersion=\"8.0.50727\",solutionVersion=\"9\",}}newaction{trigger=\"vs2008\",shortname=\"Visual Studio 2008\",description=\"Generate Microsoft Visual Studio 2008 project files\",os=\"win" + "dows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(n)premake.generate(n,\"%%.sln\",e.sln2005.generate)end,onproject=function(n)if premake.isdotnetproject(n)then\npremake.generate(n,\"%%.csproj\",e.cs2005.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.csproj.user\",e.cs2005.generate_user)end\nelse\npremake.generate(n,\"%%.vcproj\",e.vc200x.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.vcproj.user\",e.vc200x.generate_user)end\nend\nend,oncleansolution=e.cleansolution,oncleanproject=e.cleanproject,oncleantarget=e.cleantarget,vstudio={productVersion=\"9.0.21022\",solutionVersion=\"10\",toolsVersion=\"3.5\",}}newaction{trigger=\"vs2010\",shortname=\"Visual Studio 2010\",description=\"Generate Microsoft Visual Studio 2010 project files\",os=\"windows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\"," + "\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(n)premake.generate(n,\"%%.sln\",e.sln2005.generate)end,onproject=function(n)if premake.isdotnetproject(n)then\npremake.generate(n,\"%%.csproj\",e.cs2005.generate)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.csproj.user\",e.cs2005.generate_user)end\nelse\npremake.generate(n,\"%%.vcxproj\",premake.vs2010_vcxproj)if _OPTIONS.generate_user then\npremake.generate(n,\"%%.vcxproj.user\",premake.vs2010_vcxproj_user)end\npremake.generate(n,\"%%.vcxproj.filters\",e.vc2010.generate_filters)end\nend,oncleansolution=premake.vstudio.cleansolution,oncleanproject=premake.vstudio.cleanproject,oncleantarget=premake.vstudio.cleantarget,vstudio={productVersion=\"8.0.30703\",solutionVersion=\"11\",targetFramework=\"4.0\",toolsVersion=\"4.0\",}}", + + /* actions/vstudio/vs2002_solution.lua */ + "premake.vstudio.sln2002={}local i=premake.vstudio\nlocal o=premake.vstudio.sln2002\nfunction o.generate(o)io.indent=nil\nio.eol='\\r\\n'o.vstudio_configs=premake.vstudio.buildconfigs(o)_p('Microsoft Visual Studio Solution File, Format Version 7.00')for n in premake.solution.eachproject(o)do\nlocal o=path.translate(path.getrelative(o.location,i.projectfile(n)))_p('Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"',i.tool(n),n.name,o,n.uuid)_p('EndProject')end\n_p('Global')_p(1,'GlobalSection(SolutionConfiguration) = preSolution')for o,i in ipairs(o.configurations)do\n_p(2,'ConfigName.%d = %s',o-1,i)end\n_p(1,'EndGlobalSection')_p(1,'GlobalSection(ProjectDependencies) = postSolution')_p(1,'EndGlobalSection')_p(1,'GlobalSection(ProjectConfiguration) = postSolution')for n in premake.solution.eachproject(o)do\nfor e,o in ipairs(o.configurations)do\n_p(2,'{%s}.%s.ActiveCfg = %s|%s',n.uuid,o,o,i.arch(n))_p(2,'{%s}.%s.Build.0 = %s|%s',n.uuid,o,o,i.arch(n))end\nend\n_p(1,'EndGlobalSection')_p(1,'GlobalSection(ExtensibilityG" + "lobals) = postSolution')_p(1,'EndGlobalSection')_p(1,'GlobalSection(ExtensibilityAddIns) = postSolution')_p(1,'EndGlobalSection')_p('EndGlobal')end", + + /* actions/vstudio/vs2002_csproj.lua */ + "premake.vstudio.cs2002={}local s=premake.vstudio\nlocal a=premake.vstudio.cs2002\nlocal function n(a,t,e)if t==\"Compile\"and e:endswith(\".cs\")then\nreturn\"SubTypeCode\"end\nif t==\"EmbeddedResource\"and e:endswith(\".resx\")then\nlocal e=e:sub(1,-6)local e=path.getname(e..\".cs\")if premake.findfile(a,e)then\nreturn\"Dependency\",e\nend\nend\nreturn\"None\"end\nfunction a.Files(a)local e=premake.project.buildsourcetree(a)premake.tree.traverse(e,{onleaf=function(e)local t=premake.dotnet.getbuildaction(e.cfg)local s=path.translate(premake.esc(e.cfg.name),\"\\\\\")local a,e=n(a,t,e.path)_p(4,'<File')_p(5,'RelPath = \"%s\"',s)_p(5,'BuildAction = \"%s\"',t)if e then\n_p(5,'DependentUpon = \"%s\"',premake.esc(path.translate(e,\"\\\\\")))end\nif a==\"SubTypeCode\"then\n_p(5,'SubType = \"Code\"')end\n_p(4,'/>')end},false)end\nfunction a.generate(t)io.eol=\"\\r\\n\"_p('<VisualStudioProject>')_p(1,'<CSHARP')_p(2,'ProjectType = \"Local\"')_p(2,'ProductVersion = \"%s\"',iif(_ACTION==\"vs2002\",\"7.0.9254\",\"7.10.3077" + "\"))_p(2,'SchemaVersion = \"%s\"',iif(_ACTION==\"vs2002\",\"1.0\",\"2.0\"))_p(2,'ProjectGuid = \"{%s}\"',t.uuid)_p(1,'>')_p(2,'<Build>')_p(3,'<Settings')_p(4,'ApplicationIcon = \"\"')_p(4,'AssemblyKeyContainerName = \"\"')_p(4,'AssemblyName = \"%s\"',t.buildtarget.basename)_p(4,'AssemblyOriginatorKeyFile = \"\"')_p(4,'DefaultClientScript = \"JScript\"')_p(4,'DefaultHTMLPageLayout = \"Grid\"')_p(4,'DefaultTargetSchema = \"IE50\"')_p(4,'DelaySign = \"false\"')if _ACTION==\"vs2002\"then\n_p(4,'NoStandardLibraries = \"false\"')end\n_p(4,'OutputType = \"%s\"',premake.dotnet.getkind(t))if _ACTION==\"vs2003\"then\n_p(4,'PreBuildEvent = \"\"')_p(4,'PostBuildEvent = \"\"')end\n_p(4,'RootNamespace = \"%s\"',t.buildtarget.basename)if _ACTION==\"vs2003\"then\n_p(4,'RunPostBuildEvent = \"OnBuildSuccess\"')end\n_p(4,'StartupObject = \"\"')_p(3,'>')for e in premake.eachconfig(t)do\n_p(4,'<Config')_p(5,'Name = \"%s\"',premake.esc(e.name))_p(5,'AllowUnsafeBlocks = \"%s\"',iif(e.flags.Unsafe,\"true\",\"false\"))_p(5,'BaseAddres" + "s = \"285212672\"')_p(5,'CheckForOverflowUnderflow = \"false\"')_p(5,'ConfigurationOverrideFile = \"\"')_p(5,'DefineConstants = \"%s\"',premake.esc(table.concat(e.defines,\";\")))_p(5,'DocumentationFile = \"\"')_p(5,'DebugSymbols = \"%s\"',iif(e.flags.Symbols,\"true\",\"false\"))_p(5,'FileAlignment = \"4096\"')_p(5,'IncrementalBuild = \"false\"')if _ACTION==\"vs2003\"then\n_p(5,'NoStdLib = \"false\"')_p(5,'NoWarn = \"\"')end\n_p(5,'Optimize = \"%s\"',iif(e.flags.Optimize or e.flags.OptimizeSize or e.flags.OptimizeSpeed,\"true\",\"false\"))_p(5,'OutputPath = \"%s\"',premake.esc(e.buildtarget.directory))_p(5,'RegisterForComInterop = \"false\"')_p(5,'RemoveIntegerChecks = \"false\"')_p(5,'TreatWarningsAsErrors = \"%s\"',iif(e.flags.FatalWarnings,\"true\",\"false\"))_p(5,'WarningLevel = \"4\"')_p(4,'/>')end\n_p(3,'</Settings>')_p(3,'<References>')for t,e in ipairs(premake.getlinks(t,\"siblings\",\"object\"))do\n_p(4,'<Reference')_p(5,'Name = \"%s\"',e.buildtarget.basename)_p(5,'Project = \"{%s}\"',e.uuid)_p(5,'Pac" + "kage = \"{%s}\"',s.tool(e))_p(4,'/>')end\nfor t,e in ipairs(premake.getlinks(t,\"system\",\"fullpath\"))do\n_p(4,'<Reference')_p(5,'Name = \"%s\"',path.getbasename(e))_p(5,'AssemblyName = \"%s\"',path.getname(e))if path.getdirectory(e)~=\".\"then\n_p(5,'HintPath = \"%s\"',path.translate(e,\"\\\\\"))end\n_p(4,'/>')end\n_p(3,'</References>')_p(2,'</Build>')_p(2,'<Files>')_p(3,'<Include>')a.Files(t)_p(3,'</Include>')_p(2,'</Files>')_p(1,'</CSHARP>')_p('</VisualStudioProject>')end", + + /* actions/vstudio/vs2002_csproj_user.lua */ + "local e=premake.vstudio.cs2002\nfunction e.generate_user(e)io.eol=\"\\r\\n\"_p('<VisualStudioProject>')_p(1,'<CSHARP>')_p(2,'<Build>')local t=table.translate(e.libdirs,function(t)return path.getabsolute(e.location..\"/\"..t)end)_p(3,'<Settings ReferencePath = \"%s\">',path.translate(table.concat(t,\";\"),\"\\\\\"))for e in premake.eachconfig(e)do\n_p(4,'<Config')_p(5,'Name = \"%s\"',premake.esc(e.name))_p(5,'EnableASPDebugging = \"false\"')_p(5,'EnableASPXDebugging = \"false\"')_p(5,'EnableUnmanagedDebugging = \"false\"')_p(5,'EnableSQLServerDebugging = \"false\"')_p(5,'RemoteDebugEnabled = \"false\"')_p(5,'RemoteDebugMachine = \"\"')_p(5,'StartAction = \"Project\"')_p(5,'StartArguments = \"\"')_p(5,'StartPage = \"\"')_p(5,'StartProgram = \"\"')_p(5,'StartURL = \"\"')_p(5,'StartWorkingDirectory = \"\"')_p(5,'StartWithIE = \"false\"')_p(4,'/>')end\n_p(3,'</Settings>')_p(2,'</Build>')_p(2,'<OtherProjectSettings')_p(3,'CopyProjectDestinationFolder = \"\"')_p(3,'CopyProjectUncPath = \"\"')_p(3,'CopyProjectOption =" + " \"0\"')_p(3,'ProjectView = \"ProjectFiles\"')_p(3,'ProjectTrust = \"0\"')_p(2,'/>')_p(1,'</CSHARP>')_p('</VisualStudioProject>')end", + + /* actions/vstudio/vs200x_vcproj.lua */ + "premake.vstudio.vc200x={}local o=premake.vstudio.vc200x\nlocal i=premake.tree\nlocal function n(e)if(_ACTION<\"vs2005\")then\nreturn iif(e,\"TRUE\",\"FALSE\")else\nreturn iif(e,\"true\",\"false\")end\nend\nfunction o.optimization(o)local e=0\nfor n,o in ipairs(o.flags)do\nif(o==\"Optimize\")then\ne=3\nelseif(o==\"OptimizeSize\")then\ne=1\nelseif(o==\"OptimizeSpeed\")then\ne=2\nend\nend\nreturn e\nend\nfunction o.header(e)io.eol=\"\\r\\n\"_p('<?xml version=\"1.0\" encoding=\"Windows-1252\"?>')_p('<%s',e)_p(1,'ProjectType=\"Visual C++\"')if _ACTION==\"vs2002\"then\n_p(1,'Version=\"7.00\"')elseif _ACTION==\"vs2003\"then\n_p(1,'Version=\"7.10\"')elseif _ACTION==\"vs2005\"then\n_p(1,'Version=\"8.00\"')elseif _ACTION==\"vs2008\"then\n_p(1,'Version=\"9.00\"')end\nend\nfunction o.Configuration(o,e)_p(2,'<Configuration')_p(3,'Name=\"%s\"',premake.esc(o))_p(3,'OutputDirectory=\"%s\"',premake.esc(e.buildtarget.directory))_p(3,'IntermediateDirectory=\"%s\"',premake.esc(e.objectsdir))local o\nif(e.kind==\"SharedLib\")then" + "\no=2\nelseif(e.kind==\"StaticLib\")then\no=4\nelse\no=1\nend\n_p(3,'ConfigurationType=\"%s\"',o)if(e.flags.MFC)then\n_p(3,'UseOfMFC=\"%d\"',iif(e.flags.StaticRuntime,1,2))end\nif(e.flags.ATL or e.flags.StaticATL)then\n_p(3,'UseOfATL=\"%d\"',iif(e.flags.StaticATL,1,2))end\n_p(3,'CharacterSet=\"%s\"',iif(e.flags.Unicode,1,2))if e.flags.Managed then\n_p(3,'ManagedExtensions=\"1\"')end\n_p(3,'>')end\nfunction o.Files(o)local e=premake.project.buildsourcetree(o)i.traverse(e,{onbranchenter=function(o,e)_p(e,'<Filter')_p(e,'\\tName=\"%s\"',o.name)_p(e,'\\tFilter=\"\"')_p(e,'\\t>')end,onbranchexit=function(o,e)_p(e,'</Filter>')end,onleaf=function(l,e)local t=l.cfg.name\n_p(e,'<File')_p(e,'\\tRelativePath=\"%s\"',path.translate(t,\"\\\\\"))_p(e,'\\t>')e=e+1\nfor n,i in ipairs(o.solution.vstudio_configs)do\nif i.isreal then\nlocal n=premake.getconfig(o,i.src_buildcfg,i.src_platform)local l=(not o.flags.NoPCH and o.pchsource==l.cfg.name)local a=path.iscppfile(t)local o=(path.iscfile(t)~=premake.project.iscproject(o))if " + "l or(a and o)then\n_p(e,'<FileConfiguration')_p(e,'\\tName=\"%s\"',i.name)_p(e,'\\t>')_p(e,'\\t<Tool')_p(e,'\\t\\tName=\"%s\"',iif(n.system==\"Xbox360\",\"VCCLX360CompilerTool\",\"VCCLCompilerTool\"))if o then\n_p(e,'\\t\\tCompileAs=\"%s\"',iif(path.iscfile(t),1,2))end\nif l then\nif n.system==\"PS3\"then\nlocal o=table.join(premake.snc.getcflags(n),premake.snc.getcxxflags(n),n.buildoptions)o=table.concat(o,\" \");o=o..' --create_pch=\"$(IntDir)/$(TargetName).pch\"'_p(e,'\\t\\tAdditionalOptions=\"%s\"',premake.esc(o))else\n_p(e,'\\t\\tUsePrecompiledHeader=\"1\"')end\nend\n_p(e,'\\t/>')_p(e,'</FileConfiguration>')end\nend\nend\ne=e-1\n_p(e,'</File>')end,},false,2)end\nfunction o.Platforms(e)local o={}_p(1,'<Platforms>')for n,e in ipairs(e.solution.vstudio_configs)do\nif e.isreal and not table.contains(o,e.platform)then\ntable.insert(o,e.platform)_p(2,'<Platform')_p(3,'Name=\"%s\"',e.platform)_p(2,'/>')end\nend\n_p(1,'</Platforms>')end\nfunction o.Symbols(e)if(not e.flags.Symbols)then\nreturn 0\nelse\nif e.flags" + ".NoEditAndContinue or\no.optimization(e)~=0 or\ne.flags.Managed or\ne.platform==\"x64\"then\nreturn 3\nelse\nreturn 4\nend\nend\nend\nfunction o.VCCLCompilerTool(e)_p(3,'<Tool')_p(4,'Name=\"%s\"',iif(e.platform~=\"Xbox360\",\"VCCLCompilerTool\",\"VCCLX360CompilerTool\"))if#e.buildoptions>0 then\n_p(4,'AdditionalOptions=\"%s\"',table.concat(premake.esc(e.buildoptions),\" \"))end\n_p(4,'Optimization=\"%s\"',o.optimization(e))if e.flags.NoFramePointer then\n_p(4,'OmitFramePointers=\"%s\"',n(true))end\nif#e.includedirs>0 then\n_p(4,'AdditionalIncludeDirectories=\"%s\"',premake.esc(path.translate(table.concat(e.includedirs,\";\"),'\\\\')))end\nif#e.defines>0 then\n_p(4,'PreprocessorDefinitions=\"%s\"',premake.esc(table.concat(e.defines,\";\")))end\nif premake.config.isdebugbuild(e)and not e.flags.NoMinimalRebuild and not e.flags.Managed then\n_p(4,'MinimalRebuild=\"%s\"',n(true))end\nif e.flags.NoExceptions then\n_p(4,'ExceptionHandling=\"%s\"',iif(_ACTION<\"vs2005\",\"FALSE\",0))elseif e.flags.SEH and _ACTION>\"vs" + "2003\"then\n_p(4,'ExceptionHandling=\"2\"')end\nif o.optimization(e)==0 and not e.flags.Managed then\n_p(4,'BasicRuntimeChecks=\"3\"')end\nif o.optimization(e)~=0 then\n_p(4,'StringPooling=\"%s\"',n(true))end\nlocal i\nif premake.config.isdebugbuild(e)then\ni=iif(e.flags.StaticRuntime,1,3)else\ni=iif(e.flags.StaticRuntime,0,2)end\n_p(4,'RuntimeLibrary=\"%s\"',i)_p(4,'EnableFunctionLevelLinking=\"%s\"',n(true))if _ACTION>\"vs2003\"and e.platform~=\"Xbox360\"and e.platform~=\"x64\"then\nif e.flags.EnableSSE then\n_p(4,'EnableEnhancedInstructionSet=\"1\"')elseif e.flags.EnableSSE2 then\n_p(4,'EnableEnhancedInstructionSet=\"2\"')end\nend\nif _ACTION<\"vs2005\"then\nif e.flags.FloatFast then\n_p(4,'ImproveFloatingPointConsistency=\"%s\"',n(false))elseif e.flags.FloatStrict then\n_p(4,'ImproveFloatingPointConsistency=\"%s\"',n(true))end\nelse\nif e.flags.FloatFast then\n_p(4,'FloatingPointModel=\"2\"')elseif e.flags.FloatStrict then\n_p(4,'FloatingPointModel=\"1\"')end\nend\nif _ACTION<\"vs2005\"and not e.flags.NoRT" + "TI then\n_p(4,'RuntimeTypeInfo=\"%s\"',n(true))elseif _ACTION>\"vs2003\"and e.flags.NoRTTI and not e.flags.Managed then\n_p(4,'RuntimeTypeInfo=\"%s\"',n(false))end\nif e.flags.NativeWChar then\n_p(4,'TreatWChar_tAsBuiltInType=\"%s\"',n(true))elseif e.flags.NoNativeWChar then\n_p(4,'TreatWChar_tAsBuiltInType=\"%s\"',n(false))end\nif not e.flags.NoPCH and e.pchheader then\n_p(4,'UsePrecompiledHeader=\"%s\"',iif(_ACTION<\"vs2005\",3,2))_p(4,'PrecompiledHeaderThrough=\"%s\"',e.pchheader)else\n_p(4,'UsePrecompiledHeader=\"%s\"',iif(_ACTION>\"vs2003\"or e.flags.NoPCH,0,2))end\n_p(4,'WarningLevel=\"%s\"',iif(e.flags.ExtraWarnings,4,3))if e.flags.FatalWarnings then\n_p(4,'WarnAsError=\"%s\"',n(true))end\nif _ACTION<\"vs2008\"and not e.flags.Managed then\n_p(4,'Detect64BitPortabilityProblems=\"%s\"',n(not e.flags.No64BitChecks))end\n_p(4,'ProgramDataBaseFileName=\"$(OutDir)\\\\%s.pdb\"',path.getbasename(e.buildtarget.name))_p(4,'DebugInformationFormat=\"%s\"',o.Symbols(e))if e.language==\"C\"then\n_p(4,'CompileAs=\"1\"" + "')end\n_p(3,'/>')end\nfunction o.VCLinkerTool(e)_p(3,'<Tool')if e.kind~=\"StaticLib\"then\n_p(4,'Name=\"%s\"',iif(e.platform~=\"Xbox360\",\"VCLinkerTool\",\"VCX360LinkerTool\"))if e.flags.NoImportLib then\n_p(4,'IgnoreImportLibrary=\"%s\"',n(true))end\nif#e.linkoptions>0 then\n_p(4,'AdditionalOptions=\"%s\"',table.concat(premake.esc(e.linkoptions),\" \"))end\nif#e.links>0 then\n_p(4,'AdditionalDependencies=\"%s\"',table.concat(premake.getlinks(e,\"all\",\"fullpath\"),\" \"))end\n_p(4,'OutputFile=\"$(OutDir)\\\\%s\"',e.buildtarget.name)_p(4,'LinkIncremental=\"%s\"',iif(premake.config.isincrementallink(e),2,1))_p(4,'AdditionalLibraryDirectories=\"%s\"',table.concat(premake.esc(path.translate(e.libdirs,'\\\\')),\";\"))local i=premake.findfile(e,\".def\")if i then\n_p(4,'ModuleDefinitionFile=\"%s\"',i)end\nif e.flags.NoManifest then\n_p(4,'GenerateManifest=\"%s\"',n(false))end\n_p(4,'GenerateDebugInformation=\"%s\"',n(o.Symbols(e)~=0))if o.Symbols(e)~=0 then\n_p(4,'ProgramDataBaseFileName=\"$(OutDir)\\\\%s.pdb\"'," + "path.getbasename(e.buildtarget.name))end\n_p(4,'SubSystem=\"%s\"',iif(e.kind==\"ConsoleApp\",1,2))if o.optimization(e)~=0 then\n_p(4,'OptimizeReferences=\"2\"')_p(4,'EnableCOMDATFolding=\"2\"')end\nif(e.kind==\"ConsoleApp\"or e.kind==\"WindowedApp\")and not e.flags.WinMain then\n_p(4,'EntryPointSymbol=\"mainCRTStartup\"')end\nif e.kind==\"SharedLib\"then\nlocal o=e.linktarget.fullpath\n_p(4,'ImportLibrary=\"%s\"',iif(e.flags.NoImportLib,e.objectsdir..\"\\\\\"..path.getname(o),o))end\n_p(4,'TargetMachine=\"%d\"',iif(e.platform==\"x64\",17,1))else\n_p(4,'Name=\"VCLibrarianTool\"')if#e.links>0 then\n_p(4,'AdditionalDependencies=\"%s\"',table.concat(premake.getlinks(e,\"all\",\"fullpath\"),\" \"))end\n_p(4,'OutputFile=\"$(OutDir)\\\\%s\"',e.buildtarget.name)if#e.libdirs>0 then\n_p(4,'AdditionalLibraryDirectories=\"%s\"',premake.esc(path.translate(table.concat(e.libdirs,\";\"))))end\nlocal o={}if e.platform==\"x32\"then\ntable.insert(o,\"/MACHINE:X86\")elseif e.platform==\"x64\"then\ntable.insert(o,\"/MACHINE:X64\"" + ")end\no=table.join(o,e.linkoptions)if#o>0 then\n_p(4,'AdditionalOptions=\"%s\"',table.concat(premake.esc(o),\" \"))end\nend\n_p(3,'/>')end\nfunction o.VCCLCompilerTool_PS3(e)_p(3,'<Tool')_p(4,'Name=\"VCCLCompilerTool\"')local o=table.join(premake.snc.getcflags(e),premake.snc.getcxxflags(e),e.buildoptions)if not e.flags.NoPCH and e.pchheader then\n_p(4,'UsePrecompiledHeader=\"%s\"',iif(_ACTION<\"vs2005\",3,2))_p(4,'PrecompiledHeaderThrough=\"%s\"',path.getname(e.pchheader))table.insert(o,'--use_pch=\"$(IntDir)/$(TargetName).pch\"')else\n_p(4,'UsePrecompiledHeader=\"%s\"',iif(_ACTION>\"vs2003\"or e.flags.NoPCH,0,2))end\n_p(4,'AdditionalOptions=\"%s\"',premake.esc(table.concat(o,\" \")))if#e.includedirs>0 then\n_p(4,'AdditionalIncludeDirectories=\"%s\"',premake.esc(path.translate(table.concat(e.includedirs,\";\"),'\\\\')))end\nif#e.defines>0 then\n_p(4,'PreprocessorDefinitions=\"%s\"',table.concat(premake.esc(e.defines),\";\"))end\n_p(4,'ProgramDataBaseFileName=\"$(OutDir)\\\\%s.pdb\"',path.getbasename(e.buildtar" + "get.name))_p(4,'DebugInformationFormat=\"0\"')_p(4,'CompileAs=\"0\"')_p(3,'/>')end\nfunction o.VCLinkerTool_PS3(e)_p(3,'<Tool')if e.kind~=\"StaticLib\"then\n_p(4,'Name=\"VCLinkerTool\"')local o=table.join(premake.snc.getldflags(e),e.linkoptions)if#o>0 then\n_p(4,'AdditionalOptions=\"%s\"',premake.esc(table.concat(o,\" \")))end\nif#e.links>0 then\n_p(4,'AdditionalDependencies=\"%s\"',table.concat(premake.getlinks(e,\"all\",\"fullpath\"),\" \"))end\n_p(4,'OutputFile=\"$(OutDir)\\\\%s\"',e.buildtarget.name)_p(4,'LinkIncremental=\"0\"')_p(4,'AdditionalLibraryDirectories=\"%s\"',table.concat(premake.esc(path.translate(e.libdirs,'\\\\')),\";\"))_p(4,'GenerateManifest=\"%s\"',n(false))_p(4,'ProgramDatabaseFile=\"\"')_p(4,'RandomizedBaseAddress=\"1\"')_p(4,'DataExecutionPrevention=\"0\"')else\n_p(4,'Name=\"VCLibrarianTool\"')local o=table.join(premake.snc.getldflags(e),e.linkoptions)if#o>0 then\n_p(4,'AdditionalOptions=\"%s\"',premake.esc(table.concat(o,\" \")))end\nif#e.links>0 then\n_p(4,'AdditionalDependencies=\"%s" + "\"',table.concat(premake.getlinks(e,\"all\",\"fullpath\"),\" \"))end\n_p(4,'OutputFile=\"$(OutDir)\\\\%s\"',e.buildtarget.name)if#e.libdirs>0 then\n_p(4,'AdditionalLibraryDirectories=\"%s\"',premake.esc(path.translate(table.concat(e.libdirs,\";\"))))end\nend\n_p(3,'/>')end\nfunction o.VCResourceCompilerTool(e)_p(3,'<Tool')_p(4,'Name=\"VCResourceCompilerTool\"')if#e.resoptions>0 then\n_p(4,'AdditionalOptions=\"%s\"',table.concat(premake.esc(e.resoptions),\" \"))end\nif#e.defines>0 or#e.resdefines>0 then\n_p(4,'PreprocessorDefinitions=\"%s\"',table.concat(premake.esc(table.join(e.defines,e.resdefines)),\";\"))end\nif#e.includedirs>0 or#e.resincludedirs>0 then\nlocal e=table.join(e.includedirs,e.resincludedirs)_p(4,'AdditionalIncludeDirectories=\"%s\"',premake.esc(path.translate(table.concat(e,\";\"),'\\\\')))end\n_p(3,'/>')end\nfunction o.VCManifestTool(o)local e={}for n,o in ipairs(o.files)do\nif path.getextension(o)==\".manifest\"then\ntable.insert(e,o)end\nend\n_p(3,'<Tool')_p(4,'Name=\"VCManifestTool\"')if#e" + ">0 then\n_p(4,'AdditionalManifestFiles=\"%s\"',premake.esc(table.concat(e,\";\")))end\n_p(3,'/>')end\nfunction o.VCMIDLTool(e)_p(3,'<Tool')_p(4,'Name=\"VCMIDLTool\"')if e.platform==\"x64\"then\n_p(4,'TargetEnvironment=\"3\"')end\n_p(3,'/>')end\nfunction o.buildstepsblock(n,e)_p(3,'<Tool')_p(4,'Name=\"%s\"',n)if#e>0 then\n_p(4,'CommandLine=\"%s\"',premake.esc(table.implode(e,\"\",\"\",\"\\r\\n\")))end\n_p(3,'/>')end\no.toolmap={VCCLCompilerTool=o.VCCLCompilerTool,VCCLCompilerTool_PS3=o.VCCLCompilerTool_PS3,VCLinkerTool=o.VCLinkerTool,VCLinkerTool_PS3=o.VCLinkerTool_PS3,VCManifestTool=o.VCManifestTool,VCMIDLTool=o.VCMIDLTool,VCResourceCompilerTool=o.VCResourceCompilerTool,VCPreBuildEventTool=function(e)o.buildstepsblock(\"VCPreBuildEventTool\",e.prebuildcommands)end,VCPreLinkEventTool=function(e)o.buildstepsblock(\"VCPreLinkEventTool\",e.prelinkcommands)end,VCPostBuildEventTool=function(e)o.buildstepsblock(\"VCPostBuildEventTool\",e.postbuildcommands)end,}local function i(o,e)if o==\"vs2002\"then\nreturn{\"VCCLC" + "ompilerTool\",\"VCCustomBuildTool\",\"VCLinkerTool\",\"VCMIDLTool\",\"VCPostBuildEventTool\",\"VCPreBuildEventTool\",\"VCPreLinkEventTool\",\"VCResourceCompilerTool\",\"VCWebServiceProxyGeneratorTool\",\"VCWebDeploymentTool\"}end\nif o==\"vs2003\"then\nreturn{\"VCCLCompilerTool\",\"VCCustomBuildTool\",\"VCLinkerTool\",\"VCMIDLTool\",\"VCPostBuildEventTool\",\"VCPreBuildEventTool\",\"VCPreLinkEventTool\",\"VCResourceCompilerTool\",\"VCWebServiceProxyGeneratorTool\",\"VCXMLDataGeneratorTool\",\"VCWebDeploymentTool\",\"VCManagedWrapperGeneratorTool\",\"VCAuxiliaryManagedWrapperGeneratorTool\"}end\nif e==\"Xbox360\"then\nreturn{\"VCPreBuildEventTool\",\"VCCustomBuildTool\",\"VCXMLDataGeneratorTool\",\"VCWebServiceProxyGeneratorTool\",\"VCMIDLTool\",\"VCCLCompilerTool\",\"VCManagedResourceCompilerTool\",\"VCResourceCompilerTool\",\"VCPreLinkEventTool\",\"VCLinkerTool\",\"VCALinkTool\",\"VCX360ImageTool\",\"VCBscMakeTool\",\"VCX360DeploymentTool\",\"VCPostBuildEventTool\",\"DebuggerTool\",}end\nif e==\"PS3\"then\nre" + "turn{\"VCPreBuildEventTool\",\"VCCustomBuildTool\",\"VCXMLDataGeneratorTool\",\"VCWebServiceProxyGeneratorTool\",\"VCMIDLTool\",\"VCCLCompilerTool_PS3\",\"VCManagedResourceCompilerTool\",\"VCResourceCompilerTool\",\"VCPreLinkEventTool\",\"VCLinkerTool_PS3\",\"VCALinkTool\",\"VCManifestTool\",\"VCXDCMakeTool\",\"VCBscMakeTool\",\"VCFxCopTool\",\"VCAppVerifierTool\",\"VCWebDeploymentTool\",\"VCPostBuildEventTool\"}else\nreturn{\"VCPreBuildEventTool\",\"VCCustomBuildTool\",\"VCXMLDataGeneratorTool\",\"VCWebServiceProxyGeneratorTool\",\"VCMIDLTool\",\"VCCLCompilerTool\",\"VCManagedResourceCompilerTool\",\"VCResourceCompilerTool\",\"VCPreLinkEventTool\",\"VCLinkerTool\",\"VCALinkTool\",\"VCManifestTool\",\"VCXDCMakeTool\",\"VCBscMakeTool\",\"VCFxCopTool\",\"VCAppVerifierTool\",\"VCWebDeploymentTool\",\"VCPostBuildEventTool\"}end\nend\nfunction o.generate(e)o.header('VisualStudioProject')_p(1,'Name=\"%s\"',premake.esc(e.name))_p(1,'ProjectGUID=\"{%s}\"',e.uuid)if _ACTION>\"vs2003\"then\n_p(1,'RootNamespace=\"%s\"',e" + ".name)end\n_p(1,'Keyword=\"%s\"',iif(e.flags.Managed,\"ManagedCProj\",\"Win32Proj\"))_p(1,'>')o.Platforms(e)if _ACTION>\"vs2003\"then\n_p(1,'<ToolFiles>')_p(1,'</ToolFiles>')end\n_p(1,'<Configurations>')for t,n in ipairs(e.solution.vstudio_configs)do\nif n.isreal then\nlocal e=premake.getconfig(e,n.src_buildcfg,n.src_platform)o.Configuration(n.name,e)for i,n in ipairs(i(_ACTION,n.src_platform))do\nif o.toolmap[n]then\no.toolmap[n](e)elseif n==\"VCX360DeploymentTool\"then\n_p(3,'<Tool')_p(4,'Name=\"VCX360DeploymentTool\"')_p(4,'DeploymentType=\"0\"')if#e.deploymentoptions>0 then\n_p(4,'AdditionalOptions=\"%s\"',table.concat(premake.esc(e.deploymentoptions),\" \"))end\n_p(3,'/>')elseif n==\"VCX360ImageTool\"then\n_p(3,'<Tool')_p(4,'Name=\"VCX360ImageTool\"')if#e.imageoptions>0 then\n_p(4,'AdditionalOptions=\"%s\"',table.concat(premake.esc(e.imageoptions),\" \"))end\nif e.imagepath~=nil then\n_p(4,'OutputFileName=\"%s\"',premake.esc(path.translate(e.imagepath)))end\n_p(3,'/>')elseif n==\"DebuggerTool\"then\n_p(3," + "'<DebuggerTool')_p(3,'/>')else\n_p(3,'<Tool')_p(4,'Name=\"%s\"',n)_p(3,'/>')end\nend\n_p(2,'</Configuration>')end\nend\n_p(1,'</Configurations>')_p(1,'<References>')_p(1,'</References>')_p(1,'<Files>')o.Files(e)_p(1,'</Files>')_p(1,'<Globals>')_p(1,'</Globals>')_p('</VisualStudioProject>')end", + + /* actions/vstudio/vs200x_vcproj_user.lua */ + "local e=premake.vstudio.vc200x\nfunction e.generate_user(i)e.header('VisualStudioUserFile')_p(1,'ShowAllFiles=\"false\"')_p(1,'>')_p(1,'<Configurations>')for r,n in ipairs(i.solution.vstudio_configs)do\nif n.isreal then\nlocal i=premake.getconfig(i,n.src_buildcfg,n.src_platform)_p(2,'<Configuration')_p(3,'Name=\"%s\"',premake.esc(n.name))_p(3,'>')e.debugdir(i)_p(2,'</Configuration>')end\nend\n_p(1,'</Configurations>')_p('</VisualStudioUserFile>')end\nfunction e.environmentargs(e)if e.environmentargs and#e.environmentargs>0 then\n_p(4,'Environment=\"%s\"',string.gsub(table.concat(e.environmentargs,\"
\"),'\"','"'))if e.flags.EnvironmentArgsDontMerge then\n_p(4,'EnvironmentMerge=\"false\"')end\nend\nend\nfunction e.debugdir(n)_p(3,'<DebugSettings')if n.debugdir then\n_p(4,'WorkingDirectory=\"%s\"',path.translate(n.debugdir,'\\\\'))end\nif#n.debugargs>0 then\n_p(4,'CommandArguments=\"%s\"',table.concat(n.debugargs,\" \"))end\ne.environmentargs(n)_p(3,'/>')end", + + /* actions/vstudio/vs2003_solution.lua */ + "premake.vstudio.sln2003={}local i=premake.vstudio\nlocal o=premake.vstudio.sln2003\nfunction o.generate(o)io.indent=nil\nio.eol='\\r\\n'o.vstudio_configs=premake.vstudio.buildconfigs(o)_p('Microsoft Visual Studio Solution File, Format Version 8.00')for t in premake.solution.eachproject(o)do\nlocal o=path.translate(path.getrelative(o.location,i.projectfile(t)))_p('Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"',i.tool(t),t.name,o,t.uuid)local o=premake.getdependencies(t)if#o>0 then\n_p('\\tProjectSection(ProjectDependencies) = postProject')for t,o in ipairs(o)do\n_p('\\t\\t{%s} = {%s}',o.uuid,o.uuid)end\n_p('\\tEndProjectSection')end\n_p('EndProject')end\n_p('Global')_p('\\tGlobalSection(SolutionConfiguration) = preSolution')for t,o in ipairs(o.configurations)do\n_p('\\t\\t%s = %s',o,o)end\n_p('\\tEndGlobalSection')_p('\\tGlobalSection(ProjectDependencies) = postSolution')_p('\\tEndGlobalSection')_p('\\tGlobalSection(ProjectConfiguration) = postSolution')for t in premake.solution.eachproject(o)do\nfor e,o in ipai" + "rs(o.configurations)do\n_p('\\t\\t{%s}.%s.ActiveCfg = %s|%s',t.uuid,o,o,i.arch(t))_p('\\t\\t{%s}.%s.Build.0 = %s|%s',t.uuid,o,o,i.arch(t))end\nend\n_p('\\tEndGlobalSection')_p('\\tGlobalSection(ExtensibilityGlobals) = postSolution')_p('\\tEndGlobalSection')_p('\\tGlobalSection(ExtensibilityAddIns) = postSolution')_p('\\tEndGlobalSection')_p('EndGlobal')end", + + /* actions/vstudio/vs2005_solution.lua */ + "premake.vstudio.sln2005={}local t=premake.vstudio\nlocal o=premake.vstudio.sln2005\nfunction o.generate(e)io.indent=nil\nio.eol='\\r\\n'e.vstudio_configs=premake.vstudio.buildconfigs(e)_p('')o.header(e)for e in premake.solution.eachproject(e)do\no.project(e)end\n_p('Global')o.platforms(e)o.project_platforms(e)o.properties(e)_p('EndGlobal')end\nfunction o.header(o)local o=premake.action.current()_p('Microsoft Visual Studio Solution File, Format Version %d.00',o.vstudio.solutionVersion)_p('# Visual Studio %s',_ACTION:sub(3))end\nfunction o.project(e)local n=path.translate(path.getrelative(e.solution.location,t.projectfile(e)),\"\\\\\")_p('Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"',t.tool(e),e.name,n,e.uuid)o.projectdependencies(e)_p('EndProject')end\nfunction o.projectdependencies(o)local o=premake.getdependencies(o)if#o>0 then\n_p('\\tProjectSection(ProjectDependencies) = postProject')for e,o in ipairs(o)do\n_p('\\t\\t{%s} = {%s}',o.uuid,o.uuid)end\n_p('\\tEndProjectSection')end\nend\nfunction o.platforms" + "(o)_p('\\tGlobalSection(SolutionConfigurationPlatforms) = preSolution')for e,o in ipairs(o.vstudio_configs)do\n_p('\\t\\t%s = %s',o.name,o.name)end\n_p('\\tEndGlobalSection')end\nfunction o.project_platforms_sln2prj_mapping(n,t,o,e)_p('\\t\\t{%s}.%s.ActiveCfg = %s|%s',t.uuid,o.name,o.buildcfg,e)if e==o.platform or o.platform==\"Mixed Platforms\"then\n_p('\\t\\t{%s}.%s.Build.0 = %s|%s',t.uuid,o.name,o.buildcfg,e)end\nend\nfunction o.project_platforms(e)_p('\\tGlobalSection(ProjectConfigurationPlatforms) = postSolution')for i in premake.solution.eachproject(e)do\nfor n,t in ipairs(e.vstudio_configs)do\nlocal n\nif premake.isdotnetproject(i)then\nn=\"Any CPU\"else\nif t.platform==\"Any CPU\"or t.platform==\"Mixed Platforms\"then\nn=e.vstudio_configs[3].platform\nelse\nn=t.platform\nend\nend\no.project_platforms_sln2prj_mapping(e,i,t,n)end\nend\n_p('\\tEndGlobalSection')end\nfunction o.properties(o)_p('\\tGlobalSection(SolutionProperties) = preSolution')_p('\\t\\tHideSolutionNode = FALSE')_p('\\tEndGlobalSection')" + "end", + + /* actions/vstudio/vs2005_csproj.lua */ + "premake.vstudio.cs2005={}local s=premake.vstudio\nlocal e=premake.vstudio.cs2005\nlocal function o(t,r,e)if r==\"Compile\"and e:endswith(\".cs\")then\nif e:endswith(\".Designer.cs\")then\nlocal n=e:sub(1,-13)local e=n..\".cs\"if premake.findfile(t,e)then\nreturn\"Dependency\",e\nend\ne=n..\".resx\"if premake.findfile(t,e)then\nreturn\"AutoGen\",e\nend\nelseif e:endswith(\".xaml.cs\")then\nlocal e=e:sub(1,-9)local e=e..\".xaml\"if premake.findfile(t,e)then\nreturn\"SubTypeCode\",e\nend\nelse\nlocal e=e:sub(1,-4)local e=e..\".Designer.cs\"if premake.findfile(t,e)then\nreturn\"SubTypeForm\"end\nend\nend\nif r==\"EmbeddedResource\"and e:endswith(\".resx\")then\nlocal n=e:sub(1,-6)local e=path.getname(n..\".cs\")if premake.findfile(t,e)then\nif premake.findfile(t,n..\".Designer.cs\")then\nreturn\"DesignerType\",e\nelse\nreturn\"Dependency\",e\nend\nelse\ne=path.getname(n..\".Designer.cs\")if premake.findfile(t,e)then\nreturn\"AutoGenerated\"end\nend\nend\nif e:endswith(\".xaml\")then\nreturn\"XamlDesigner\"end\nif " + "r==\"Content\"then\nreturn\"CopyNewest\"end\nreturn\"None\"end\nfunction e.arch(e)return\"AnyCPU\"end\nfunction e.files(e)local t=premake.project.buildsourcetree(e)premake.tree.traverse(t,{onleaf=function(t)local n=premake.dotnet.getbuildaction(t.cfg)local r=path.translate(premake.esc(t.cfg.name),\"\\\\\")local e,o=o(e,n,t.path)if e==\"None\"then\n_p(' <%s Include=\"%s\" />',n,r)else\n_p(' <%s Include=\"%s\">',n,r)if e==\"AutoGen\"then\n_p(' <AutoGen>True</AutoGen>')elseif e==\"AutoGenerated\"then\n_p(' <SubType>Designer</SubType>')_p(' <Generator>ResXFileCodeGenerator</Generator>')_p(' <LastGenOutput>%s.Designer.cs</LastGenOutput>',premake.esc(path.getbasename(t.name)))elseif e==\"SubTypeDesigner\"then\n_p(' <SubType>Designer</SubType>')elseif e==\"SubTypeForm\"then\n_p(' <SubType>Form</SubType>')elseif e==\"SubTypeCode\"then\n_p(' <SubType>Code</SubType>')elseif e==\"XamlDesigner\"then\n_p(' <SubType>Designer</SubType>')_p(' <Generator>MSBuild:Compile</Gener" + "ator>')elseif e==\"PreserveNewest\"then\n_p(' <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>')end\nif o then\n_p(' <DependentUpon>%s</DependentUpon>',path.translate(premake.esc(o),\"\\\\\"))end\n_p(' </%s>',n)end\nend},false)end\nfunction e.projectelement(e)local t=premake.action.current()local e=''if t.vstudio.toolsVersion then\ne=string.format(' ToolsVersion=\"%s\"',t.vstudio.toolsVersion)end\nif _ACTION>\"vs2008\"then\n_p('<?xml version=\"1.0\" encoding=\"utf-8\"?>')end\n_p('<Project%s DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">',e)end\nfunction e.projectsettings(t)_p(' <PropertyGroup>')_p(\" <Configuration Condition=\\\" '$(Configuration)' == '' \\\">%s</Configuration>\",premake.esc(t.solution.configurations[1]))_p(\" <Platform Condition=\\\" '$(Platform)' == '' \\\">%s</Platform>\",e.arch(t))local e=premake.action.current()if e.vstudio.productVersion then\n_p(' <ProductVersion>%s</ProductVersion>',e.vstudio.productVersion)en" + "d\nif _ACTION<\"vs2012\"then\n_p(' <SchemaVersion>2.0</SchemaVersion>')end\n_p(' <ProjectGuid>{%s}</ProjectGuid>',t.uuid)_p(' <OutputType>%s</OutputType>',premake.dotnet.getkind(t))_p(' <AppDesignerFolder>Properties</AppDesignerFolder>')_p(' <RootNamespace>%s</RootNamespace>',t.buildtarget.basename)_p(' <AssemblyName>%s</AssemblyName>',t.buildtarget.basename)local e=t.framework or e.vstudio.targetFramework\nif e then\n_p(' <TargetFrameworkVersion>v%s</TargetFrameworkVersion>',e)end\nif _ACTION=='vs2010'then\n_p(' <TargetFrameworkProfile></TargetFrameworkProfile>')end\nif _ACTION>=\"vs2010\"then\n_p(' <FileAlignment>512</FileAlignment>')end\n_p(' </PropertyGroup>')end\nfunction e.propertygroup(t)_p(\" <PropertyGroup Condition=\\\" '$(Configuration)|$(Platform)' == '%s|%s' \\\">\",premake.esc(t.name),e.arch(t))if _ACTION>\"vs2008\"then\n_p(' <PlatformTarget>%s</PlatformTarget>',e.arch(t))end\nend\nfunction e.generate(n)io.eol=\"\\r\\n\"e.projectelement(n)if _ACTION>\"vs2010\"then" + "\n_p(' <Import Project=\"$(MSBuildExtensionsPath)\\\\$(MSBuildToolsVersion)\\\\Microsoft.Common.props\" Condition=\"Exists(\\'$(MSBuildExtensionsPath)\\\\$(MSBuildToolsVersion)\\\\Microsoft.Common.props\\')\" />')end\ne.projectsettings(n)for t in premake.eachconfig(n)do\ne.propertygroup(t)if t.flags.Symbols then\n_p(' <DebugSymbols>true</DebugSymbols>')_p(' <DebugType>full</DebugType>')else\n_p(' <DebugType>pdbonly</DebugType>')end\n_p(' <Optimize>%s</Optimize>',iif(t.flags.Optimize or t.flags.OptimizeSize or t.flags.OptimizeSpeed,\"true\",\"false\"))_p(' <OutputPath>%s</OutputPath>',t.buildtarget.directory)_p(' <DefineConstants>%s</DefineConstants>',table.concat(premake.esc(t.defines),\";\"))_p(' <ErrorReport>prompt</ErrorReport>')_p(' <WarningLevel>4</WarningLevel>')if t.flags.Unsafe then\n_p(' <AllowUnsafeBlocks>true</AllowUnsafeBlocks>')end\nif t.flags.FatalWarnings then\n_p(' <TreatWarningsAsErrors>true</TreatWarningsAsErrors>')end\n_p(' </PropertyGroup>')end\n_p(' <ItemGr" + "oup>')for t,e in ipairs(premake.getlinks(n,\"siblings\",\"object\"))do\n_p(' <ProjectReference Include=\"%s\">',path.translate(path.getrelative(n.location,s.projectfile(e)),\"\\\\\"))_p(' <Project>{%s}</Project>',e.uuid)_p(' <Name>%s</Name>',premake.esc(e.name))_p(' </ProjectReference>')end\nfor t,e in ipairs(premake.getlinks(n,\"system\",\"name\"))do\n_p(' <Reference Include=\"%s\" />',premake.esc(e))end\n_p(' </ItemGroup>')_p(' <ItemGroup>')e.files(n)_p(' </ItemGroup>')local e=iif(_ACTION<\"vs2012\",\"Bin\",\"Tools\")_p(' <Import Project=\"$(MSBuild%sPath)\\\\Microsoft.CSharp.targets\" />',e)_p(' <!-- To modify your build process, add your task inside one of the targets below and uncomment it.')_p(' Other similar extension points exist, see Microsoft.Common.targets.')_p(' <Target Name=\"BeforeBuild\">')_p(' </Target>')_p(' <Target Name=\"AfterBuild\">')_p(' </Target>')_p(' -->')_p('</Project>')end", + + /* actions/vstudio/vs2005_csproj_user.lua */ + "local e=premake.vstudio.cs2005\nfunction e.generate_user(e)io.eol=\"\\r\\n\"_p('<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">')_p(' <PropertyGroup>')local e=table.translate(e.libdirs,function(t)return path.getabsolute(e.location..\"/\"..t)end)_p(' <ReferencePath>%s</ReferencePath>',path.translate(table.concat(e,\";\"),\"\\\\\"))_p(' </PropertyGroup>')_p('</Project>')end", + + /* actions/vstudio/vs2010_vcxproj.lua */ + "premake.vstudio.vc2010={}local e=premake.vstudio.vc2010\nlocal s=premake.vstudio\nlocal function p(e)_p(1,'<ItemGroup Label=\"ProjectConfigurations\">')for n,e in ipairs(e.solution.vstudio_configs)do\n_p(2,'<ProjectConfiguration Include=\"%s\">',premake.esc(e.name))_p(3,'<Configuration>%s</Configuration>',e.buildcfg)_p(3,'<Platform>%s</Platform>',e.platform)_p(2,'</ProjectConfiguration>')end\n_p(1,'</ItemGroup>')end\nlocal function d(e)_p(1,'<PropertyGroup Label=\"Globals\">')_p(2,'<ProjectGuid>{%s}</ProjectGuid>',e.uuid)_p(2,'<RootNamespace>%s</RootNamespace>',e.name)if e.flags and e.flags.Managed then\n_p(2,'<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>')_p(2,'<Keyword>ManagedCProj</Keyword>')else\n_p(2,'<Keyword>Win32Proj</Keyword>')end\n_p(1,'</PropertyGroup>')end\nfunction e.config_type(e)local n={SharedLib=\"DynamicLibrary\",StaticLib=\"StaticLibrary\",ConsoleApp=\"Application\",WindowedApp=\"Application\"}return n[e.kind]end\nlocal function i()return\"Condition=\\\"'$(Configuration)|$(Platform)'" + "=='%s'\\\"\"end\nlocal function o(n)local e=\"Disabled\"for i,n in ipairs(n.flags)do\nif(n==\"Optimize\")then\ne=\"Full\"elseif(n==\"OptimizeSize\")then\ne=\"MinSpace\"elseif(n==\"OptimizeSpeed\")then\ne=\"MaxSpeed\"end\nend\nreturn e\nend\nfunction e.configurationPropertyGroup(n,t)_p(1,'<PropertyGroup '..i()..' Label=\"Configuration\">',premake.esc(t.name))_p(2,'<ConfigurationType>%s</ConfigurationType>',e.config_type(n))_p(2,'<UseDebugLibraries>%s</UseDebugLibraries>',iif(o(n)==\"Disabled\",\"true\",\"false\"))_p(2,'<CharacterSet>%s</CharacterSet>',iif(n.flags.Unicode,\"Unicode\",\"MultiByte\"))local e={vs2012=\"v110\",vs2013=\"v120\",vs2015=\"v140\"}local e=e[_ACTION]if e then\n_p(2,'<PlatformToolset>%s</PlatformToolset>',e)end\nif n.flags.MFC then\n_p(2,'<UseOfMfc>%s</UseOfMfc>',iif(n.flags.StaticRuntime,\"Static\",\"Dynamic\"))end\nif n.flags.ATL or n.flags.StaticATL then\n_p(2,'<UseOfAtl>%s</UseOfAtl>',iif(n.flags.StaticATL,\"Static\",\"Dynamic\"))end\nif n.flags.Managed then\n_p(2,'<CLRSupport>true</CLR" + "Support>')end\n_p(1,'</PropertyGroup>')end\nlocal function a(n)for t,e in ipairs(n.solution.vstudio_configs)do\nlocal n=premake.getconfig(n,e.src_buildcfg,e.src_platform)_p(1,'<ImportGroup '..i()..' Label=\"PropertySheets\">',premake.esc(e.name))_p(2,'<Import Project=\"$(UserRootDir)\\\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists(\\'$(UserRootDir)\\\\Microsoft.Cpp.$(Platform).user.props\\')\" Label=\"LocalAppDataPlatform\" />')_p(1,'</ImportGroup>')end\nend\nfunction e.outputProperties(e)for n,t in ipairs(e.solution.vstudio_configs)do\nlocal e=premake.getconfig(e,t.src_buildcfg,t.src_platform)local n=e.buildtarget\n_p(1,'<PropertyGroup '..i()..'>',premake.esc(t.name))_p(2,'<OutDir>%s\\\\</OutDir>',premake.esc(n.directory))if e.platform==\"Xbox360\"then\n_p(2,'<OutputFile>$(OutDir)%s</OutputFile>',premake.esc(n.name))end\n_p(2,'<IntDir>%s\\\\</IntDir>',premake.esc(e.objectsdir))_p(2,'<TargetName>%s</TargetName>',premake.esc(path.getbasename(n.name)))_p(2,'<TargetExt>%s</TargetExt>',premake.esc(pat" + "h.getextension(n.name)))if e.kind==\"SharedLib\"then\nlocal e=(e.flags.NoImportLib~=nil)_p(2,'<IgnoreImportLibrary>%s</IgnoreImportLibrary>',tostring(e))end\nif e.kind~=\"StaticLib\"then\n_p(2,'<LinkIncremental>%s</LinkIncremental>',tostring(premake.config.isincrementallink(e)))end\nif e.flags.NoManifest then\n_p(2,'<GenerateManifest>false</GenerateManifest>')end\n_p(1,'</PropertyGroup>')end\nend\nlocal function f(i)local n\nlocal e=i.flags\nif premake.config.isdebugbuild(i)then\nn=iif(e.StaticRuntime and not e.Managed,\"MultiThreadedDebug\",\"MultiThreadedDebugDLL\")else\nn=iif(e.StaticRuntime and not e.Managed,\"MultiThreaded\",\"MultiThreadedDLL\")end\nreturn n\nend\nlocal function c(e)if not e.flags.NoPCH and e.pchheader then\n_p(3,'<PrecompiledHeader>Use</PrecompiledHeader>')_p(3,'<PrecompiledHeaderFile>%s</PrecompiledHeaderFile>',e.pchheader)else\n_p(3,'<PrecompiledHeader></PrecompiledHeader>')end\nend\nlocal function t(n,e)if#e.defines>0 then\n_p(n,'<PreprocessorDefinitions>%s;%%(PreprocessorDefinitions" + ")</PreprocessorDefinitions>',premake.esc(table.concat(e.defines,\";\")))else\n_p(n,'<PreprocessorDefinitions></PreprocessorDefinitions>')end\nend\nlocal function P(n,e)if#e.includedirs>0 then\n_p(n,'<AdditionalIncludeDirectories>%s;%%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>',premake.esc(path.translate(table.concat(e.includedirs,\";\"),'\\\\')))end\nend\nlocal function n(n,e)if#e.includedirs>0 or#e.resincludedirs>0 then\nlocal e=table.join(e.includedirs,e.resincludedirs)_p(n,'<AdditionalIncludeDirectories>%s;%%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>',premake.esc(path.translate(table.concat(e,\";\"),'\\\\')))end\nend\nlocal function g(e)_p(2,'<ResourceCompile>')t(3,e)n(3,e)_p(2,'</ResourceCompile>')end\nlocal function m(e)if e.flags.NoExceptions then\n_p(2,'<ExceptionHandling>false</ExceptionHandling>')elseif e.flags.SEH then\n_p(2,'<ExceptionHandling>Async</ExceptionHandling>')end\nend\nlocal function u(e)if e.flags.NoRTTI and not e.flags.Managed then\n_p(3,'<RuntimeTy" + "peInfo>false</RuntimeTypeInfo>')end\nend\nlocal function _(e)if e.flags.NativeWChar then\n_p(3,'<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>')elseif e.flags.NoNativeWChar then\n_p(3,'<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>')end\nend\nlocal function C(e)if e.flags.EnableSSE then\n_p(3,'<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>')elseif e.flags.EnableSSE2 then\n_p(3,'<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>')end\nend\nlocal function l(e)if e.flags.FloatFast then\n_p(3,'<FloatingPointModel>Fast</FloatingPointModel>')elseif e.flags.FloatStrict and not e.flags.Managed then\n_p(3,'<FloatingPointModel>Strict</FloatingPointModel>')end\nend\nlocal function r(e)local n=''if e.flags.Symbols then\nif e.platform==\"x64\"or e.flags.Managed\nor premake.config.isoptimizedbuild(e.flags)or e.flags.NoEditAndContinue\nthen\nn=\"ProgramDatabase\"else\nn=\"EditAndContinue\"end\nend\n_p(3,'<DebugInformationForma" + "t>%s</DebugInformationFormat>',n)end\nlocal function h(e)if premake.config.isdebugbuild(e)and not e.flags.NoMinimalRebuild then\n_p(3,'<MinimalRebuild>true</MinimalRebuild>')else\n_p(3,'<MinimalRebuild>false</MinimalRebuild>')end\nend\nlocal function n(e)if e.language==\"C\"then\n_p(3,'<CompileAs>CompileAsC</CompileAs>')end\nend\nlocal function b(e)_p(2,'<ClCompile>')if#e.buildoptions>0 then\n_p(3,'<AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>',table.concat(premake.esc(e.buildoptions),\" \"))end\n_p(3,'<Optimization>%s</Optimization>',o(e))P(3,e)t(3,e)h(e)if not premake.config.isoptimizedbuild(e.flags)then\nif not e.flags.Managed then\n_p(3,'<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>')end\nif e.flags.ExtraWarnings then\n_p(3,'<SmallerTypeCheck>true</SmallerTypeCheck>')end\nelse\n_p(3,'<StringPooling>true</StringPooling>')end\n_p(3,'<RuntimeLibrary>%s</RuntimeLibrary>',f(e))_p(3,'<FunctionLevelLinking>true</FunctionLevelLinking>')c(e)if e.flags.ExtraWarnings then\n_p(3,'<Warning" + "Level>Level4</WarningLevel>')else\n_p(3,'<WarningLevel>Level3</WarningLevel>')end\nif e.flags.FatalWarnings then\n_p(3,'<TreatWarningAsError>true</TreatWarningAsError>')end\nm(e)u(e)_(e)C(e)l(e)r(e)if e.flags.Symbols then\n_p(3,'<ProgramDataBaseFileName>$(OutDir)%s.pdb</ProgramDataBaseFileName>',path.getbasename(e.buildtarget.name))end\nif e.flags.NoFramePointer then\n_p(3,'<OmitFramePointers>true</OmitFramePointers>')end\nn(e)_p(2,'</ClCompile>')end\nlocal function r(e)if#e.postbuildcommands>0 then\n_p(2,'<PostBuildEvent>')_p(3,'<Command>%s</Command>',premake.esc(table.implode(e.postbuildcommands,\"\",\"\",\"\\r\\n\")))_p(2,'</PostBuildEvent>')end\nif#e.prebuildcommands>0 then\n_p(2,'<PreBuildEvent>')_p(3,'<Command>%s</Command>',premake.esc(table.implode(e.prebuildcommands,\"\",\"\",\"\\r\\n\")))_p(2,'</PreBuildEvent>')end\nif#e.prelinkcommands>0 then\n_p(2,'<PreLinkEvent>')_p(3,'<Command>%s</Command>',premake.esc(table.implode(e.prelinkcommands,\"\",\"\",\"\\r\\n\")))_p(2,'</PreLinkEvent>')end\nend\nlocal fu" + "nction o(n,e)if#e.linkoptions>0 then\n_p(n,'<AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>',table.concat(premake.esc(e.linkoptions),\" \"))end\nend\nlocal function t(i,e)local n={x32='MachineX86',x64='MachineX64'}if n[e.platform]then\n_p(i,'<TargetMachine>%s</TargetMachine>',n[e.platform])end\nend\nlocal function c(e)if e.kind=='StaticLib'and e.platform~=\"Xbox360\"then\n_p(1,'<Lib>')_p(2,'<OutputFile>$(OutDir)%s</OutputFile>',e.buildtarget.name)o(2,e)t(2,e)_p(1,'</Lib>')end\nend\nlocal function l(e)if e.kind==\"SharedLib\"then\nlocal n=e.linktarget.fullpath\n_p(3,'<ImportLibrary>%s</ImportLibrary>',iif(e.flags.NoImportLib,e.objectsdir..\"\\\\\"..path.getname(n),n))end\nend\nfunction e.link(n)_p(2,'<Link>')_p(3,'<SubSystem>%s</SubSystem>',iif(n.kind==\"ConsoleApp\",\"Console\",\"Windows\"))_p(3,'<GenerateDebugInformation>%s</GenerateDebugInformation>',tostring(n.flags.Symbols~=nil))if premake.config.isoptimizedbuild(n.flags)then\n_p(3,'<EnableCOMDATFolding>true</EnableCOMDATFolding>')_p(3,'<Op" + "timizeReferences>true</OptimizeReferences>')end\nif n.kind~='StaticLib'then\ne.additionalDependencies(n)_p(3,'<OutputFile>$(OutDir)%s</OutputFile>',n.buildtarget.name)if#n.libdirs>0 then\n_p(3,'<AdditionalLibraryDirectories>%s;%%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>',premake.esc(path.translate(table.concat(n.libdirs,';'),'\\\\')))end\nif e.config_type(n)=='Application'and not n.flags.WinMain and not n.flags.Managed then\n_p(3,'<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>')end\nl(n)local e=premake.findfile(n,\".def\")if e then\n_p(3,'<ModuleDefinitionFile>%s</ModuleDefinitionFile>',e)end\nt(3,n)o(3,n)end\n_p(2,'</Link>')end\nfunction e.additionalDependencies(e)local e=premake.getlinks(e,\"system\",\"fullpath\")if#e>0 then\n_p(3,'<AdditionalDependencies>%s;%%(AdditionalDependencies)</AdditionalDependencies>',table.concat(e,\";\"))end\nend\nlocal function l(n)for o,t in ipairs(n.solution.vstudio_configs)do\nlocal n=premake.getconfig(n,t.src_buildcfg,t.src_platform)_p(1,'<ItemDefinit" + "ionGroup '..i()..'>',premake.esc(t.name))b(n)g(n)c(n)e.link(n)r(n)_p(1,'</ItemDefinitionGroup>')end\nend\nfunction e.getfilegroup(i,t)local e=i.vc2010sortedfiles\nif not e then\ne={ClCompile={},ClInclude={},None={},ResourceCompile={},}for n in premake.project.eachfile(i)do\nif path.iscppfile(n.name)then\ntable.insert(e.ClCompile,n)elseif path.iscppheader(n.name)then\ntable.insert(e.ClInclude,n)elseif path.isresourcefile(n.name)then\ntable.insert(e.ResourceCompile,n)else\ntable.insert(e.None,n)end\nend\ni.vc2010sortedfiles=e\nend\nreturn e[t]end\nfunction e.files(n)e.simplefilesgroup(n,\"ClInclude\")e.compilerfilesgroup(n)e.simplefilesgroup(n,\"None\")e.simplefilesgroup(n,\"ResourceCompile\")end\nfunction e.simplefilesgroup(i,n)local e=e.getfilegroup(i,n)if#e>0 then\n_p(1,'<ItemGroup>')for i,e in ipairs(e)do\n_p(2,'<%s Include=\"%s\" />',n,path.translate(e.name,\"\\\\\"))end\n_p(1,'</ItemGroup>')end\nend\nfunction e.compilerfilesgroup(n)local t=n.solution.vstudio_configs\nlocal o=e.getfilegroup(n,\"ClCompile\")" + "if#o>0 then\nlocal e={}for t,i in ipairs(t)do\nlocal n=premake.getconfig(n,i.src_buildcfg,i.src_platform)if n.pchheader and n.pchsource and not n.flags.NoPCH then\ne[i]=path.translate(n.pchsource,\"\\\\\")end\nend\n_p(1,'<ItemGroup>')for o,n in ipairs(o)do\nlocal o=path.translate(n.name,\"\\\\\")_p(2,'<ClCompile Include=\"%s\">',o)for t,n in ipairs(t)do\nif e[n]and o==e[n]then\n_p(3,'<PrecompiledHeader '..i()..'>Create</PrecompiledHeader>',premake.esc(n.name))e[n]=nil\nend\nend\n_p(2,'</ClCompile>')end\n_p(1,'</ItemGroup>')end\nend\nfunction e.header(e)io.eol=\"\\r\\n\"_p('<?xml version=\"1.0\" encoding=\"utf-8\"?>')local n=\"\"if e then\nn=' DefaultTargets=\"'..e..'\"'end\n_p('<Project%s ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">',n)end\nfunction premake.vs2010_vcxproj(n)io.indent=\" \"e.header(\"Build\")p(n)d(n)_p(1,'<Import Project=\"$(VCTargetsPath)\\\\Microsoft.Cpp.Default.props\" />')for t,i in ipairs(n.solution.vstudio_configs)do\nlocal n=premake.getconfig(n,i.s" + "rc_buildcfg,i.src_platform)e.configurationPropertyGroup(n,i)end\n_p(1,'<Import Project=\"$(VCTargetsPath)\\\\Microsoft.Cpp.props\" />')_p(1,'<ImportGroup Label=\"ExtensionSettings\">')_p(1,'</ImportGroup>')a(n)_p(1,'<PropertyGroup Label=\"UserMacros\" />')e.outputProperties(n)l(n)e.files(n)e.projectReferences(n)_p(1,'<Import Project=\"$(VCTargetsPath)\\\\Microsoft.Cpp.targets\" />')_p(1,'<ImportGroup Label=\"ExtensionTargets\">')_p(1,'</ImportGroup>')_p('</Project>')end\nfunction e.projectReferences(n)local e=premake.getdependencies(n)if#e>0 then\n_p(1,'<ItemGroup>')for i,e in ipairs(e)do\nlocal n=path.getrelative(n.location,s.projectfile(e))_p(2,'<ProjectReference Include=\"%s\">',path.translate(n,\"\\\\\"))_p(3,'<Project>{%s}</Project>',e.uuid)_p(2,'</ProjectReference>')end\n_p(1,'</ItemGroup>')end\nend\nfunction e.debugdir(e)if e.debugdir then\n_p(' <LocalDebuggerWorkingDirectory>%s</LocalDebuggerWorkingDirectory>',path.translate(e.debugdir,'\\\\'))_p(' <DebuggerFlavor>WindowsLocalDebugger</DebuggerFl" + "avor>')end\nif e.debugargs then\n_p(' <LocalDebuggerCommandArguments>%s</LocalDebuggerCommandArguments>',table.concat(e.debugargs,\" \"))end\nend\nfunction e.debugenvs(e)if e.debugenvs and#e.debugenvs>0 then\n_p(2,'<LocalDebuggerEnvironment>%s%s</LocalDebuggerEnvironment>',table.concat(e.debugenvs,\"\\n\"),iif(e.flags.DebugEnvsInherit,'\\n$(LocalDebuggerEnvironment)',''))if e.flags.DebugEnvsDontMerge then\n_p(2,'<LocalDebuggerMergeEnvironment>false</LocalDebuggerMergeEnvironment>')end\nend\nend\nfunction premake.vs2010_vcxproj_user(t)io.indent=\" \"e.header()for o,n in ipairs(t.solution.vstudio_configs)do\nlocal t=premake.getconfig(t,n.src_buildcfg,n.src_platform)_p(' <PropertyGroup '..i()..'>',premake.esc(n.name))e.debugdir(t)e.debugenvs(t)_p(' </PropertyGroup>')end\n_p('</Project>')end", + + /* actions/vstudio/vs2010_vcxproj_filters.lua */ + "local e=premake.vstudio.vc2010\nlocal i=premake.project\nfunction e.filteridgroup(e)local l={}local t=false\nfor e in i.eachfile(e)do\nlocal i=string.explode(e.vpath,\"/\",true)local e=\"\"for r=1,#i-1 do\nif not t then\nt=true\n_p(1,'<ItemGroup>')end\ne=e..i[r]if not l[e]then\nl[e]=true\n_p(2,'<Filter Include=\"%s\">',e)_p(3,'<UniqueIdentifier>{%s}</UniqueIdentifier>',os.uuid())_p(2,'</Filter>')end\ne=e..\"\\\\\"end\nend\nif t then\n_p(1,'</ItemGroup>')end\nend\nfunction e.filefiltergroup(l,t)local e=e.getfilegroup(l,t)if#e>0 then\n_p(1,'<ItemGroup>')for l,e in ipairs(e)do\nlocal l\nif e.name~=e.vpath then\nl=path.getdirectory(e.vpath)else\nl=path.getdirectory(e.name)end\nif l~=\".\"then\n_p(2,'<%s Include=\"%s\">',t,path.translate(e.name,\"\\\\\"))_p(3,'<Filter>%s</Filter>',path.translate(l,\"\\\\\"))_p(2,'</%s>',t)else\n_p(2,'<%s Include=\"%s\" />',t,path.translate(e.name,\"\\\\\"))end\nend\n_p(1,'</ItemGroup>')end\nend\nfunction e.generate_filters(t)io.indent=\" \"e.header()e.filteridgroup(t)e.filefilterg" + "roup(t,\"None\")e.filefiltergroup(t,\"ClInclude\")e.filefiltergroup(t,\"ClCompile\")e.filefiltergroup(t,\"ResourceCompile\")_p('</Project>')end", + + /* actions/vstudio/vs2012.lua */ + "premake.vstudio.vc2012={}local e=premake.vstudio.vc2012\nlocal r=premake.vstudio\nnewaction{trigger=\"vs2012\",shortname=\"Visual Studio 2012\",description=\"Generate Microsoft Visual Studio 2012 project files\",os=\"windows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(e)premake.generate(e,\"%%.sln\",r.sln2005.generate)end,onproject=function(e)if premake.isdotnetproject(e)then\npremake.generate(e,\"%%.csproj\",r.cs2005.generate)premake.generate(e,\"%%.csproj.user\",r.cs2005.generate_user)else\npremake.generate(e,\"%%.vcxproj\",premake.vs2010_vcxproj)premake.generate(e,\"%%.vcxproj.user\",premake.vs2010_vcxproj_user)premake.generate(e,\"%%.vcxproj.filters\",r.vc2010.generate_filters)end\nend,oncleansolution=premake.vstudio.cleansolution,oncleanproject=premake.vstudio.cleanproject,oncleantarget=premake.vstudio.cleantarget,vstudio={solutionVersion=\"12\",targetFramework=\"4.5\",t" + "oolsVersion=\"4.0\",}}", + + /* actions/vstudio/vs2013.lua */ + "premake.vstudio.vc2013={}local e=premake.vstudio.vc2013\nlocal r=premake.vstudio\nnewaction{trigger=\"vs2013\",shortname=\"Visual Studio 2013\",description=\"Generate Microsoft Visual Studio 2013 project files\",os=\"windows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(e)premake.generate(e,\"%%.sln\",r.sln2005.generate)end,onproject=function(e)if premake.isdotnetproject(e)then\npremake.generate(e,\"%%.csproj\",r.cs2005.generate)premake.generate(e,\"%%.csproj.user\",r.cs2005.generate_user)else\npremake.generate(e,\"%%.vcxproj\",premake.vs2010_vcxproj)premake.generate(e,\"%%.vcxproj.user\",premake.vs2010_vcxproj_user)premake.generate(e,\"%%.vcxproj.filters\",r.vc2010.generate_filters)end\nend,oncleansolution=premake.vstudio.cleansolution,oncleanproject=premake.vstudio.cleanproject,oncleantarget=premake.vstudio.cleantarget,vstudio={solutionVersion=\"12\",targetFramework=\"4.5\",t" + "oolsVersion=\"12.0\",}}", + + /* actions/vstudio/vs2015.lua */ + "premake.vstudio.vc2015={}local e=premake.vstudio.vc2015\nlocal r=premake.vstudio\nnewaction{trigger=\"vs2015\",shortname=\"Visual Studio 2015\",description=\"Generate Microsoft Visual Studio 2015 project files\",os=\"windows\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"StaticLib\",\"SharedLib\"},valid_languages={\"C\",\"C++\",\"C#\"},valid_tools={cc={\"msc\"},dotnet={\"msnet\"},},onsolution=function(e)premake.generate(e,\"%%.sln\",r.sln2005.generate)end,onproject=function(e)if premake.isdotnetproject(e)then\npremake.generate(e,\"%%.csproj\",r.cs2005.generate)premake.generate(e,\"%%.csproj.user\",r.cs2005.generate_user)else\npremake.generate(e,\"%%.vcxproj\",premake.vs2010_vcxproj)premake.generate(e,\"%%.vcxproj.user\",premake.vs2010_vcxproj_user)premake.generate(e,\"%%.vcxproj.filters\",r.vc2010.generate_filters)end\nend,oncleansolution=premake.vstudio.cleansolution,oncleanproject=premake.vstudio.cleanproject,oncleantarget=premake.vstudio.cleantarget,vstudio={solutionVersion=\"12\",targetFramework=\"4.5.2\"" + ",toolsVersion=\"14.0\",}}", + + /* actions/xcode/_xcode.lua */ + "premake.xcode={}newaction{trigger=\"xcode3\",shortname=\"Xcode 3\",description=\"Generate Apple Xcode 3 project files (experimental)\",os=\"macosx\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"SharedLib\",\"StaticLib\"},valid_languages={\"C\",\"C++\"},valid_tools={cc={\"gcc\"},},valid_platforms={Native=\"Native\",x32=\"Native 32-bit\",x64=\"Native 64-bit\",Universal32=\"32-bit Universal\",Universal64=\"64-bit Universal\",Universal=\"Universal\",},default_platform=\"Universal\",onsolution=function(e)premake.xcode.preparesolution(e)end,onproject=function(e)premake.generate(e,\"%%.xcodeproj/project.pbxproj\",premake.xcode.project)end,oncleanproject=function(e)premake.clean.directory(e,\"%%.xcodeproj\")end,oncheckproject=function(n)local e\nfor o in premake.eachconfig(n)do\nif e and e~=o.kind then\nerror(\"Project '\"..n.name..\"' uses more than one target kind; not supported by Xcode\",0)end\ne=o.kind\nend\nend,}newaction{trigger=\"xcode4\",shortname=\"Xcode 4\",description=\"Generate Apple Xcode 4 project file" + "s (experimental)\",os=\"macosx\",valid_kinds={\"ConsoleApp\",\"WindowedApp\",\"SharedLib\",\"StaticLib\"},valid_languages={\"C\",\"C++\"},valid_tools={cc={\"gcc\"},},valid_platforms={Native=\"Native\",x32=\"Native 32-bit\",x64=\"Native 64-bit\",Universal32=\"32-bit Universal\",Universal64=\"64-bit Universal\",Universal=\"Universal\",},default_platform=\"Universal\",onsolution=function(e)premake.generate(e,\"%%.xcworkspace/contents.xcworkspacedata\",premake.xcode4.workspace_generate)end,onproject=function(e)premake.generate(e,\"%%.xcodeproj/project.pbxproj\",premake.xcode.project)end,oncleanproject=function(e)premake.clean.directory(e,\"%%.xcodeproj\")premake.clean.directory(e,\"%%.xcworkspace\")end,oncheckproject=function(o)local e\nfor n in premake.eachconfig(o)do\nif e and e~=n.kind then\nerror(\"Project '\"..o.name..\"' uses more than one target kind; not supported by Xcode\",0)end\ne=n.kind\nend\nend,}", + + /* actions/xcode/xcode_common.lua */ + "local e=premake.xcode\nlocal i=premake.tree\nfunction e.getbuildcategory(n)local e={[\".a\"]=\"Frameworks\",[\".c\"]=\"Sources\",[\".cc\"]=\"Sources\",[\".cpp\"]=\"Sources\",[\".cxx\"]=\"Sources\",[\".dylib\"]=\"Frameworks\",[\".framework\"]=\"Frameworks\",[\".m\"]=\"Sources\",[\".mm\"]=\"Sources\",[\".strings\"]=\"Resources\",[\".nib\"]=\"Resources\",[\".xib\"]=\"Resources\",[\".icns\"]=\"Resources\",[\".bmp\"]=\"Resources\",[\".wav\"]=\"Resources\",}return e[path.getextension(n.name)]end\nfunction e.getconfigname(e)local n=e.name\nif#e.project.solution.xcode.platforms>1 then\nn=n..\" \"..premake.action.current().valid_platforms[e.platform]end\nreturn n\nend\nfunction e.getfiletype(n)local e={[\".c\"]=\"sourcecode.c.c\",[\".cc\"]=\"sourcecode.cpp.cpp\",[\".cpp\"]=\"sourcecode.cpp.cpp\",[\".css\"]=\"text.css\",[\".cxx\"]=\"sourcecode.cpp.cpp\",[\".framework\"]=\"wrapper.framework\",[\".gif\"]=\"image.gif\",[\".h\"]=\"sourcecode.c.h\",[\".html\"]=\"text.html\",[\".lua\"]=\"sourcecode.lua\",[\".m\"]=\"sourcecode" + ".c.objc\",[\".mm\"]=\"sourcecode.cpp.objc\",[\".nib\"]=\"wrapper.nib\",[\".pch\"]=\"sourcecode.c.h\",[\".plist\"]=\"text.plist.xml\",[\".strings\"]=\"text.plist.strings\",[\".xib\"]=\"file.xib\",[\".icns\"]=\"image.icns\",[\".bmp\"]=\"image.bmp\",[\".wav\"]=\"audio.wav\",}return e[path.getextension(n.path)]or\"text\"end\nfunction e.getproducttype(n)local e={ConsoleApp=\"com.apple.product-type.tool\",WindowedApp=\"com.apple.product-type.application\",StaticLib=\"com.apple.product-type.library.static\",SharedLib=\"com.apple.product-type.library.dynamic\",}return e[n.cfg.kind]end\nfunction e.gettargettype(e)local n={ConsoleApp='\"compiled.mach-o.executable\"',WindowedApp=\"wrapper.application\",StaticLib=\"archive.ar\",SharedLib='\"compiled.mach-o.dylib\"',}return n[e.cfg.kind]end\nfunction e.getxcodeprojname(e)local e=premake.project.getfilename(e,\"%%.xcodeproj\")return e\nend\nfunction e.isframework(e)return(path.getextension(e)==\".framework\")end\nfunction e.newid()return string.format(\"%04X%04X%04X%04X%04X" + "%04X\",math.random(0,32767),math.random(0,32767),math.random(0,32767),math.random(0,32767),math.random(0,32767),math.random(0,32767))end\nfunction e.preparesolution(e)e.xcode={}e.xcode.platforms=premake.filterplatforms(e,premake.action.current().valid_platforms,\"Universal\")for n in premake.solution.eachproject(e)do\nlocal i=premake.getconfig(n,n.configurations[1],e.xcode.platforms[1])local e=premake.tree.new(path.getname(i.buildtarget.bundlepath))e.cfg=i\ne.id=premake.xcode.newid(e,\"product\")e.targetid=premake.xcode.newid(e,\"target\")n.xcode={}n.xcode.projectnode=e\nend\nend\nfunction e.printlist(e,n)if#e>0 then\n_p(4,'%s = (',n)for n,e in ipairs(e)do\nlocal e=e:gsub('\"','\\\\\"')_p(5,'\"%s\",',e)end\n_p(4,');')end\nend\nfunction e.Header()_p('// !$*UTF8*$!')_p('{')_p(1,'archiveVersion = 1;')_p(1,'classes = {')_p(1,'};')_p(1,'objectVersion = 45;')_p(1,'objects = {')_p('')end\nfunction e.PBXBuildFile(n)_p('/* Begin PBXBuildFile section */')i.traverse(n,{onnode=function(n)if n.buildid then\n_p(2,'%s /* %s " + "in %s */ = {isa = PBXBuildFile; fileRef = %s /* %s */; };',n.buildid,n.name,e.getbuildcategory(n),n.id,n.name)end\nend})_p('/* End PBXBuildFile section */')_p('')end\nfunction e.PBXContainerItemProxy(e)if#e.projects.children>0 then\n_p('/* Begin PBXContainerItemProxy section */')for n,e in ipairs(e.projects.children)do\n_p(2,'%s /* PBXContainerItemProxy */ = {',e.productproxyid)_p(3,'isa = PBXContainerItemProxy;')_p(3,'containerPortal = %s /* %s */;',e.id,path.getname(e.path))_p(3,'proxyType = 2;')_p(3,'remoteGlobalIDString = %s;',e.project.xcode.projectnode.id)_p(3,'remoteInfo = \"%s\";',e.project.xcode.projectnode.name)_p(2,'};')_p(2,'%s /* PBXContainerItemProxy */ = {',e.targetproxyid)_p(3,'isa = PBXContainerItemProxy;')_p(3,'containerPortal = %s /* %s */;',e.id,path.getname(e.path))_p(3,'proxyType = 1;')_p(3,'remoteGlobalIDString = %s;',e.project.xcode.projectnode.targetid)_p(3,'remoteInfo = \"%s\";',e.project.xcode.projectnode.name)_p(2,'};')end\n_p('/* End PBXContainerItemProxy section */')_p('')end\nend" + "\nfunction e.PBXFileReference(t)_p('/* Begin PBXFileReference section */')i.traverse(t,{onleaf=function(n)if not n.path then\nreturn\nend\nif n.kind==\"product\"then\n_p(2,'%s /* %s */ = {isa = PBXFileReference; explicitFileType = %s; includeInIndex = 0; name = \"%s\"; path = \"%s\"; sourceTree = BUILT_PRODUCTS_DIR; };',n.id,n.name,e.gettargettype(n),n.name,path.getname(n.cfg.buildtarget.bundlepath))elseif n.parent.parent==t.projects then\nlocal e=path.getrelative(t.project.location,n.parent.project.location)_p(2,'%s /* %s */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = \"%s\"; path = \"%s\"; sourceTree = SOURCE_ROOT; };',n.parent.id,n.parent.name,n.parent.name,path.join(e,n.parent.name))else\nlocal t,o\nif e.isframework(n.path)then\nlocal e=n.path\nlocal r,i,n=string.find(e,\"^%$%((.+)%)/\")if n then\ne=string.sub(e,i+1)end\nif string.find(e,'/')then\nif string.find(e,'^%.')then\nerror('relative paths are not currently supported for frameworks')end\nt=e\nelse\nt=\"/System/Libr" + "ary/Frameworks/\"..e\nend\nif n then\no=n\nif string.find(t,'^/')then\nt=string.sub(t,2)end\nelse\no=\"<absolute>\"end\nelse\no=\"<group>\"if n.parent.isvpath then\nt=n.cfg.name\nelse\nt=i.getlocalpath(n)end\nend\n_p(2,'%s /* %s */ = {isa = PBXFileReference; lastKnownFileType = %s; name = \"%s\"; path = \"%s\"; sourceTree = \"%s\"; };',n.id,n.name,e.getfiletype(n),n.name,t,o)end\nend})_p('/* End PBXFileReference section */')_p('')end\nfunction e.PBXFrameworksBuildPhase(e)_p('/* Begin PBXFrameworksBuildPhase section */')_p(2,'%s /* Frameworks */ = {',e.products.children[1].fxstageid)_p(3,'isa = PBXFrameworksBuildPhase;')_p(3,'buildActionMask = 2147483647;')_p(3,'files = (')i.traverse(e.frameworks,{onleaf=function(e)_p(4,'%s /* %s in Frameworks */,',e.buildid,e.name)end})i.traverse(e.projects,{onleaf=function(e)_p(4,'%s /* %s in Frameworks */,',e.buildid,e.name)end})_p(3,');')_p(3,'runOnlyForDeploymentPostprocessing = 0;')_p(2,'};')_p('/* End PBXFrameworksBuildPhase section */')_p('')end\nfunction e.PBXGroup(n)_" + "p('/* Begin PBXGroup section */')i.traverse(n,{onnode=function(e)if(e.path and#e.children==0)or e.kind==\"vgroup\"then\nreturn\nend\nif e.parent==n.projects then\n_p(2,'%s /* Products */ = {',e.productgroupid)else\n_p(2,'%s /* %s */ = {',e.id,e.name)end\n_p(3,'isa = PBXGroup;')_p(3,'children = (')for n,e in ipairs(e.children)do\n_p(4,'%s /* %s */,',e.id,e.name)end\n_p(3,');')if e.parent==n.projects then\n_p(3,'name = Products;')else\n_p(3,'name = \"%s\";',e.name)if e.path and not e.isvpath then\nlocal n=e.path\nif e.parent.path then\nn=path.getrelative(e.parent.path,e.path)end\n_p(3,'path = \"%s\";',n)end\nend\n_p(3,'sourceTree = \"<group>\";')_p(2,'};')end},true)_p('/* End PBXGroup section */')_p('')end\nfunction e.PBXNativeTarget(i)_p('/* Begin PBXNativeTarget section */')for t,n in ipairs(i.products.children)do\nlocal t=i.project.name\nlocal function o(e)if#i.project[e]>0 then\nreturn true\nend\nfor i,n in ipairs(i.configs)do\nif#n[e]>0 then\nreturn true\nend\nend\nend\n_p(2,'%s /* %s */ = {',n.targetid,t)_" + "p(3,'isa = PBXNativeTarget;')_p(3,'buildConfigurationList = %s /* Build configuration list for PBXNativeTarget \"%s\" */;',n.cfgsection,t)_p(3,'buildPhases = (')if o('prebuildcommands')then\n_p(4,'9607AE1010C857E500CD1376 /* Prebuild */,')end\n_p(4,'%s /* Resources */,',n.resstageid)_p(4,'%s /* Sources */,',n.sourcesid)if o('prelinkcommands')then\n_p(4,'9607AE3510C85E7E00CD1376 /* Prelink */,')end\n_p(4,'%s /* Frameworks */,',n.fxstageid)if o('postbuildcommands')then\n_p(4,'9607AE3710C85E8F00CD1376 /* Postbuild */,')end\n_p(3,');')_p(3,'buildRules = (')_p(3,');')_p(3,'dependencies = (')for n,e in ipairs(i.projects.children)do\n_p(4,'%s /* PBXTargetDependency */,',e.targetdependid)end\n_p(3,');')_p(3,'name = \"%s\";',t)local i\nif n.cfg.kind==\"ConsoleApp\"then\ni=\"$(HOME)/bin\"elseif n.cfg.kind==\"WindowedApp\"then\ni=\"$(HOME)/Applications\"end\nif i then\n_p(3,'productInstallPath = \"%s\";',i)end\n_p(3,'productName = \"%s\";',t)_p(3,'productReference = %s /* %s */;',n.id,n.name)_p(3,'productType = \"%s\";'," + "e.getproducttype(n))_p(2,'};')end\n_p('/* End PBXNativeTarget section */')_p('')end\nfunction e.PBXProject(e)_p('/* Begin PBXProject section */')_p(2,'08FB7793FE84155DC02AAC07 /* Project object */ = {')_p(3,'isa = PBXProject;')_p(3,'buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject \"%s\" */;',e.name)_p(3,'compatibilityVersion = \"Xcode 3.2\";')_p(3,'hasScannedForEncodings = 1;')_p(3,'mainGroup = %s /* %s */;',e.id,e.name)_p(3,'projectDirPath = \"\";')if#e.projects.children>0 then\n_p(3,'projectReferences = (')for n,e in ipairs(e.projects.children)do\n_p(4,'{')_p(5,'ProductGroup = %s /* Products */;',e.productgroupid)_p(5,'ProjectRef = %s /* %s */;',e.id,path.getname(e.path))_p(4,'},')end\n_p(3,');')end\n_p(3,'projectRoot = \"\";')_p(3,'targets = (')for n,e in ipairs(e.products.children)do\n_p(4,'%s /* %s */,',e.targetid,e.name)end\n_p(3,');')_p(2,'};')_p('/* End PBXProject section */')_p('')end\nfunction e.PBXReferenceProxy(n)if#n.projects.children>0 then\n_p('/* Beg" + "in PBXReferenceProxy section */')i.traverse(n.projects,{onleaf=function(n)_p(2,'%s /* %s */ = {',n.id,n.name)_p(3,'isa = PBXReferenceProxy;')_p(3,'fileType = %s;',e.gettargettype(n))_p(3,'path = \"%s\";',n.path)_p(3,'remoteRef = %s /* PBXContainerItemProxy */;',n.parent.productproxyid)_p(3,'sourceTree = BUILT_PRODUCTS_DIR;')_p(2,'};')end})_p('/* End PBXReferenceProxy section */')_p('')end\nend\nfunction e.PBXResourcesBuildPhase(n)_p('/* Begin PBXResourcesBuildPhase section */')for o,t in ipairs(n.products.children)do\n_p(2,'%s /* Resources */ = {',t.resstageid)_p(3,'isa = PBXResourcesBuildPhase;')_p(3,'buildActionMask = 2147483647;')_p(3,'files = (')i.traverse(n,{onnode=function(n)if e.getbuildcategory(n)==\"Resources\"then\n_p(4,'%s /* %s in Resources */,',n.buildid,n.name)end\nend})_p(3,');')_p(3,'runOnlyForDeploymentPostprocessing = 0;')_p(2,'};')end\n_p('/* End PBXResourcesBuildPhase section */')_p('')end\nfunction e.PBXShellScriptBuildPhase(r)local t=false\nlocal function i(a,s,p)local o=r.project[p]local" + " n=table.join(o,{})for i,t in ipairs(r.configs)do\nlocal i=t[p]if#i>#o then\ntable.insert(n,'if [ \"${CONFIGURATION}\" = \"'..e.getconfigname(t)..'\" ]; then')for e=#o+1,#i do\ntable.insert(n,i[e])end\ntable.insert(n,'fi')end\nend\nif#n>0 then\nif not t then\n_p('/* Begin PBXShellScriptBuildPhase section */')t=true\nend\n_p(2,'%s /* %s */ = {',a,s)_p(3,'isa = PBXShellScriptBuildPhase;')_p(3,'buildActionMask = 2147483647;')_p(3,'files = (')_p(3,');')_p(3,'inputPaths = (');_p(3,');');_p(3,'name = %s;',s);_p(3,'outputPaths = (');_p(3,');');_p(3,'runOnlyForDeploymentPostprocessing = 0;');_p(3,'shellPath = /bin/sh;');_p(3,'shellScript = \"%s\";',table.concat(n,\"\\\\n\"):gsub('\"','\\\\\"'))_p(2,'};')end\nend\ni(\"9607AE1010C857E500CD1376\",\"Prebuild\",\"prebuildcommands\")i(\"9607AE3510C85E7E00CD1376\",\"Prelink\",\"prelinkcommands\")i(\"9607AE3710C85E8F00CD1376\",\"Postbuild\",\"postbuildcommands\")if t then\n_p('/* End PBXShellScriptBuildPhase section */')end\nend\nfunction e.PBXSourcesBuildPhase(n)_p('/* Begin" + " PBXSourcesBuildPhase section */')for o,t in ipairs(n.products.children)do\n_p(2,'%s /* Sources */ = {',t.sourcesid)_p(3,'isa = PBXSourcesBuildPhase;')_p(3,'buildActionMask = 2147483647;')_p(3,'files = (')i.traverse(n,{onleaf=function(n)if e.getbuildcategory(n)==\"Sources\"then\n_p(4,'%s /* %s in Sources */,',n.buildid,n.name)end\nend})_p(3,');')_p(3,'runOnlyForDeploymentPostprocessing = 0;')_p(2,'};')end\n_p('/* End PBXSourcesBuildPhase section */')_p('')end\nfunction e.PBXVariantGroup(e)_p('/* Begin PBXVariantGroup section */')i.traverse(e,{onbranch=function(e)if e.kind==\"vgroup\"then\n_p(2,'%s /* %s */ = {',e.id,e.name)_p(3,'isa = PBXVariantGroup;')_p(3,'children = (')for n,e in ipairs(e.children)do\n_p(4,'%s /* %s */,',e.id,e.name)end\n_p(3,');')_p(3,'name = %s;',e.name)_p(3,'sourceTree = \"<group>\";')_p(2,'};')end\nend})_p('/* End PBXVariantGroup section */')_p('')end\nfunction e.PBXTargetDependency(e)if#e.projects.children>0 then\n_p('/* Begin PBXTargetDependency section */')i.traverse(e.projects,{onle" + "af=function(e)_p(2,'%s /* PBXTargetDependency */ = {',e.parent.targetdependid)_p(3,'isa = PBXTargetDependency;')_p(3,'name = \"%s\";',e.name)_p(3,'targetProxy = %s /* PBXContainerItemProxy */;',e.parent.targetproxyid)_p(2,'};')end})_p('/* End PBXTargetDependency section */')_p('')end\nend\nfunction e.XCBuildConfiguration_Target(i,t,n)local t=e.getconfigname(n)_p(2,'%s /* %s */ = {',n.xcode.targetid,t)_p(3,'isa = XCBuildConfiguration;')_p(3,'buildSettings = {')_p(4,'ALWAYS_SEARCH_USER_PATHS = NO;')if not n.flags.Symbols then\n_p(4,'DEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";')end\nif n.kind~=\"StaticLib\"and n.buildtarget.prefix~=\"\"then\n_p(4,'EXECUTABLE_PREFIX = %s;',n.buildtarget.prefix)end\nif n.targetextension then\nlocal e=n.targetextension\ne=iif(e:startswith(\".\"),e:sub(2),e)_p(4,'EXECUTABLE_EXTENSION = %s;',e)end\nlocal e=path.getdirectory(n.buildtarget.bundlepath)if e~=\".\"then\n_p(4,'CONFIGURATION_BUILD_DIR = %s;',e)end\n_p(4,'GCC_DYNAMIC_NO_PIC = NO;')_p(4,'GCC_MODEL_TUNING = G5;')if i.infopl" + "ist then\n_p(4,'INFOPLIST_FILE = \"%s\";',i.infoplist.cfg.name)end\ninstallpaths={ConsoleApp='/usr/local/bin',WindowedApp='\"$(HOME)/Applications\"',SharedLib='/usr/local/lib',StaticLib='/usr/local/lib',}_p(4,'INSTALL_PATH = %s;',installpaths[n.kind])_p(4,'PRODUCT_NAME = \"%s\";',n.buildtarget.basename)_p(3,'};')_p(3,'name = \"%s\";',t)_p(2,'};')end\nfunction e.XCBuildConfiguration_Project(i,n)local o=e.getconfigname(n)_p(2,'%s /* %s */ = {',n.xcode.projectid,o)_p(3,'isa = XCBuildConfiguration;')_p(3,'buildSettings = {')local i={Native=\"$(NATIVE_ARCH_ACTUAL)\",x32=\"i386\",x64=\"x86_64\",Universal32=\"$(ARCHS_STANDARD_32_BIT)\",Universal64=\"$(ARCHS_STANDARD_64_BIT)\",Universal=\"$(ARCHS_STANDARD_32_64_BIT)\",}_p(4,'ARCHS = \"%s\";',i[n.platform])local t=path.getdirectory(n.buildtarget.bundlepath)if t~=\".\"then\n_p(4,'CONFIGURATION_BUILD_DIR = \"$(SYMROOT)\";');end\n_p(4,'CONFIGURATION_TEMP_DIR = \"$(OBJROOT)\";')if n.flags.Symbols then\n_p(4,'COPY_PHASE_STRIP = NO;')end\n_p(4,'GCC_C_LANGUAGE_STANDARD = gnu9" + "9;')if n.flags.NoExceptions then\n_p(4,'GCC_ENABLE_CPP_EXCEPTIONS = NO;')end\nif n.flags.NoRTTI then\n_p(4,'GCC_ENABLE_CPP_RTTI = NO;')end\nif _ACTION~=\"xcode4\"and n.flags.Symbols and not n.flags.NoEditAndContinue then\n_p(4,'GCC_ENABLE_FIX_AND_CONTINUE = YES;')end\nif n.flags.NoExceptions then\n_p(4,'GCC_ENABLE_OBJC_EXCEPTIONS = NO;')end\nif n.flags.Optimize or n.flags.OptimizeSize then\n_p(4,'GCC_OPTIMIZATION_LEVEL = s;')elseif n.flags.OptimizeSpeed then\n_p(4,'GCC_OPTIMIZATION_LEVEL = 3;')else\n_p(4,'GCC_OPTIMIZATION_LEVEL = 0;')end\nif n.pchheader and not n.flags.NoPCH then\n_p(4,'GCC_PRECOMPILE_PREFIX_HEADER = YES;')_p(4,'GCC_PREFIX_HEADER = \"%s\";',n.pchheader)end\ne.printlist(n.defines,'GCC_PREPROCESSOR_DEFINITIONS')_p(4,'GCC_SYMBOLS_PRIVATE_EXTERN = NO;')if n.flags.FatalWarnings then\n_p(4,'GCC_TREAT_WARNINGS_AS_ERRORS = YES;')end\n_p(4,'GCC_WARN_ABOUT_RETURN_TYPE = YES;')_p(4,'GCC_WARN_UNUSED_VARIABLE = YES;')e.printlist(n.includedirs,'HEADER_SEARCH_PATHS')e.printlist(n.libdirs,'LIBRARY_SEARCH_PATH" + "S')_p(4,'OBJROOT = \"%s\";',n.objectsdir)_p(4,'ONLY_ACTIVE_ARCH = %s;',iif(premake.config.isdebugbuild(n),'YES','NO'))local r={[\"-ffast-math\"]=n.flags.FloatFast,[\"-ffloat-store\"]=n.flags.FloatStrict,[\"-fomit-frame-pointer\"]=n.flags.NoFramePointer,}local i={}for n,t in pairs(r)do\nif t then\ntable.insert(i,n)end\nend\ne.printlist(table.join(i,n.buildoptions),'OTHER_CFLAGS')i={}for t,n in ipairs(premake.getlinks(n,\"system\"))do\nif not e.isframework(n)then\ntable.insert(i,\"-l\"..n)end\nend\ni=table.join(i,n.linkoptions)e.printlist(i,'OTHER_LDFLAGS')if n.flags.StaticRuntime then\n_p(4,'STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static;')end\nif t~=\".\"then\n_p(4,'SYMROOT = \"%s\";',t)end\nif n.flags.ExtraWarnings then\n_p(4,'WARNING_CFLAGS = \"-Wall\";')end\n_p(3,'};')_p(3,'name = \"%s\";',o)_p(2,'};')end\nfunction e.XCBuildConfiguration(n)_p('/* Begin XCBuildConfiguration section */')for t,i in ipairs(n.products.children)do\nfor o,t in ipairs(n.configs)do\ne.XCBuildConfiguration_Target(n,i,t)end\nend\nfor t,i " + "in ipairs(n.configs)do\ne.XCBuildConfiguration_Project(n,i)end\n_p('/* End XCBuildConfiguration section */')_p('')end\nfunction e.XCBuildConfigurationList(n)local i=n.project.solution\n_p('/* Begin XCConfigurationList section */')for t,i in ipairs(n.products.children)do\n_p(2,'%s /* Build configuration list for PBXNativeTarget \"%s\" */ = {',i.cfgsection,i.name)_p(3,'isa = XCConfigurationList;')_p(3,'buildConfigurations = (')for i,n in ipairs(n.configs)do\n_p(4,'%s /* %s */,',n.xcode.targetid,e.getconfigname(n))end\n_p(3,');')_p(3,'defaultConfigurationIsVisible = 0;')_p(3,'defaultConfigurationName = \"%s\";',e.getconfigname(n.configs[1]))_p(2,'};')end\n_p(2,'1DEB928908733DD80010E9CD /* Build configuration list for PBXProject \"%s\" */ = {',n.name)_p(3,'isa = XCConfigurationList;')_p(3,'buildConfigurations = (')for i,n in ipairs(n.configs)do\n_p(4,'%s /* %s */,',n.xcode.projectid,e.getconfigname(n))end\n_p(3,');')_p(3,'defaultConfigurationIsVisible = 0;')_p(3,'defaultConfigurationName = \"%s\";',e.getconfigname" + "(n.configs[1]))_p(2,'};')_p('/* End XCConfigurationList section */')_p('')end\nfunction e.Footer()_p(1,'};')_p('\\trootObject = 08FB7793FE84155DC02AAC07 /* Project object */;')_p('}')end", + + /* actions/xcode/xcode_project.lua */ + "local e=premake.xcode\nlocal o=premake.tree\nfunction e.buildprjtree(r)local n=premake.project.buildsourcetree(r)n.configs={}for t,i in ipairs(r.solution.configurations)do\nfor t,o in ipairs(r.solution.xcode.platforms)do\nlocal o=premake.getconfig(r,i,o)o.xcode={}o.xcode.targetid=e.newid(r.xcode.projectnode,i)o.xcode.projectid=e.newid(n,i)table.insert(n.configs,o)end\nend\no.traverse(n,{onbranch=function(e)if path.getextension(e.name)==\".lproj\"then\nlocal i=path.getbasename(e.name)for n,r in ipairs(e.children)do\nlocal n=e.parent.children[r.name]if not n then\nn=o.insert(e.parent,o.new(r.name))n.kind=\"vgroup\"end\nr.name=path.getbasename(i)o.insert(n,r)end\no.remove(e)end\nend})n.frameworks=o.new(\"Frameworks\")for r in premake.eachconfig(r)do\nfor r,i in ipairs(premake.getlinks(r,\"system\",\"fullpath\"))do\nlocal r=path.getname(i)if e.isframework(r)and not n.frameworks.children[r]then\nnode=o.insert(n.frameworks,o.new(r))node.path=i\nend\nend\nend\nif#n.frameworks.children>0 then\no.insert(n,n.frameworks)" + "end\nn.products=o.insert(n,o.new(\"Products\"))n.projects=o.new(\"Projects\")for t,i in ipairs(premake.getdependencies(r,\"sibling\",\"object\"))do\nlocal t=e.getxcodeprojname(i)local n=o.insert(n.projects,o.new(path.getname(t)))n.path=t\nn.project=i\nn.productgroupid=e.newid(n,\"prodgrp\")n.productproxyid=e.newid(n,\"prodprox\")n.targetproxyid=e.newid(n,\"targprox\")n.targetdependid=e.newid(n,\"targdep\")local e=premake.getconfig(i,r.configurations[1])node=o.insert(n,o.new(e.linktarget.name))node.path=e.linktarget.fullpath\nnode.cfg=e\nend\nif#n.projects.children>0 then\no.insert(n,n.projects)end\no.traverse(n,{onnode=function(o)o.id=e.newid(o)if e.getbuildcategory(o)then\no.buildid=e.newid(o,\"build\")end\nif string.endswith(o.name,\"Info.plist\")then\nn.infoplist=o\nend\nend},true)node=o.insert(n.products,r.xcode.projectnode)node.kind=\"product\"node.path=node.cfg.buildtarget.fullpath\nnode.cfgsection=e.newid(node,\"cfg\")node.resstageid=e.newid(node,\"rez\")node.sourcesid=e.newid(node,\"src\")node.fxstagei" + "d=e.newid(node,\"fxs\")return n\nend\nfunction premake.xcode.project(n)local n=e.buildprjtree(n)e.Header(n)e.PBXBuildFile(n)e.PBXContainerItemProxy(n)e.PBXFileReference(n)e.PBXFrameworksBuildPhase(n)e.PBXGroup(n)e.PBXNativeTarget(n)e.PBXProject(n)e.PBXReferenceProxy(n)e.PBXResourcesBuildPhase(n)e.PBXShellScriptBuildPhase(n)e.PBXSourcesBuildPhase(n)e.PBXVariantGroup(n)e.PBXTargetDependency(n)e.XCBuildConfiguration(n)e.XCBuildConfigurationList(n)e.Footer(n)end", + + /* actions/xcode/xcode4_workspace.lua */ + "premake.xcode4={}local e=premake.xcode4\nfunction e.workspace_head()_p('<?xml version=\"1.0\" encoding=\"UTF-8\"?>')_p('<Workspace')_p(1,'version = \"1.0\">')end\nfunction e.workspace_tail()_p('</Workspace>')end\nfunction e.workspace_file_ref(o)local e=path.getrelative(o.solution.location,o.location)if e=='.'then e=''else e=e..'/'end\n_p(1,'<FileRef')_p(2,'location = \"group:%s\">',e..o.name..'.xcodeproj')_p(1,'</FileRef>')end\nfunction e.workspace_generate(o)premake.xcode.preparesolution(o)e.workspace_head()for o in premake.solution.eachproject(o)do\ne.workspace_file_ref(o)end\ne.workspace_tail()end", + + /* actions/clean/_clean.lua */ + "premake.clean={}function premake.clean.directory(n,e)local e=premake.project.getfilename(n,e)os.rmdir(e)end\nfunction premake.clean.file(e,n)local e=premake.project.getfilename(e,n)os.remove(e)end\nnewaction{trigger=\"clean\",description=\"Remove all binaries and generated files\",onsolution=function(n)for e in premake.action.each()do\nif e.oncleansolution then\ne.oncleansolution(n)end\nend\nend,onproject=function(e)for n in premake.action.each()do\nif n.oncleanproject then\nn.oncleanproject(e)end\nend\nif(e.objectsdir)then\npremake.clean.directory(e,e.objectsdir)end\nlocal n=e.solution.platforms or{}if not table.contains(n,\"Native\")then\nn=table.join(n,{\"Native\"})end\nfor a,n in ipairs(n)do\nfor n in premake.eachconfig(e,n)do\npremake.clean.directory(e,n.objectsdir)premake.clean.file(e,premake.gettarget(n,\"build\",\"posix\",\"windows\",\"windows\").fullpath)premake.clean.file(e,premake.gettarget(n,\"build\",\"posix\",\"posix\",\"linux\").fullpath)premake.clean.file(e,premake.gettarget(n,\"build\",\"posix" + "\",\"posix\",\"macosx\").fullpath)premake.clean.file(e,premake.gettarget(n,\"build\",\"posix\",\"PS3\",\"windows\").fullpath)if n.kind==\"WindowedApp\"then\npremake.clean.directory(e,premake.gettarget(n,\"build\",\"posix\",\"posix\",\"linux\").fullpath..\".app\")end\npremake.clean.file(e,premake.gettarget(n,\"link\",\"windows\",\"windows\",\"windows\").fullpath)premake.clean.file(e,premake.gettarget(n,\"link\",\"posix\",\"posix\",\"linux\").fullpath)local n=path.join(premake.project.getfilename(e,n.buildtarget.directory),n.buildtarget.basename)for e in premake.action.each()do\nif e.oncleantarget then\ne.oncleantarget(n)end\nend\nend\nend\nend}", + + /* _premake_main.lua */ + "local t=\"premake4.lua\"local a=\"Type 'premake4 --help' for help\"local i=\"premake4 (Premake Build Script Generator) %s\"_WORKING_DIR=os.getcwd()local function o(r)if not r then return true end\nr=premake.checkvalue(r,premake.fields.platforms.allowed)for n in premake.solution.each()do\nlocal e=n.platforms or{}if#e==0 then\ntable.insert(e,\"Native\")end\nif not table.contains(e,\"Native\")then\nreturn false,n.name..\" does not target native platform\\nNative platform settings are required for the --platform feature.\"end\nif not table.contains(e,r)then\ntable.insert(e,r)end\nn.platforms=e\nend\nreturn true\nend\nfunction _premake_main(e)if(e)then\nlocal r=dofile(e..\"/_manifest.lua\")for n,r in ipairs(r)do\ndofile(e..\"/\"..r)end\nend\n_PREMAKE_COMMAND=path.getabsolute(_PREMAKE_COMMAND)premake.action.set(_ACTION)math.randomseed(os.time())local e=_OPTIONS[\"file\"]or t\nif(os.isfile(e))then\ndofile(e)end\nif(_OPTIONS[\"version\"])then\nprintf(i,_PREMAKE_VERSION)return 1\nend\nif(_OPTIONS[\"help\"])then\npremak" + "e.showhelp()return 1\nend\nif(not _ACTION)then\nprint(a)return 1\nend\nif(not os.isfile(e))then\nerror(\"No Premake script (\"..t..\") found!\",2)end\naction=premake.action.current()if(not action)then\nerror(\"Error: no such action '\".._ACTION..\"'\",0)end\nok,err=premake.option.validate(_OPTIONS)if(not ok)then error(\"Error: \"..err,0)end\nok,err=premake.checktools()if(not ok)then error(\"Error: \"..err,0)end\nok,err=o(_OPTIONS[\"platform\"])if(not ok)then error(\"Error: \"..err,0)end\nprint(\"Building configurations...\")premake.bake.buildconfigs()ok,err=premake.checkprojects()if(not ok)then error(\"Error: \"..err,0)end\nprintf(\"Running action '%s'...\",action.trigger)premake.action.call(action.trigger)print(\"Done.\")return 0\nend", + + 0 +}; diff --git a/tests/actions/test_clean.lua b/tests/actions/test_clean.lua index f0badbc..bd205d6 100644 --- a/tests/actions/test_clean.lua +++ b/tests/actions/test_clean.lua @@ -93,7 +93,9 @@ kind "ConsoleApp" prepare() test.contains(removed, "MyProject.csproj") - test.contains(removed, "MyProject.csproj.user") + if _OPTIONS.generate_user then + test.contains(removed, "MyProject.csproj.user") + end test.contains(removed, "MyProject.pdb") test.contains(removed, "MyProject.idb") test.contains(removed, "MyProject.ilk") |