forked from 0ad/0ad
# Updated build system
to use Premake 3.1 (slightly modified - see next commit), and to properly support VS2005. Should still be compatible with GCC, though there may be differences I haven't noticed. Removed option to build ScEd (because it won't work anyway). This was SVN commit r3782.
This commit is contained in:
parent
8c440a4e24
commit
3fbc464857
@ -1,23 +1,23 @@
|
||||
function sourcesfromdirs(root, dirs)
|
||||
local res = {}
|
||||
for i=1, getn(dirs) do
|
||||
for i,v in dirs do
|
||||
local files = matchfiles(
|
||||
root..dirs[i].."/*.cpp",
|
||||
root..dirs[i].."/*.h",
|
||||
root..dirs[i].."/*.asm")
|
||||
tconcat(res, files)
|
||||
root..v.."/*.cpp",
|
||||
root..v.."/*.h",
|
||||
root..v.."/*.asm")
|
||||
listconcat(res, files)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function trimrootdir(root, dirs)
|
||||
for i=1, getn(dirs) do
|
||||
dirs[i] = strsub(dirs[i], strlen(root))
|
||||
for i,v in dirs do
|
||||
dirs[i] = strsub(v, strlen(root))
|
||||
end
|
||||
end
|
||||
|
||||
function tconcat(table, values)
|
||||
for i=1, getn(values) do
|
||||
tinsert(table, values[i])
|
||||
function listconcat(list, values)
|
||||
for i,v in values do
|
||||
table.insert(list, v)
|
||||
end
|
||||
end
|
||||
|
Binary file not shown.
@ -1,39 +1,44 @@
|
||||
addoption("atlas", "Include Atlas scenario editor packages")
|
||||
addoption("sced", "Include ScEd package")
|
||||
addoption("outpath", "Location for generated project files")
|
||||
|
||||
dofile("../functions.lua")
|
||||
dofile("functions.lua")
|
||||
|
||||
-- Set up the Project
|
||||
project.name = "pyrogenesis"
|
||||
project.bindir = "../../../binaries/system"
|
||||
project.libdir = "../../../binaries/system"
|
||||
project.debugdir = "../../../binaries/system"
|
||||
project.bindir = "../../binaries/system"
|
||||
project.libdir = "../../binaries/system"
|
||||
project.debugdir = "../../binaries/system"
|
||||
if not options["outpath"] then
|
||||
error("You must specify the 'outpath' parameter")
|
||||
end
|
||||
project.path = options["outpath"]
|
||||
project.configs = { "Debug", "Release", "Testing" }
|
||||
|
||||
if (OS == "windows") then
|
||||
project.nasmpath = "../../../build/bin/nasm"
|
||||
project.nasmpath = "../../build/bin/nasm.exe"
|
||||
end
|
||||
|
||||
---------------- Main game package (pyrogenesis/sced) ----------------
|
||||
function create_package()
|
||||
package = newpackage()
|
||||
package.path = project.path
|
||||
package.language = "c++"
|
||||
package.buildflags = { "no-manifest", "with-symbols", "no-edit-and-continue" }
|
||||
return package
|
||||
end
|
||||
|
||||
---------------- Main game package (pyrogenesis) ----------------
|
||||
|
||||
function setuppackage_engine (projectname)
|
||||
|
||||
-- Start the package part
|
||||
package = newpackage()
|
||||
package = create_package()
|
||||
|
||||
if (projectname == "sced") then
|
||||
package.name = "sced"
|
||||
exename = "sced"
|
||||
objdirprefix = "obj/ScEd_"
|
||||
else
|
||||
package.name = "pyrogenesis"
|
||||
exename = "ps"
|
||||
objdirprefix = "obj/"
|
||||
end
|
||||
package.name = "pyrogenesis"
|
||||
exename = "ps"
|
||||
objdirprefix = "obj/"
|
||||
|
||||
-- Windowed executable on windows, "exe" on all other platforms
|
||||
package.kind = "winexe"
|
||||
package.language = "c++"
|
||||
|
||||
-- Package target for debug and release build
|
||||
-- On Windows, ".exe" is added on the end, on unices the name is used directly
|
||||
@ -76,26 +81,21 @@ function setuppackage_engine (projectname)
|
||||
"terrain",
|
||||
"sound",
|
||||
"scripting",
|
||||
"i18n"
|
||||
}
|
||||
"i18n",
|
||||
|
||||
if (projectname ~= "sced") then tconcat(source_dirs, {
|
||||
"gui",
|
||||
"gui/scripting",
|
||||
|
||||
"tools/atlas/GameInterface",
|
||||
"tools/atlas/GameInterface/Handlers"
|
||||
}) end
|
||||
|
||||
if (projectname == "sced") then tconcat(source_dirs, {
|
||||
"tools/sced",
|
||||
"tools/sced/ui"
|
||||
}) end
|
||||
}
|
||||
|
||||
package.files = sourcesfromdirs(sourceroot, source_dirs)
|
||||
table.insert(package.files, sourceroot.."main.cpp")
|
||||
|
||||
tinsert(package.files, sourceroot.."main.cpp")
|
||||
package.trimprefix = sourceroot
|
||||
|
||||
--trimrootdir(sourceroot, package.files)
|
||||
|
||||
include_dirs = {
|
||||
"ps",
|
||||
@ -108,45 +108,28 @@ function setuppackage_engine (projectname)
|
||||
""
|
||||
}
|
||||
|
||||
if (projectname == "sced") then
|
||||
tinsert(include_dirs, "tools/sced")
|
||||
end
|
||||
|
||||
package.includepaths = {}
|
||||
foreach(include_dirs, function (i,v)
|
||||
tinsert(package.includepaths, sourceroot .. v)
|
||||
end)
|
||||
for i,v in include_dirs do
|
||||
table.insert(package.includepaths, sourceroot .. v)
|
||||
end
|
||||
|
||||
package.libpaths = {}
|
||||
|
||||
table.insert(package.buildflags, "extra-warnings")
|
||||
|
||||
if (OS == "windows") then
|
||||
package.buildflags = { "no-rtti" }
|
||||
else
|
||||
package.buildflags = { }
|
||||
table.insert(package.buildflags, "no-rtti")
|
||||
end
|
||||
|
||||
-- PremakeWiki says with-symbols and optimize are automatically set for
|
||||
-- Debug and Release builds, respectively. doesn't happen though, so do it manually.
|
||||
|
||||
package.config["Debug"].buildflags = { "with-symbols", "no-edit-and-continue" }
|
||||
|
||||
package.config["Testing"].buildflags = { "with-symbols", "no-runtime-checks", "no-edit-and-continue" }
|
||||
package.config["Testing"].buildflags = { "no-runtime-checks" }
|
||||
package.config["Testing"].defines = { "TESTING" }
|
||||
|
||||
package.config["Release"].buildflags = { "with-symbols", "no-runtime-checks", "no-edit-and-continue", "optimize" }
|
||||
package.config["Release"].buildflags = { "no-runtime-checks", "optimize" }
|
||||
package.config["Release"].defines = { "NDEBUG" }
|
||||
|
||||
|
||||
if (projectname == "sced") then
|
||||
tinsert(package.defines, "SCED")
|
||||
tinsert(package.defines, "_AFXDLL")
|
||||
-- Disable the whole GUI system, since it conflicts with the MFC headers
|
||||
tinsert(package.defines, "NO_GUI")
|
||||
-- Some definitions to make the lib code initialisation work
|
||||
tinsert(package.defines, "USE_WINMAIN")
|
||||
tinsert(package.defines, "NO_MAIN_REDIRECT")
|
||||
end
|
||||
|
||||
-- Platform Specifics
|
||||
if (OS == "windows") then
|
||||
|
||||
@ -166,23 +149,16 @@ function setuppackage_engine (projectname)
|
||||
}
|
||||
|
||||
-- Add '<libraries root>/<libraryname>/lib' and '/include' to the includepaths and libpaths
|
||||
foreach(external_libraries, function (i,v)
|
||||
tinsert(package.includepaths, librariesroot..v.."/include")
|
||||
tinsert(package.libpaths, librariesroot..v.."/lib")
|
||||
end)
|
||||
for i,v in external_libraries do
|
||||
table.insert(package.includepaths, librariesroot..v.."/include")
|
||||
table.insert(package.libpaths, librariesroot..v.."/lib")
|
||||
end
|
||||
|
||||
-- Libraries
|
||||
package.links = { "opengl32" }
|
||||
tinsert(package.files, sourcesfromdirs(sourceroot, {"lib/sysdep/win"}))
|
||||
tinsert(package.files, {sourceroot.."lib/sysdep/win/error_dialog.rc"})
|
||||
|
||||
if (projectname == "sced") then
|
||||
tinsert(package.files, {sourceroot.."tools/sced/ui/ScEd.rc"})
|
||||
end
|
||||
|
||||
if (projectname ~= "sced") then
|
||||
tinsert(package.files, {sourceroot.."lib/sysdep/win/icon.rc"})
|
||||
end
|
||||
table.insert(package.files, sourcesfromdirs(sourceroot, {"lib/sysdep/win"}))
|
||||
table.insert(package.files, {sourceroot.."lib/sysdep/win/error_dialog.rc"})
|
||||
table.insert(package.files, {sourceroot.."lib/sysdep/win/icon.rc"})
|
||||
|
||||
package.linkoptions = { "/ENTRY:entry",
|
||||
"/DELAYLOAD:opengl32.dll",
|
||||
@ -220,19 +196,17 @@ function setuppackage_engine (projectname)
|
||||
}
|
||||
|
||||
-- required to use WinMain() on Windows, otherwise will default to main()
|
||||
tinsert(package.buildflags, { "no-main" })
|
||||
table.insert(package.buildflags, { "no-main" })
|
||||
|
||||
-- use native wchar_t type (not typedef to unsigned short)
|
||||
package.buildoptions = {
|
||||
"/Zc:wchar_t",
|
||||
}
|
||||
table.insert(package.buildflags, { "native-wchar_t" })
|
||||
|
||||
package.pchHeader = "precompiled.h"
|
||||
package.pchSource = "precompiled.cpp"
|
||||
package.pchheader = "precompiled.h"
|
||||
package.pchsource = "precompiled.cpp"
|
||||
|
||||
else -- Non-Windows, = Unix
|
||||
|
||||
tinsert(package.files, sourcesfromdirs(sourceroot, {"lib/sysdep/unix"}))
|
||||
table.insert(package.files, sourcesfromdirs(sourceroot, {"lib/sysdep/unix"}))
|
||||
|
||||
-- Libraries
|
||||
package.links = {
|
||||
@ -261,18 +235,18 @@ function setuppackage_engine (projectname)
|
||||
"-Wno-non-virtual-dtor",
|
||||
}
|
||||
|
||||
tinsert(package.libpaths, { "/usr/X11R6/lib" } )
|
||||
table.insert(package.libpaths, { "/usr/X11R6/lib" } )
|
||||
-- Defines
|
||||
package.defines = {
|
||||
"__STDC_VERSION__=199901L",
|
||||
"CONFIG_USE_MMGR" }
|
||||
-- Includes (X11 include path isn't standard across distributions)
|
||||
tinsert(package.includepaths, { "/usr/X11R6/include/X11" } )
|
||||
tinsert(package.includepaths, { "/usr/include/X11" } )
|
||||
table.insert(package.includepaths, { "/usr/X11R6/include/X11" } )
|
||||
table.insert(package.includepaths, { "/usr/include/X11" } )
|
||||
|
||||
-- speed up math functions by inlining. warning: this may result in
|
||||
-- non-IEEE-conformant results, but haven't noticed any trouble so far.
|
||||
tinsert(package.buildoptions, { "-ffast-math" })
|
||||
table.insert(package.buildoptions, { "-ffast-math" })
|
||||
end
|
||||
end
|
||||
|
||||
@ -282,12 +256,11 @@ end
|
||||
|
||||
function setuppackage_atlas(package_name, target_type, source_dirs, include_dirs, flags)
|
||||
|
||||
package = newpackage()
|
||||
package = create_package()
|
||||
package.name = package_name
|
||||
objdirprefix = "obj/"..package_name.."_"
|
||||
|
||||
package.kind = target_type
|
||||
package.language = "c++"
|
||||
|
||||
-- Package target for debug and release build
|
||||
package.config["Debug"].target = package_name.."_d"
|
||||
@ -296,15 +269,14 @@ function setuppackage_atlas(package_name, target_type, source_dirs, include_dirs
|
||||
package.config["Debug"].objdir = objdirprefix.."Debug"
|
||||
package.config["Release"].objdir = objdirprefix.."Release"
|
||||
|
||||
sourceroot = "../../../source/tools/atlas/"
|
||||
sourceroot = "../../../source/tools/atlas/" .. package_name
|
||||
librariesroot = "../../../libraries/"
|
||||
|
||||
|
||||
sources = sourcesfromdirs(sourceroot, source_dirs)
|
||||
if (flags["extrasource"]) then
|
||||
foreach(flags["extrasource"], function (i,v)
|
||||
tinsert(sources, sourceroot..v)
|
||||
end)
|
||||
if flags["extrasource"] then
|
||||
for i,v in flags["extrasource"] do
|
||||
table.insert(sources, sourceroot .. v)
|
||||
end
|
||||
end
|
||||
|
||||
-- We don't want three pointless levels of directories in each project,
|
||||
@ -312,54 +284,50 @@ function setuppackage_atlas(package_name, target_type, source_dirs, include_dirs
|
||||
-- names are used by Premake to construct the project tree), but set
|
||||
-- 'filesprefix' (with Premake altered to recognise that) so the project
|
||||
-- will still point to the correct filenames.
|
||||
trimrootdir(sourceroot, sources)
|
||||
package.filesprefix = sourceroot
|
||||
package.trimprefix = sourceroot .. "/"
|
||||
package.files = sources
|
||||
|
||||
package.includepaths = {}
|
||||
foreach(include_dirs, function (i,v)
|
||||
tinsert(package.includepaths, sourceroot .. v)
|
||||
end)
|
||||
for i,v in include_dirs do
|
||||
table.insert(package.includepaths, sourceroot .. v)
|
||||
end
|
||||
|
||||
package.libpaths = {}
|
||||
|
||||
if (OS == "windows") then
|
||||
package.buildflags = { "no-rtti" }
|
||||
else
|
||||
package.buildflags = { }
|
||||
table.insert(package.buildflags, "no-rtti")
|
||||
end
|
||||
|
||||
-- PremakeWiki says with-symbols and optimize are automatically set for
|
||||
-- Debug and Release builds, respectively. doesn't happen though, so do it manually.
|
||||
package.config["Debug"].buildflags = { "with-symbols", "no-edit-and-continue" }
|
||||
package.config["Release"].buildflags = { "with-symbols", "no-runtime-checks", "no-edit-and-continue", "optimize" }
|
||||
package.config["Release"].buildflags = { "no-runtime-checks", "optimize" }
|
||||
package.config["Release"].defines = { "NDEBUG" }
|
||||
|
||||
-- Platform Specifics
|
||||
if (OS == "windows") then
|
||||
|
||||
tinsert(package.defines, "_UNICODE")
|
||||
table.insert(package.defines, "_UNICODE")
|
||||
|
||||
-- Directories under 'libraries', each containing 'lib' and 'include':
|
||||
external_libraries = {}
|
||||
if (flags["boost"]) then tinsert(external_libraries, "boost") end
|
||||
if (flags["devil"]) then tinsert(external_libraries, "devil") end
|
||||
if (flags["xerces"]) then tinsert(external_libraries, "xerces") end
|
||||
if (flags["zlib"]) then tinsert(external_libraries, "zlib") end
|
||||
if (flags["boost"]) then table.insert(external_libraries, "boost") end
|
||||
if (flags["devil"]) then table.insert(external_libraries, "devil") end
|
||||
if (flags["xerces"]) then table.insert(external_libraries, "xerces") end
|
||||
if (flags["zlib"]) then table.insert(external_libraries, "zlib") end
|
||||
|
||||
external_libraries.n = nil; -- remove the array size, else it'll be interpreted as a directory
|
||||
|
||||
-- Add '<libraries root>/<libraryname>/lib' and '/include' to the includepaths and libpaths
|
||||
foreach(external_libraries, function (i,v)
|
||||
tinsert(package.includepaths, librariesroot..v.."/include")
|
||||
tinsert(package.libpaths, librariesroot..v.."/lib")
|
||||
end)
|
||||
for i,v in external_libraries do
|
||||
table.insert(package.includepaths, librariesroot..v.."/include")
|
||||
table.insert(package.libpaths, librariesroot..v.."/lib")
|
||||
end
|
||||
|
||||
-- Handle wx specially
|
||||
if (flags["wx"]) then
|
||||
tinsert(package.includepaths, librariesroot.."wxwidgets/include/msvc")
|
||||
tinsert(package.includepaths, librariesroot.."wxwidgets/include")
|
||||
tinsert(package.libpaths, librariesroot.."wxwidgets/lib/vc_lib")
|
||||
table.insert(package.includepaths, librariesroot.."wxwidgets/include/msvc")
|
||||
table.insert(package.includepaths, librariesroot.."wxwidgets/include")
|
||||
table.insert(package.libpaths, librariesroot.."wxwidgets/lib/vc_lib")
|
||||
end
|
||||
|
||||
-- Link to required libraries
|
||||
@ -367,15 +335,15 @@ function setuppackage_atlas(package_name, target_type, source_dirs, include_dirs
|
||||
package.config["Debug"].links = { "wxmsw26ud_gl" }
|
||||
package.config["Release"].links = { "wxmsw26u_gl" }
|
||||
if (flags["depends"]) then
|
||||
tconcat(package.links, flags["depends"])
|
||||
listconcat(package.links, flags["depends"])
|
||||
end
|
||||
|
||||
-- required to use WinMain() on Windows, otherwise will default to main()
|
||||
tinsert(package.buildflags, { "no-main" })
|
||||
table.insert(package.buildflags, { "no-main" })
|
||||
|
||||
if (flags["pch"]) then
|
||||
package.pchHeader = "stdafx.h"
|
||||
package.pchSource = "stdafx.cpp"
|
||||
package.pchheader = "stdafx.h"
|
||||
package.pchsource = "stdafx.cpp"
|
||||
end
|
||||
|
||||
else -- Non-Windows, = Unix
|
||||
@ -388,12 +356,11 @@ end
|
||||
|
||||
function setuppackage_atlas_frontend (package_name)
|
||||
|
||||
package = newpackage()
|
||||
package = create_package()
|
||||
package.name = package_name
|
||||
objdirprefix = "obj/Frontend/"..package_name.."_"
|
||||
|
||||
package.kind = "winexe"
|
||||
package.language = "c++"
|
||||
|
||||
-- Package target for debug and release build
|
||||
package.config["Debug"].target = package_name.."_d"
|
||||
@ -404,25 +371,24 @@ function setuppackage_atlas_frontend (package_name)
|
||||
|
||||
sourceroot = "../../../source/tools/atlas/AtlasFrontends/"
|
||||
|
||||
package.filesprefix = sourceroot
|
||||
package.files = {
|
||||
package_name..".cpp",
|
||||
package_name..".rc"
|
||||
sourceroot..package_name..".cpp",
|
||||
sourceroot..package_name..".rc"
|
||||
}
|
||||
package.trimprefix = sourceroot
|
||||
|
||||
package.includepaths = { sourceroot..".." }
|
||||
|
||||
package.config["Debug"].buildflags = { "with-symbols", "no-edit-and-continue" }
|
||||
package.config["Release"].buildflags = { "with-symbols", "no-runtime-checks", "no-edit-and-continue", "optimize" }
|
||||
package.config["Release"].buildflags = { "no-runtime-checks", "optimize" }
|
||||
package.config["Release"].defines = { "NDEBUG" }
|
||||
|
||||
-- Platform Specifics
|
||||
if (OS == "windows") then
|
||||
tinsert(package.defines, "_UNICODE")
|
||||
tinsert(package.links, "AtlasUI")
|
||||
table.insert(package.defines, "_UNICODE")
|
||||
table.insert(package.links, "AtlasUI")
|
||||
|
||||
-- required to use WinMain() on Windows, otherwise will default to main()
|
||||
tinsert(package.buildflags, { "no-main" })
|
||||
table.insert(package.buildflags, { "no-main" })
|
||||
|
||||
else -- Non-Windows, = Unix
|
||||
-- TODO
|
||||
@ -437,7 +403,7 @@ end
|
||||
function setuppackages_atlas()
|
||||
setuppackage_atlas("AtlasObject", "lib", {
|
||||
-- src
|
||||
"AtlasObject"
|
||||
""
|
||||
},{
|
||||
-- include
|
||||
},{
|
||||
@ -446,32 +412,32 @@ function setuppackages_atlas()
|
||||
|
||||
setuppackage_atlas("AtlasUI", "dll", {
|
||||
-- src
|
||||
"AtlasUI/ActorEditor",
|
||||
"AtlasUI/ArchiveViewer",
|
||||
"AtlasUI/ColourTester",
|
||||
"AtlasUI/CustomControls/Buttons",
|
||||
"AtlasUI/CustomControls/DraggableListCtrl",
|
||||
"AtlasUI/CustomControls/EditableListCtrl",
|
||||
"AtlasUI/CustomControls/FileHistory",
|
||||
"AtlasUI/CustomControls/HighResTimer",
|
||||
"AtlasUI/CustomControls/SnapSplitterWindow",
|
||||
"AtlasUI/CustomControls/VirtualDirTreeCtrl",
|
||||
"AtlasUI/CustomControls/Windows",
|
||||
"AtlasUI/FileConverter",
|
||||
"AtlasUI/General",
|
||||
"AtlasUI/Misc",
|
||||
"AtlasUI/ScenarioEditor",
|
||||
"AtlasUI/ScenarioEditor/Sections/Common",
|
||||
"AtlasUI/ScenarioEditor/Sections/Map",
|
||||
"AtlasUI/ScenarioEditor/Sections/Object",
|
||||
"AtlasUI/ScenarioEditor/Sections/Terrain",
|
||||
"AtlasUI/ScenarioEditor/Tools",
|
||||
"AtlasUI/ScenarioEditor/Tools/Common"
|
||||
"/ActorEditor",
|
||||
"/ArchiveViewer",
|
||||
"/ColourTester",
|
||||
"/CustomControls/Buttons",
|
||||
"/CustomControls/DraggableListCtrl",
|
||||
"/CustomControls/EditableListCtrl",
|
||||
"/CustomControls/FileHistory",
|
||||
"/CustomControls/HighResTimer",
|
||||
"/CustomControls/SnapSplitterWindow",
|
||||
"/CustomControls/VirtualDirTreeCtrl",
|
||||
"/CustomControls/Windows",
|
||||
"/FileConverter",
|
||||
"/General",
|
||||
"/Misc",
|
||||
"/ScenarioEditor",
|
||||
"/ScenarioEditor/Sections/Common",
|
||||
"/ScenarioEditor/Sections/Map",
|
||||
"/ScenarioEditor/Sections/Object",
|
||||
"/ScenarioEditor/Sections/Terrain",
|
||||
"/ScenarioEditor/Tools",
|
||||
"/ScenarioEditor/Tools/Common"
|
||||
},{
|
||||
-- include
|
||||
"/..",
|
||||
"",
|
||||
"AtlasUI",
|
||||
"AtlasUI/CustomControls"
|
||||
"/CustomControls"
|
||||
},{
|
||||
pch = 1,
|
||||
boost = 1,
|
||||
@ -479,20 +445,20 @@ function setuppackages_atlas()
|
||||
wx = 1,
|
||||
xerces = 1,
|
||||
depends = { "AtlasObject", "DatafileIO" },
|
||||
extrasource = { "AtlasUI/Misc/icons.rc" }
|
||||
extrasource = { "/Misc/icons.rc" }
|
||||
})
|
||||
|
||||
setuppackage_atlas("DatafileIO", "lib", {
|
||||
-- src
|
||||
"DatafileIO",
|
||||
"DatafileIO/BAR",
|
||||
"DatafileIO/DDT",
|
||||
"DatafileIO/SCN",
|
||||
"DatafileIO/Stream",
|
||||
"DatafileIO/XMB"
|
||||
"",
|
||||
"/BAR",
|
||||
"/DDT",
|
||||
"/SCN",
|
||||
"/Stream",
|
||||
"/XMB"
|
||||
},{
|
||||
-- include
|
||||
"DatafileIO"
|
||||
""
|
||||
},{
|
||||
pch = 1,
|
||||
devil = 1,
|
||||
@ -511,10 +477,6 @@ end
|
||||
|
||||
setuppackage_engine("pyrogenesis")
|
||||
|
||||
if (options["sced"]) then
|
||||
setuppackage_engine("sced")
|
||||
end
|
||||
|
||||
if (options["atlas"]) then
|
||||
setuppackages_atlas()
|
||||
end
|
||||
|
@ -1,103 +0,0 @@
|
||||
Premake Changelog
|
||||
-----------------
|
||||
|
||||
1.9
|
||||
* Made verbose mode even more verbose.
|
||||
* posix.c now builds properly as C.
|
||||
* Fixed package dependency generation for GNU and VS2003.
|
||||
* Display Lua version number in usage text.
|
||||
* Fixed VS link between *.aspx and *.aspx.cs files.
|
||||
* Fixed VS link between *.resx and *.cs files.
|
||||
* Fixed *.d file generation for gcc 2.9x.
|
||||
* Unified various help options under '--help'.
|
||||
* Bin and Lib paths can now be arbitrarily long.
|
||||
* linkoptions are now applied in VC6 and VC7 projects.
|
||||
|
||||
1.8
|
||||
* Added support for ASP.NET projects.
|
||||
* Fixed a bug in VC6 support for static libraries.
|
||||
* matchfiles() now uses package path instead of script path.
|
||||
* Added --verbose option.
|
||||
* No longer apply no-rtti and no-exceptions to *.c files.
|
||||
|
||||
1.7
|
||||
* Location of generated project files can now be specified with
|
||||
the project.path variable.
|
||||
* Inter-package dependencies are fixed for GNU makefiles.
|
||||
* No longer need to execute in same directory as project script.
|
||||
* Added "c" language specifier.
|
||||
* Added support for .resx and .config files to C# projects.
|
||||
* Added support for full assembly names in .NET references.
|
||||
* Fixed handling of paths in package.target variable.
|
||||
* Improved support for SharpDevelop.
|
||||
* Started support for OS X.
|
||||
* Added support for Digital Mars compiler.
|
||||
|
||||
1.6.1
|
||||
* VS7 generator crashed if a package was built before one of its
|
||||
dependencies. Now immediately assigns UUID before processing.
|
||||
|
||||
1.6
|
||||
* Added support for Visual Studio 2003 and SharpDevelop.
|
||||
* Added binaries directory as a reference path for VS7.
|
||||
|
||||
1.5
|
||||
* Added initial support for building static libraries.
|
||||
* Added "no-main" flag, prevents overriding WinMain() on
|
||||
Windows builds.
|
||||
* Added "--no-rtti" and "no-exceptions" build flags to
|
||||
disable those C++ features.
|
||||
* Display error message when project has no packages.
|
||||
* Moved VC7 *.pdb files into intermediates directory.
|
||||
|
||||
1.4
|
||||
* Bug fixes to the path manipulation routines.
|
||||
* GNU makefiles are regenerated when premake scripts change.
|
||||
|
||||
1.3
|
||||
* Added support for the Cygwin environment.
|
||||
* Added "static-runtime" build flag to statically link against C/C++
|
||||
standard runtime libraries.
|
||||
* Bug fixes to Visual Studio 6 and 7 generators and path reversing
|
||||
algorithm.
|
||||
|
||||
1.2
|
||||
* Standardized format of command-line options.
|
||||
* Can now handle custom command-line options in script.
|
||||
* Added new function findlib().
|
||||
* Added new C++ build flag "managed" for writing C++ .NET code.
|
||||
* Can now use open-source C# compilers in VS6 generator.
|
||||
* Several bug fixes to the VS7 generator.
|
||||
|
||||
1.1
|
||||
* Added support for custom build configurations. Added "optimize",
|
||||
"optimize-size", "optimize-speed", and "no-symbols" flags to control
|
||||
build settings.
|
||||
* Added matchfiles() to select files using wildcards.
|
||||
* Added "unsafe" flag for C# projects.
|
||||
* Added newpackage() function for creating new package objects inline,
|
||||
instead of creating separate scripts.
|
||||
* Changed include() to dopackage() and option() to addoption(). The old
|
||||
versions have been kept for compatibility, but will be deprecated
|
||||
eventually.
|
||||
* Major cleanup of the source code.
|
||||
|
||||
1.0
|
||||
* Fixed a bug related to the reference paths in VS7 C# projects.
|
||||
* Display a warning message if a reference path can't be found.
|
||||
* Automatically create bin and lib directories if they do not exist.
|
||||
* GNU C# projects will now properly use the configured library paths.
|
||||
|
||||
0.9.2
|
||||
* Added --with-mono and --with-pnet options.
|
||||
* VS7 C# projects will now properly use the configured library paths.
|
||||
|
||||
0.9.1
|
||||
* Switched to Lua (http://www.lua.org/) for project script parsing.
|
||||
* Add support for custom project options.
|
||||
* Changed 'type' to 'kind' to avoid conflict with Lua function of the same name.
|
||||
* Changed 'conexe' to 'exe' because I liked it better.
|
||||
* Changed 'library' to 'dll' for C# projects to keep things consistent.
|
||||
|
||||
0.9.0
|
||||
* Initial public release.
|
@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
@ -1,24 +0,0 @@
|
||||
# Makefile autogenerated by premake
|
||||
# Options:
|
||||
# CONFIG=[Debug|Release]
|
||||
|
||||
ifndef CONFIG
|
||||
CONFIG=Debug
|
||||
endif
|
||||
|
||||
export CONFIG
|
||||
|
||||
.PHONY: all clean Premake
|
||||
|
||||
all: Premake
|
||||
|
||||
Makefile: ./premake.lua
|
||||
@echo ==== Regenerating Makefiles ====
|
||||
@premake --target gnu
|
||||
|
||||
Premake:
|
||||
@echo ==== Building Premake ====
|
||||
@$(MAKE) --no-print-directory -C ./ -f Premake.make
|
||||
|
||||
clean:
|
||||
@$(MAKE) --no-print-directory -C ./ -f Premake.make clean
|
@ -1,325 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="Premake" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=Premake - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Premake.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Premake.mak" CFG="Premake - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Premake - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "Premake - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Premake - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug\"
|
||||
# PROP BASE Intermediate_Dir "Debug\"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ".\"
|
||||
# PROP Intermediate_Dir "obj\Debug\"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /GX /GR /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /debug /pdbtype:sept
|
||||
# ADD LINK32 /nologo /subsystem:console /out:".\premake.exe" /machine:I386 /pdbtype:sept /libpath:".\" /pdb:".\premake.pdb" /debug
|
||||
!ELSEIF "$(CFG)" == "Premake - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release\"
|
||||
# PROP BASE Intermediate_Dir "Release\"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir ".\"
|
||||
# PROP Intermediate_Dir "obj\Release\"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /GR /O1 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 /nologo /subsystem:console /out:".\premake.exe" /machine:I386 /pdbtype:sept /libpath:".\"
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Premake - Win32 Debug"
|
||||
# Name "Premake - Win32 Release"
|
||||
# Begin Group "Src"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "Lua"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lapi.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lauxlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lbaselib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lcode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ldebug.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ldo.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lfunc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lgc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\liolib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\llex.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lmathlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lmem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lobject.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lparser.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lstate.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lstring.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lstrlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ltable.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ltests.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ltm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lundump.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lvm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lzio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lapi.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lauxlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lcode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ldebug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ldo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lfunc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lgc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\llex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\llimits.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lmem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lobject.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lopcodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lparser.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lstate.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lstring.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ltable.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\ltm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lua.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\luadebug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lualib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lundump.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lvm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\Lua\lzio.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\premake.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\project.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\project.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\util.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\util.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\clean.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\gnu.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\sharpdev.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\vs7.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\vs6.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Src\windows.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
@ -1,29 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Premake"=.\Premake.dsp
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
@ -1,112 +0,0 @@
|
||||
# Sub-makefile autogenerated by premake
|
||||
|
||||
BINDIR = .
|
||||
LIBDIR = .
|
||||
|
||||
CFLAGS =
|
||||
LDFLAGS = -L$(BINDIR) -L$(LIBDIR)
|
||||
TARGET =
|
||||
|
||||
ifeq ($(CONFIG),Debug)
|
||||
CFLAGS +=
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
LDFLAGS +=
|
||||
TARGET = premake
|
||||
endif
|
||||
ifeq ($(CONFIG),Release)
|
||||
CFLAGS += -Os
|
||||
CXXFLAGS = $(CFLAGS) -Os
|
||||
LDFLAGS +=
|
||||
TARGET = premake
|
||||
endif
|
||||
|
||||
obj/%.o : %.cc
|
||||
-@if [ ! -d obj ]; then mkdir obj; fi
|
||||
@echo $(notdir $<)
|
||||
@$(CXX) $(CXXFLAGS) -MD -o $@ -c $<
|
||||
-@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi
|
||||
@cp obj/$*.d obj/$*.P; \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \
|
||||
rm -f obj/$*.d
|
||||
|
||||
obj/%.o : %.cpp
|
||||
-@if [ ! -d obj ]; then mkdir obj; fi
|
||||
@echo $(notdir $<)
|
||||
@$(CXX) $(CXXFLAGS) -MD -o $@ -c $<
|
||||
-@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi
|
||||
@cp obj/$*.d obj/$*.P; \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \
|
||||
rm -f obj/$*.d
|
||||
|
||||
obj/%.o : %.cxx
|
||||
-@if [ ! -d obj ]; then mkdir obj; fi
|
||||
@echo $(notdir $<)
|
||||
@$(CXX) $(CXXFLAGS) -MD -o $@ -c $<
|
||||
-@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi
|
||||
@cp obj/$*.d obj/$*.P; \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \
|
||||
rm -f obj/$*.d
|
||||
|
||||
obj/%.o : %.c
|
||||
-@if [ ! -d obj ]; then mkdir obj; fi
|
||||
@echo $(notdir $<)
|
||||
@$(CC) $(CFLAGS) -MD -o $@ -c $<
|
||||
-@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi
|
||||
@cp obj/$*.d obj/$*.P; \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \
|
||||
rm -f obj/$*.d
|
||||
|
||||
OBJECTS = \
|
||||
obj/premake.o \
|
||||
obj/project.o \
|
||||
obj/util.o \
|
||||
obj/clean.o \
|
||||
obj/gnu.o \
|
||||
obj/sharpdev.o \
|
||||
obj/vs7.o \
|
||||
obj/vs6.o \
|
||||
obj/lapi.o \
|
||||
obj/lauxlib.o \
|
||||
obj/lbaselib.o \
|
||||
obj/lcode.o \
|
||||
obj/ldebug.o \
|
||||
obj/ldo.o \
|
||||
obj/lfunc.o \
|
||||
obj/lgc.o \
|
||||
obj/liolib.o \
|
||||
obj/llex.o \
|
||||
obj/lmathlib.o \
|
||||
obj/lmem.o \
|
||||
obj/lobject.o \
|
||||
obj/lparser.o \
|
||||
obj/lstate.o \
|
||||
obj/lstring.o \
|
||||
obj/lstrlib.o \
|
||||
obj/ltable.o \
|
||||
obj/ltests.o \
|
||||
obj/ltm.o \
|
||||
obj/lundump.o \
|
||||
obj/lvm.o \
|
||||
obj/lzio.o \
|
||||
obj/posix.o \
|
||||
|
||||
VPATH = Src Src/Lua
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||
@echo Linking Premake
|
||||
-@if [ ! -d $(BINDIR) ]; then mkdir $(BINDIR); fi
|
||||
-@if [ ! -d $(LIBDIR) ]; then mkdir $(LIBDIR); fi
|
||||
@$(CXX) -o $@ $(filter-out %.so, $^) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
@echo Cleaning Premake
|
||||
-@rm -rf $(BINDIR)/$(TARGET) obj/*
|
||||
|
||||
-include $(OBJECTS:%.o=%.P)
|
||||
|
@ -1,21 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Premake", "Premake.vcproj", "{D240CFA2-A134-D147-8EF3-30B485E4E25F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{D240CFA2-A134-D147-8EF3-30B485E4E25F}.Debug.ActiveCfg = Debug|Win32
|
||||
{D240CFA2-A134-D147-8EF3-30B485E4E25F}.Debug.Build.0 = Debug|Win32
|
||||
{D240CFA2-A134-D147-8EF3-30B485E4E25F}.Release.ActiveCfg = Release|Win32
|
||||
{D240CFA2-A134-D147-8EF3-30B485E4E25F}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,314 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="Premake"
|
||||
ProjectGUID="{D240CFA2-A134-D147-8EF3-30B485E4E25F}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".."
|
||||
IntermediateDirectory="obj\Debug\"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
IgnoreImportLibrary="TRUE"
|
||||
AdditionalOptions=""
|
||||
AdditionalDependencies=""
|
||||
OutputFile="$(OutDir)\premake.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=".\"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="obj\Debug\premake.pdb"
|
||||
SubSystem="1"
|
||||
EntryPointSymbol="mainCRTStartup"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".."
|
||||
IntermediateDirectory="obj\Release\"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="1"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="TRUE"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
StringPooling="TRUE"
|
||||
MinimalRebuild="FALSE"
|
||||
BasicRuntimeChecks="0"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
IgnoreImportLibrary="TRUE"
|
||||
AdditionalOptions=""
|
||||
AdditionalDependencies=""
|
||||
OutputFile="$(OutDir)\premake.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=".\"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
EntryPointSymbol="mainCRTStartup"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Src"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="Src\clean.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\gnu.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\premake.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\project.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\project.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\sharpdev.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\util.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\util.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\vs6.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\vs7.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\windows.c">
|
||||
</File>
|
||||
<Filter
|
||||
Name="Lua"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="Src\Lua\lapi.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lapi.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lauxlib.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lauxlib.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lbaselib.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lcode.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lcode.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ldebug.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ldebug.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ldo.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ldo.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lfunc.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lfunc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lgc.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lgc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\liolib.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\llex.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\llex.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\llimits.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lmathlib.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lmem.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lmem.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lobject.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lobject.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lopcodes.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lparser.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lparser.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lstate.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lstate.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lstring.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lstring.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lstrlib.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ltable.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ltable.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ltests.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ltm.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\ltm.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lua.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\luadebug.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lualib.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lundump.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lundump.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lvm.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lvm.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lzio.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Src\Lua\lzio.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,20 +0,0 @@
|
||||
PREMAKE v1.8
|
||||
|
||||
Copyright (C) 2002-2004 by Jason Perkins
|
||||
Distributed under the GNU General Public License, see LICENSE.txt
|
||||
|
||||
The Lua language and runtime library is (C) TeCGraf, PUC-Rio.
|
||||
See their website at http://www.lua.org/
|
||||
|
||||
|
||||
BUILDING PREMAKE
|
||||
|
||||
GNU make: type 'make'
|
||||
|
||||
MS Visual C++ v6: open Premake.dsw and build.
|
||||
|
||||
MS Visual C++ v7: open Premake.sln and build.
|
||||
|
||||
|
||||
For questions, comments, or more information, visit the project
|
||||
website at http://premake.sourceforge.net/
|
@ -1,54 +0,0 @@
|
||||
Lua Copyright Notice
|
||||
--------------------
|
||||
|
||||
Lua is free and non-proprietary.
|
||||
It can be used for both academic and commercial purposes at absolutely no cost.
|
||||
There are no royalties or GNU-like "copyleft" restrictions.
|
||||
Lua (probably) qualifies as Open Source software.
|
||||
Nevertheless, Lua is not in the public domain and TeCGraf keeps its copyright.
|
||||
|
||||
If you use Lua, please give us credit (a nice way to do this is to include a
|
||||
Lua logo in a web page for your product), but we would appreciate *not*
|
||||
receiving lengthy legal documents to sign.
|
||||
|
||||
The legal details are below.
|
||||
|
||||
===============================================================================
|
||||
|
||||
Copyright (C) 1994-2000 TeCGraf, PUC-Rio. All rights reserved.
|
||||
|
||||
Permission is hereby granted, without written agreement and without license
|
||||
or royalty fees, to use, copy, modify, translate, and distribute
|
||||
this software and its documentation (hereby called the "package")
|
||||
for any purpose, including commercial applications, subject to
|
||||
the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall appear in all
|
||||
copies or substantial portions of this package.
|
||||
|
||||
* The origin of this package must not be misrepresented; you must not
|
||||
claim that you wrote the original package. If you use this package in a
|
||||
product, an acknowledgment in the product documentation would be greatly
|
||||
appreciated (but it is not required).
|
||||
|
||||
* Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original package.
|
||||
|
||||
The authors specifically disclaim any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability and fitness for a particular
|
||||
purpose. The package provided hereunder is on an "as is" basis, and the
|
||||
authors have no obligation to provide maintenance, support, updates,
|
||||
enhancements, or modifications. In no event shall TeCGraf, PUC-Rio, or the
|
||||
authors be held liable to any party for direct, indirect, special,
|
||||
incidental, or consequential damages arising out of the use of this package
|
||||
and its documentation.
|
||||
|
||||
The Lua language and this implementation have been entirely designed and written
|
||||
by Waldemar Celes, Roberto Ierusalimschy, and Luiz Henrique de Figueiredo
|
||||
at TeCGraf, PUC-Rio in Brazil.
|
||||
|
||||
This implementation contains no third-party code.
|
||||
|
||||
===============================================================================
|
||||
|
||||
(end of COPYRIGHT)
|
@ -1,72 +0,0 @@
|
||||
This is Lua 4.0.
|
||||
See HISTORY for a summary of changes since the last version.
|
||||
|
||||
* What is Lua?
|
||||
------------
|
||||
Lua is a powerful, light-weight programming language designed for extending
|
||||
applications. Lua is also frequently used as a general-purpose, stand-alone
|
||||
language.
|
||||
|
||||
Lua combines simple procedural syntax (similar to Pascal) with powerful
|
||||
data description constructs based on associative arrays and extensible
|
||||
semantics. Lua is dynamically typed, interpreted from bytecodes, and has
|
||||
automatic memory management, making it ideal for configuration, scripting,
|
||||
and rapid prototyping.
|
||||
|
||||
Lua is a language engine that you can embed into your application.
|
||||
This means that, besides syntax and semantics, Lua has an API that
|
||||
allows the application to exchange data with Lua programs and also to
|
||||
extend Lua with C functions. In this sense, Lua can be regarded as a
|
||||
language framework for building domain-specific languages.
|
||||
|
||||
Lua is implemented as a small library of C functions, written in ANSI C,
|
||||
and compiles unmodified in all known platforms. The implementation goals
|
||||
are simplicity, efficiency, portability, and low embedding cost.
|
||||
The result is a fast language engine with small footprint, making it
|
||||
ideal in embedded systems too.
|
||||
|
||||
Lua was awarded the first prize (technological category) in the
|
||||
Second Compaq Award for Research and Development in Computer Science in 1997.
|
||||
This award was a joint venture of Compaq Computer in Brazil, the Brazilian
|
||||
Ministry of Science and Technology, and the Brazilian Academy of Sciences.
|
||||
|
||||
Lua has been used in many different projects around the world.
|
||||
For a short list, see http://www.tecgraf.puc-rio.br/lua/uses.html .
|
||||
|
||||
* Availability
|
||||
------------
|
||||
Lua is freely available for both academic and commercial purposes and
|
||||
can be downloaded from the sites below. See COPYRIGHT for details.
|
||||
|
||||
Home page: http://www.tecgraf.puc-rio.br/lua/
|
||||
http://csg.uwaterloo.ca/~lhf/lua/
|
||||
In Brazil: ftp://ftp.tecgraf.puc-rio.br/pub/lua/
|
||||
In Canada: ftp://csg.uwaterloo.ca/pub/lhf/lua/
|
||||
In the US: ftp://ftp.freesoftware.com/pub/languages/lua/
|
||||
In Germany: ftp://ftp.uni-trier.de/pub/languages/lua/
|
||||
In Germany: ftp://ftp.gwdg.de/pub/languages/lua/
|
||||
In Greece: ftp://ftp.ntua.gr/pub/lang/lua/
|
||||
In Japan: ftp://ftp.u-aizu.ac.jp/pub/lang/lua/
|
||||
In Denmark: ftp://ftp.ucore.com/lua/dist
|
||||
|
||||
* Installation
|
||||
------------
|
||||
See INSTALL.
|
||||
|
||||
* Contacting the authors
|
||||
----------------------
|
||||
Lua was designed and implemented by Waldemar Celes, Roberto Ierusalimschy
|
||||
and Luiz Henrique de Figueiredo.
|
||||
They can be contacted by email at lua@tecgraf.puc-rio.br.
|
||||
|
||||
Send your comments, questions, and bug reports to lua@tecgraf.puc-rio.br.
|
||||
For reporting bugs, try also the mailing list: lua-l@tecgraf.puc-rio.br.
|
||||
For more information about this list, including instructions on how to
|
||||
subscribe, see http://www.tecgraf.puc-rio.br/lua/lua-l.html .
|
||||
|
||||
Lua is developed at TeCGraf, the Computer Graphics Technology Group
|
||||
of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro in Brazil).
|
||||
TeCGraf is a laboratory of the Department of Computer Science.
|
||||
Dozens of industrial products developed by TeCGraf use Lua.
|
||||
|
||||
(end of README)
|
@ -1,494 +0,0 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 1.1 2003/01/24 16:25:58 jason379 Exp $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lapi.h"
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lgc.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
#include "lvm.h"
|
||||
|
||||
|
||||
const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
|
||||
"$Authors: " LUA_AUTHORS " $";
|
||||
|
||||
|
||||
|
||||
#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
|
||||
|
||||
#define api_incr_top(L) incr_top
|
||||
|
||||
|
||||
|
||||
|
||||
TObject *luaA_index (lua_State *L, int index) {
|
||||
return Index(L, index);
|
||||
}
|
||||
|
||||
|
||||
static TObject *luaA_indexAcceptable (lua_State *L, int index) {
|
||||
if (index >= 0) {
|
||||
TObject *o = L->Cbase+(index-1);
|
||||
if (o >= L->top) return NULL;
|
||||
else return o;
|
||||
}
|
||||
else return L->top+index;
|
||||
}
|
||||
|
||||
|
||||
void luaA_pushobject (lua_State *L, const TObject *o) {
|
||||
*L->top = *o;
|
||||
incr_top;
|
||||
}
|
||||
|
||||
LUA_API int lua_stackspace (lua_State *L) {
|
||||
return (L->stack_last - L->top);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** basic stack manipulation
|
||||
*/
|
||||
|
||||
|
||||
LUA_API int lua_gettop (lua_State *L) {
|
||||
return (L->top - L->Cbase);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_settop (lua_State *L, int index) {
|
||||
if (index >= 0)
|
||||
luaD_adjusttop(L, L->Cbase, index);
|
||||
else
|
||||
L->top = L->top+index+1; /* index is negative */
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_remove (lua_State *L, int index) {
|
||||
StkId p = luaA_index(L, index);
|
||||
while (++p < L->top) *(p-1) = *p;
|
||||
L->top--;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_insert (lua_State *L, int index) {
|
||||
StkId p = luaA_index(L, index);
|
||||
StkId q;
|
||||
for (q = L->top; q>p; q--)
|
||||
*q = *(q-1);
|
||||
*p = *L->top;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushvalue (lua_State *L, int index) {
|
||||
*L->top = *luaA_index(L, index);
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** access functions (stack -> C)
|
||||
*/
|
||||
|
||||
|
||||
LUA_API int lua_type (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL) ? LUA_TNONE : ttype(o);
|
||||
}
|
||||
|
||||
LUA_API const char *lua_typename (lua_State *L, int t) {
|
||||
UNUSED(L);
|
||||
return (t == LUA_TNONE) ? "no value" : luaO_typenames[t];
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_iscfunction (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL) ? 0 : iscfunction(o);
|
||||
}
|
||||
|
||||
LUA_API int lua_isnumber (lua_State *L, int index) {
|
||||
TObject *o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL) ? 0 : (tonumber(o) == 0);
|
||||
}
|
||||
|
||||
LUA_API int lua_isstring (lua_State *L, int index) {
|
||||
int t = lua_type(L, index);
|
||||
return (t == LUA_TSTRING || t == LUA_TNUMBER);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_tag (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL) ? LUA_NOTAG : luaT_tag(o);
|
||||
}
|
||||
|
||||
LUA_API int lua_equal (lua_State *L, int index1, int index2) {
|
||||
StkId o1 = luaA_indexAcceptable(L, index1);
|
||||
StkId o2 = luaA_indexAcceptable(L, index2);
|
||||
if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */
|
||||
else return luaO_equalObj(o1, o2);
|
||||
}
|
||||
|
||||
LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
|
||||
StkId o1 = luaA_indexAcceptable(L, index1);
|
||||
StkId o2 = luaA_indexAcceptable(L, index2);
|
||||
if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */
|
||||
else return luaV_lessthan(L, o1, o2, L->top);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LUA_API double lua_tonumber (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL || tonumber(o)) ? 0 : nvalue(o);
|
||||
}
|
||||
|
||||
LUA_API const char *lua_tostring (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL || tostring(L, o)) ? NULL : svalue(o);
|
||||
}
|
||||
|
||||
LUA_API size_t lua_strlen (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len;
|
||||
}
|
||||
|
||||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c;
|
||||
}
|
||||
|
||||
LUA_API void *lua_touserdata (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL :
|
||||
tsvalue(o)->u.d.value;
|
||||
}
|
||||
|
||||
LUA_API const void *lua_topointer (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
if (o == NULL) return NULL;
|
||||
switch (ttype(o)) {
|
||||
case LUA_TTABLE:
|
||||
return hvalue(o);
|
||||
case LUA_TFUNCTION:
|
||||
return clvalue(o);
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** push functions (C -> stack)
|
||||
*/
|
||||
|
||||
|
||||
LUA_API void lua_pushnil (lua_State *L) {
|
||||
ttype(L->top) = LUA_TNIL;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushnumber (lua_State *L, double n) {
|
||||
nvalue(L->top) = n;
|
||||
ttype(L->top) = LUA_TNUMBER;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
||||
tsvalue(L->top) = luaS_newlstr(L, s, len);
|
||||
ttype(L->top) = LUA_TSTRING;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushstring (lua_State *L, const char *s) {
|
||||
if (s == NULL)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
lua_pushlstring(L, s, strlen(s));
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||
luaV_Cclosure(L, fn, n);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
|
||||
/* ORDER LUA_T */
|
||||
if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(tag)))
|
||||
luaO_verror(L, "invalid tag for a userdata (%d)", tag);
|
||||
tsvalue(L->top) = luaS_createudata(L, u, tag);
|
||||
ttype(L->top) = LUA_TUSERDATA;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
*/
|
||||
|
||||
|
||||
LUA_API void lua_getglobal (lua_State *L, const char *name) {
|
||||
StkId top = L->top;
|
||||
*top = *luaV_getglobal(L, luaS_new(L, name));
|
||||
L->top = top;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_gettable (lua_State *L, int index) {
|
||||
StkId t = Index(L, index);
|
||||
StkId top = L->top;
|
||||
*(top-1) = *luaV_gettable(L, t);
|
||||
L->top = top; /* tag method may change top */
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawget (lua_State *L, int index) {
|
||||
StkId t = Index(L, index);
|
||||
LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
|
||||
*(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
|
||||
StkId o = Index(L, index);
|
||||
LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
|
||||
*L->top = *luaH_getnum(hvalue(o), n);
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_getglobals (lua_State *L) {
|
||||
hvalue(L->top) = L->gt;
|
||||
ttype(L->top) = LUA_TTABLE;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_getref (lua_State *L, int ref) {
|
||||
if (ref == LUA_REFNIL)
|
||||
ttype(L->top) = LUA_TNIL;
|
||||
else if (0 <= ref && ref < L->refSize &&
|
||||
(L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
|
||||
*L->top = L->refArray[ref].o;
|
||||
else
|
||||
return 0;
|
||||
api_incr_top(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_newtable (lua_State *L) {
|
||||
hvalue(L->top) = luaH_new(L, 0);
|
||||
ttype(L->top) = LUA_TTABLE;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
*/
|
||||
|
||||
|
||||
LUA_API void lua_setglobal (lua_State *L, const char *name) {
|
||||
StkId top = L->top;
|
||||
luaV_setglobal(L, luaS_new(L, name));
|
||||
L->top = top-1; /* remove element from the top */
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_settable (lua_State *L, int index) {
|
||||
StkId t = Index(L, index);
|
||||
StkId top = L->top;
|
||||
luaV_settable(L, t, top-2);
|
||||
L->top = top-2; /* pop index and value */
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawset (lua_State *L, int index) {
|
||||
StkId t = Index(L, index);
|
||||
LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
|
||||
*luaH_set(L, hvalue(t), L->top-2) = *(L->top-1);
|
||||
L->top -= 2;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawseti (lua_State *L, int index, int n) {
|
||||
StkId o = Index(L, index);
|
||||
LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
|
||||
*luaH_setint(L, hvalue(o), n) = *(L->top-1);
|
||||
L->top--;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_setglobals (lua_State *L) {
|
||||
StkId newtable = --L->top;
|
||||
LUA_ASSERT(ttype(newtable) == LUA_TTABLE, "table expected");
|
||||
L->gt = hvalue(newtable);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_ref (lua_State *L, int lock) {
|
||||
int ref;
|
||||
if (ttype(L->top-1) == LUA_TNIL)
|
||||
ref = LUA_REFNIL;
|
||||
else {
|
||||
if (L->refFree != NONEXT) { /* is there a free place? */
|
||||
ref = L->refFree;
|
||||
L->refFree = L->refArray[ref].st;
|
||||
}
|
||||
else { /* no more free places */
|
||||
luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
|
||||
"reference table overflow", MAX_INT);
|
||||
L->nblocks += sizeof(struct Ref);
|
||||
ref = L->refSize++;
|
||||
}
|
||||
L->refArray[ref].o = *(L->top-1);
|
||||
L->refArray[ref].st = lock ? LOCK : HOLD;
|
||||
}
|
||||
L->top--;
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** "do" functions (run Lua code)
|
||||
** (most of them are in ldo.c)
|
||||
*/
|
||||
|
||||
LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
|
||||
luaD_call(L, L->top-(nargs+1), nresults);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Garbage-collection functions
|
||||
*/
|
||||
|
||||
/* GC values are expressed in Kbytes: #bytes/2^10 */
|
||||
#define GCscale(x) ((int)((x)>>10))
|
||||
#define GCunscale(x) ((unsigned long)(x)<<10)
|
||||
|
||||
LUA_API int lua_getgcthreshold (lua_State *L) {
|
||||
return GCscale(L->GCthreshold);
|
||||
}
|
||||
|
||||
LUA_API int lua_getgccount (lua_State *L) {
|
||||
return GCscale(L->nblocks);
|
||||
}
|
||||
|
||||
LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
|
||||
if (newthreshold > GCscale(ULONG_MAX))
|
||||
L->GCthreshold = ULONG_MAX;
|
||||
else
|
||||
L->GCthreshold = GCunscale(newthreshold);
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** miscellaneous functions
|
||||
*/
|
||||
|
||||
LUA_API void lua_settag (lua_State *L, int tag) {
|
||||
luaT_realtag(L, tag);
|
||||
switch (ttype(L->top-1)) {
|
||||
case LUA_TTABLE:
|
||||
hvalue(L->top-1)->htag = tag;
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
tsvalue(L->top-1)->u.d.tag = tag;
|
||||
break;
|
||||
default:
|
||||
luaO_verror(L, "cannot change the tag of a %.20s",
|
||||
luaO_typename(L->top-1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_unref (lua_State *L, int ref) {
|
||||
if (ref >= 0) {
|
||||
LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref");
|
||||
L->refArray[ref].st = L->refFree;
|
||||
L->refFree = ref;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_next (lua_State *L, int index) {
|
||||
StkId t = luaA_index(L, index);
|
||||
Node *n;
|
||||
LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
|
||||
n = luaH_next(L, hvalue(t), luaA_index(L, -1));
|
||||
if (n) {
|
||||
*(L->top-1) = *key(n);
|
||||
*L->top = *val(n);
|
||||
api_incr_top(L);
|
||||
return 1;
|
||||
}
|
||||
else { /* no more elements */
|
||||
L->top -= 1; /* remove key */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_getn (lua_State *L, int index) {
|
||||
Hash *h = hvalue(luaA_index(L, index));
|
||||
const TObject *value = luaH_getstr(h, luaS_new(L, "n")); /* value = h.n */
|
||||
if (ttype(value) == LUA_TNUMBER)
|
||||
return (int)nvalue(value);
|
||||
else {
|
||||
Number max = 0;
|
||||
int i = h->size;
|
||||
Node *n = h->node;
|
||||
while (i--) {
|
||||
if (ttype(key(n)) == LUA_TNUMBER &&
|
||||
ttype(val(n)) != LUA_TNIL &&
|
||||
nvalue(key(n)) > max)
|
||||
max = nvalue(key(n));
|
||||
n++;
|
||||
}
|
||||
return (int)max;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_concat (lua_State *L, int n) {
|
||||
StkId top = L->top;
|
||||
luaV_strconc(L, n, top);
|
||||
L->top = top-(n-1);
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
|
||||
TString *ts = luaS_newudata(L, (size==0) ? 1 : size, NULL);
|
||||
tsvalue(L->top) = ts;
|
||||
ttype(L->top) = LUA_TUSERDATA;
|
||||
api_incr_top(L);
|
||||
return ts->u.d.value;
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
** $Id: lapi.h,v 1.1 2003/01/24 16:25:58 jason379 Exp $
|
||||
** Auxiliary functions from Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lapi_h
|
||||
#define lapi_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
TObject *luaA_index (lua_State *L, int index);
|
||||
void luaA_pushobject (lua_State *L, const TObject *o);
|
||||
|
||||
#endif
|
@ -1,216 +0,0 @@
|
||||
/*
|
||||
** $Id: lauxlib.c,v 1.2 2003/04/23 12:16:05 jason379 Exp $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* This file uses only the official API of Lua.
|
||||
** Any function declared here could be written as an application function.
|
||||
** With care, these functions can be used by other libraries.
|
||||
*/
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "luadebug.h"
|
||||
|
||||
|
||||
|
||||
LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
|
||||
int i;
|
||||
for (i=0; list[i]; i++)
|
||||
if (strcmp(list[i], name) == 0)
|
||||
return i;
|
||||
return -1; /* name not found */
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
|
||||
lua_Debug ar;
|
||||
lua_getstack(L, 0, &ar);
|
||||
lua_getinfo(L, "n", &ar);
|
||||
if (ar.name == NULL)
|
||||
ar.name = "?";
|
||||
luaL_verror(L, "bad argument #%d to `%.50s' (%.100s)",
|
||||
narg, ar.name, extramsg);
|
||||
}
|
||||
|
||||
|
||||
static void type_error (lua_State *L, int narg, int t) {
|
||||
char buff[50];
|
||||
sprintf(buff, "%.8s expected, got %.8s", lua_typename(L, t),
|
||||
lua_typename(L, lua_type(L, narg)));
|
||||
luaL_argerror(L, narg, buff);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
|
||||
if (space > lua_stackspace(L))
|
||||
luaL_verror(L, "stack overflow (%.30s)", mes);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) {
|
||||
if (lua_type(L, narg) != t)
|
||||
type_error(L, narg, t);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_checkany (lua_State *L, int narg) {
|
||||
if (lua_type(L, narg) == LUA_TNONE)
|
||||
luaL_argerror(L, narg, "value expected");
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
|
||||
const char *s = lua_tostring(L, narg);
|
||||
if (!s) type_error(L, narg, LUA_TSTRING);
|
||||
if (len) *len = lua_strlen(L, narg);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API const char *luaL_opt_lstr (lua_State *L, int narg, const char *def, size_t *len) {
|
||||
if (lua_isnull(L, narg)) {
|
||||
if (len)
|
||||
*len = (def ? strlen(def) : 0);
|
||||
return def;
|
||||
}
|
||||
else return luaL_check_lstr(L, narg, len);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API double luaL_check_number (lua_State *L, int narg) {
|
||||
double d = lua_tonumber(L, narg);
|
||||
if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
|
||||
type_error(L, narg, LUA_TNUMBER);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API double luaL_opt_number (lua_State *L, int narg, double def) {
|
||||
if (lua_isnull(L, narg)) return def;
|
||||
else return luaL_check_number(L, narg);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) {
|
||||
int i;
|
||||
for (i=0; i<n; i++)
|
||||
lua_register(L, l[i].name, l[i].func);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...) {
|
||||
char buff[500];
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
vsprintf(buff, fmt, argp);
|
||||
va_end(argp);
|
||||
lua_error(L, buff);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Generic Buffer manipulation
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
#define buffempty(B) ((B)->p == (B)->buffer)
|
||||
#define bufflen(B) ((B)->p - (B)->buffer)
|
||||
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
|
||||
|
||||
#define LIMIT (LUA_MINSTACK/2)
|
||||
|
||||
|
||||
static int emptybuffer (luaL_Buffer *B) {
|
||||
size_t l = bufflen(B);
|
||||
if (l == 0) return 0; /* put nothing on stack */
|
||||
else {
|
||||
lua_pushlstring(B->L, B->buffer, l);
|
||||
B->p = B->buffer;
|
||||
B->level++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void adjuststack (luaL_Buffer *B) {
|
||||
if (B->level > 1) {
|
||||
lua_State *L = B->L;
|
||||
int toget = 1; /* number of levels to concat */
|
||||
size_t toplen = lua_strlen(L, -1);
|
||||
do {
|
||||
size_t l = lua_strlen(L, -(toget+1));
|
||||
if (B->level - toget + 1 >= LIMIT || toplen > l) {
|
||||
toplen += l;
|
||||
toget++;
|
||||
}
|
||||
else break;
|
||||
} while (toget < B->level);
|
||||
if (toget >= 2) {
|
||||
lua_concat(L, toget);
|
||||
B->level = B->level - toget + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
|
||||
if (emptybuffer(B))
|
||||
adjuststack(B);
|
||||
return B->buffer;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
|
||||
while (l--)
|
||||
luaL_putchar(B, *s++);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
|
||||
luaL_addlstring(B, s, strlen(s));
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
|
||||
emptybuffer(B);
|
||||
if (B->level == 0)
|
||||
lua_pushlstring(B->L, NULL, 0);
|
||||
else if (B->level > 1)
|
||||
lua_concat(B->L, B->level);
|
||||
B->level = 1;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
|
||||
lua_State *L = B->L;
|
||||
size_t vl = lua_strlen(L, -1);
|
||||
if (vl <= bufffree(B)) { /* fit into buffer? */
|
||||
memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */
|
||||
B->p += vl;
|
||||
lua_pop(L, 1); /* remove from stack */
|
||||
}
|
||||
else {
|
||||
if (emptybuffer(B))
|
||||
lua_insert(L, -2); /* put buffer before new value */
|
||||
B->level++; /* add new value into B stack */
|
||||
adjuststack(B);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
|
||||
B->L = L;
|
||||
B->p = B->buffer;
|
||||
B->level = 0;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
** $Id: lauxlib.h,v 1.1 2003/01/24 16:25:59 jason379 Exp $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lauxlib_h
|
||||
#define lauxlib_h
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
#ifndef LUALIB_API
|
||||
#define LUALIB_API extern
|
||||
#endif
|
||||
|
||||
|
||||
struct luaL_reg {
|
||||
const char *name;
|
||||
lua_CFunction func;
|
||||
};
|
||||
|
||||
|
||||
LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n);
|
||||
LUALIB_API void luaL_argerror (lua_State *L, int numarg, const char *extramsg);
|
||||
LUALIB_API const char *luaL_check_lstr (lua_State *L, int numArg, size_t *len);
|
||||
LUALIB_API const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def, size_t *len);
|
||||
LUALIB_API double luaL_check_number (lua_State *L, int numArg);
|
||||
LUALIB_API double luaL_opt_number (lua_State *L, int numArg, double def);
|
||||
|
||||
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg);
|
||||
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
|
||||
LUALIB_API void luaL_checkany (lua_State *L, int narg);
|
||||
|
||||
LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...);
|
||||
LUALIB_API int luaL_findstring (const char *name, const char *const list[]);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define luaL_arg_check(L, cond,numarg,extramsg) if (!(cond)) \
|
||||
luaL_argerror(L, numarg,extramsg)
|
||||
#define luaL_check_string(L,n) (luaL_check_lstr(L, (n), NULL))
|
||||
#define luaL_opt_string(L,n,d) (luaL_opt_lstr(L, (n), (d), NULL))
|
||||
#define luaL_check_int(L,n) ((int)luaL_check_number(L, n))
|
||||
#define luaL_check_long(L,n) ((long)luaL_check_number(L, n))
|
||||
#define luaL_opt_int(L,n,d) ((int)luaL_opt_number(L, n,d))
|
||||
#define luaL_opt_long(L,n,d) ((long)luaL_opt_number(L, n,d))
|
||||
#define luaL_openl(L,a) luaL_openlib(L, a, (sizeof(a)/sizeof(a[0])))
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Generic Buffer manipulation
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LUAL_BUFFERSIZE
|
||||
#define LUAL_BUFFERSIZE BUFSIZ
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct luaL_Buffer {
|
||||
char *p; /* current position in buffer */
|
||||
int level;
|
||||
lua_State *L;
|
||||
char buffer[LUAL_BUFFERSIZE];
|
||||
} luaL_Buffer;
|
||||
|
||||
#define luaL_putchar(B,c) \
|
||||
((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \
|
||||
(*(B)->p++ = (char)(c)))
|
||||
|
||||
#define luaL_addsize(B,n) ((B)->p += (n))
|
||||
|
||||
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B);
|
||||
LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B);
|
||||
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
|
||||
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s);
|
||||
LUALIB_API void luaL_addvalue (luaL_Buffer *B);
|
||||
LUALIB_API void luaL_pushresult (luaL_Buffer *B);
|
||||
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,651 +0,0 @@
|
||||
/*
|
||||
** $Id: lbaselib.c,v 1.2 2003/04/23 12:16:05 jason379 Exp $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "luadebug.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** If your system does not support `stderr', redefine this function, or
|
||||
** redefine _ERRORMESSAGE so that it won't need _ALERT.
|
||||
*/
|
||||
static int luaB__ALERT (lua_State *L) {
|
||||
fputs(luaL_check_string(L, 1), stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Basic implementation of _ERRORMESSAGE.
|
||||
** The library `liolib' redefines _ERRORMESSAGE for better error information.
|
||||
*/
|
||||
static int luaB__ERRORMESSAGE (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TSTRING);
|
||||
lua_getglobal(L, LUA_ALERT);
|
||||
if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */
|
||||
lua_Debug ar;
|
||||
lua_pushstring(L, "error: ");
|
||||
lua_pushvalue(L, 1);
|
||||
if (lua_getstack(L, 1, &ar)) {
|
||||
lua_getinfo(L, "Sl", &ar);
|
||||
if (ar.source && ar.currentline > 0) {
|
||||
char buff[100];
|
||||
sprintf(buff, "\n <%.70s: line %d>", ar.short_src, ar.currentline);
|
||||
lua_pushstring(L, buff);
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
}
|
||||
lua_pushstring(L, "\n");
|
||||
lua_concat(L, 3);
|
||||
lua_rawcall(L, 1, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** If your system does not support `stdout', you can just remove this function.
|
||||
** If you need, you can define your own `print' function, following this
|
||||
** model but changing `fputs' to put the strings at a proper place
|
||||
** (a console window or a log file, for instance).
|
||||
*/
|
||||
static int luaB_print (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
int i;
|
||||
lua_getglobal(L, "tostring");
|
||||
for (i=1; i<=n; i++) {
|
||||
const char *s;
|
||||
lua_pushvalue(L, -1); /* function to be called */
|
||||
lua_pushvalue(L, i); /* value to print */
|
||||
lua_rawcall(L, 1, 1);
|
||||
s = lua_tostring(L, -1); /* get result */
|
||||
if (s == NULL)
|
||||
lua_error(L, "`tostring' must return a string to `print'");
|
||||
if (i>1) fputs("\t", stdout);
|
||||
fputs(s, stdout);
|
||||
lua_pop(L, 1); /* pop result */
|
||||
}
|
||||
fputs("\n", stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_tonumber (lua_State *L) {
|
||||
int base = luaL_opt_int(L, 2, 10);
|
||||
if (base == 10) { /* standard conversion */
|
||||
luaL_checkany(L, 1);
|
||||
if (lua_isnumber(L, 1)) {
|
||||
lua_pushnumber(L, lua_tonumber(L, 1));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const char *s1 = luaL_check_string(L, 1);
|
||||
char *s2;
|
||||
unsigned long n;
|
||||
luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range");
|
||||
n = strtoul(s1, &s2, base);
|
||||
if (s1 != s2) { /* at least one valid digit? */
|
||||
while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */
|
||||
if (*s2 == '\0') { /* no invalid trailing characters? */
|
||||
lua_pushnumber(L, n);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
lua_pushnil(L); /* else not a number */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_error (lua_State *L) {
|
||||
lua_error(L, luaL_opt_string(L, 1, NULL));
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
||||
static int luaB_setglobal (lua_State *L) {
|
||||
luaL_checkany(L, 2);
|
||||
lua_setglobal(L, luaL_check_string(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaB_getglobal (lua_State *L) {
|
||||
lua_getglobal(L, luaL_check_string(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_tag (lua_State *L) {
|
||||
luaL_checkany(L, 1);
|
||||
lua_pushnumber(L, lua_tag(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_settag (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_pushvalue(L, 1); /* push table */
|
||||
lua_settag(L, luaL_check_int(L, 2));
|
||||
return 1; /* return table */
|
||||
}
|
||||
|
||||
static int luaB_newtag (lua_State *L) {
|
||||
lua_pushnumber(L, lua_newtag(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_copytagmethods (lua_State *L) {
|
||||
lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1),
|
||||
luaL_check_int(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_globals (lua_State *L) {
|
||||
lua_getglobals(L); /* value to be returned */
|
||||
if (!lua_isnull(L, 1)) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_pushvalue(L, 1); /* new table of globals */
|
||||
lua_setglobals(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_rawget (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_checkany(L, 2);
|
||||
lua_rawget(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_rawset (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_checkany(L, 2);
|
||||
luaL_checkany(L, 3);
|
||||
lua_rawset(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_settagmethod (lua_State *L) {
|
||||
int tag = luaL_check_int(L, 1);
|
||||
const char *event = luaL_check_string(L, 2);
|
||||
luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
|
||||
"function or nil expected");
|
||||
if (strcmp(event, "gc") == 0)
|
||||
lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua");
|
||||
lua_gettagmethod(L, tag, event);
|
||||
lua_pushvalue(L, 3);
|
||||
lua_settagmethod(L, tag, event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_gettagmethod (lua_State *L) {
|
||||
int tag = luaL_check_int(L, 1);
|
||||
const char *event = luaL_check_string(L, 2);
|
||||
if (strcmp(event, "gc") == 0)
|
||||
lua_error(L, "deprecated use: cannot get the `gc' tag method from Lua");
|
||||
lua_gettagmethod(L, tag, event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_gcinfo (lua_State *L) {
|
||||
lua_pushnumber(L, lua_getgccount(L));
|
||||
lua_pushnumber(L, lua_getgcthreshold(L));
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_collectgarbage (lua_State *L) {
|
||||
lua_setgcthreshold(L, luaL_opt_int(L, 1, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_type (lua_State *L) {
|
||||
luaL_checkany(L, 1);
|
||||
lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_next (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
|
||||
if (lua_next(L, 1))
|
||||
return 2;
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int passresults (lua_State *L, int status, int oldtop) {
|
||||
static const char *const errornames[] =
|
||||
{"ok", "run-time error", "file error", "syntax error",
|
||||
"memory error", "error in error handling"};
|
||||
if (status == 0) {
|
||||
int nresults = lua_gettop(L) - oldtop;
|
||||
if (nresults > 0)
|
||||
return nresults; /* results are already on the stack */
|
||||
else {
|
||||
lua_pushuserdata(L, NULL); /* at least one result to signal no errors */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else { /* error */
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, errornames[status]); /* error code */
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int luaB_dostring (lua_State *L) {
|
||||
int oldtop = lua_gettop(L);
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
if (*s == '\33') /* binary files start with ESC... */
|
||||
lua_error(L, "`dostring' cannot run pre-compiled code");
|
||||
return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop);
|
||||
}
|
||||
|
||||
|
||||
static int luaB_dofile (lua_State *L) {
|
||||
int oldtop = lua_gettop(L);
|
||||
const char *fname = luaL_opt_string(L, 1, NULL);
|
||||
return passresults(L, lua_dofile(L, fname), oldtop);
|
||||
}
|
||||
|
||||
|
||||
static int luaB_call (lua_State *L) {
|
||||
int oldtop;
|
||||
const char *options = luaL_opt_string(L, 3, "");
|
||||
int err = 0; /* index of old error method */
|
||||
int i, status;
|
||||
int n;
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
n = lua_getn(L, 2);
|
||||
if (!lua_isnull(L, 4)) { /* set new error method */
|
||||
lua_getglobal(L, LUA_ERRORMESSAGE);
|
||||
err = lua_gettop(L); /* get index */
|
||||
lua_pushvalue(L, 4);
|
||||
lua_setglobal(L, LUA_ERRORMESSAGE);
|
||||
}
|
||||
oldtop = lua_gettop(L); /* top before function-call preparation */
|
||||
/* push function */
|
||||
lua_pushvalue(L, 1);
|
||||
luaL_checkstack(L, n, "too many arguments");
|
||||
for (i=0; i<n; i++) /* push arg[1...n] */
|
||||
lua_rawgeti(L, 2, i+1);
|
||||
status = lua_call(L, n, LUA_MULTRET);
|
||||
if (err != 0) { /* restore old error method */
|
||||
lua_pushvalue(L, err);
|
||||
lua_setglobal(L, LUA_ERRORMESSAGE);
|
||||
}
|
||||
if (status != 0) { /* error in call? */
|
||||
if (strchr(options, 'x'))
|
||||
lua_pushnil(L); /* return nil to signal the error */
|
||||
else
|
||||
lua_error(L, NULL); /* propagate error without additional messages */
|
||||
return 1;
|
||||
}
|
||||
if (strchr(options, 'p')) /* pack results? */
|
||||
lua_error(L, "deprecated option `p' in `call'");
|
||||
return lua_gettop(L) - oldtop; /* results are already on the stack */
|
||||
}
|
||||
|
||||
|
||||
static int luaB_tostring (lua_State *L) {
|
||||
char buff[64];
|
||||
switch (lua_type(L, 1)) {
|
||||
case LUA_TNUMBER:
|
||||
lua_pushstring(L, lua_tostring(L, 1));
|
||||
return 1;
|
||||
case LUA_TSTRING:
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
case LUA_TTABLE:
|
||||
sprintf(buff, "table: %p", lua_topointer(L, 1));
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
sprintf(buff, "function: %p", lua_topointer(L, 1));
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1));
|
||||
break;
|
||||
case LUA_TNIL:
|
||||
lua_pushstring(L, "nil");
|
||||
return 1;
|
||||
default:
|
||||
luaL_argerror(L, 1, "value expected");
|
||||
}
|
||||
lua_pushstring(L, buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_foreachi (lua_State *L) {
|
||||
int n, i;
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
n = lua_getn(L, 1);
|
||||
for (i=1; i<=n; i++) {
|
||||
lua_pushvalue(L, 2); /* function */
|
||||
lua_pushnumber(L, i); /* 1st argument */
|
||||
lua_rawgeti(L, 1, i); /* 2nd argument */
|
||||
lua_rawcall(L, 2, 1);
|
||||
if (!lua_isnil(L, -1))
|
||||
return 1;
|
||||
lua_pop(L, 1); /* remove nil result */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_foreach (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
lua_pushnil(L); /* first index */
|
||||
for (;;) {
|
||||
if (lua_next(L, 1) == 0)
|
||||
return 0;
|
||||
lua_pushvalue(L, 2); /* function */
|
||||
lua_pushvalue(L, -3); /* key */
|
||||
lua_pushvalue(L, -3); /* value */
|
||||
lua_rawcall(L, 2, 1);
|
||||
if (!lua_isnil(L, -1))
|
||||
return 1;
|
||||
lua_pop(L, 2); /* remove value and result */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int luaB_assert (lua_State *L) {
|
||||
luaL_checkany(L, 1);
|
||||
if (lua_isnil(L, 1))
|
||||
luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, ""));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_getn (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_pushnumber(L, lua_getn(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_tinsert (lua_State *L) {
|
||||
int v = lua_gettop(L); /* last argument: to be inserted */
|
||||
int n, pos;
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
n = lua_getn(L, 1);
|
||||
if (v == 2) /* called with only 2 arguments */
|
||||
pos = n+1;
|
||||
else
|
||||
pos = luaL_check_int(L, 2); /* 2nd argument is the position */
|
||||
lua_pushstring(L, "n");
|
||||
lua_pushnumber(L, n+1);
|
||||
lua_rawset(L, 1); /* t.n = n+1 */
|
||||
for (; n>=pos; n--) {
|
||||
lua_rawgeti(L, 1, n);
|
||||
lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
|
||||
}
|
||||
lua_pushvalue(L, v);
|
||||
lua_rawseti(L, 1, pos); /* t[pos] = v */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_tremove (lua_State *L) {
|
||||
int pos, n;
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
n = lua_getn(L, 1);
|
||||
pos = luaL_opt_int(L, 2, n);
|
||||
if (n <= 0) return 0; /* table is "empty" */
|
||||
lua_rawgeti(L, 1, pos); /* result = t[pos] */
|
||||
for ( ;pos<n; pos++) {
|
||||
lua_rawgeti(L, 1, pos+1);
|
||||
lua_rawseti(L, 1, pos); /* a[pos] = a[pos+1] */
|
||||
}
|
||||
lua_pushstring(L, "n");
|
||||
lua_pushnumber(L, n-1);
|
||||
lua_rawset(L, 1); /* t.n = n-1 */
|
||||
lua_pushnil(L);
|
||||
lua_rawseti(L, 1, n); /* t[n] = nil */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Quicksort
|
||||
** (based on `Algorithms in MODULA-3', Robert Sedgewick;
|
||||
** Addison-Wesley, 1993.)
|
||||
*/
|
||||
|
||||
|
||||
static void set2 (lua_State *L, int i, int j) {
|
||||
lua_rawseti(L, 1, i);
|
||||
lua_rawseti(L, 1, j);
|
||||
}
|
||||
|
||||
static int sort_comp (lua_State *L, int a, int b) {
|
||||
/* WARNING: the caller (auxsort) must ensure stack space */
|
||||
if (!lua_isnil(L, 2)) { /* function? */
|
||||
int res;
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushvalue(L, a-1); /* -1 to compensate function */
|
||||
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
|
||||
lua_rawcall(L, 2, 1);
|
||||
res = !lua_isnil(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return res;
|
||||
}
|
||||
else /* a < b? */
|
||||
return lua_lessthan(L, a, b);
|
||||
}
|
||||
|
||||
static void auxsort (lua_State *L, int l, int u) {
|
||||
while (l < u) { /* for tail recursion */
|
||||
int i, j;
|
||||
/* sort elements a[l], a[(l+u)/2] and a[u] */
|
||||
lua_rawgeti(L, 1, l);
|
||||
lua_rawgeti(L, 1, u);
|
||||
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
|
||||
set2(L, l, u); /* swap a[l] - a[u] */
|
||||
else
|
||||
lua_pop(L, 2);
|
||||
if (u-l == 1) break; /* only 2 elements */
|
||||
i = (l+u)/2;
|
||||
lua_rawgeti(L, 1, i);
|
||||
lua_rawgeti(L, 1, l);
|
||||
if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
|
||||
set2(L, i, l);
|
||||
else {
|
||||
lua_pop(L, 1); /* remove a[l] */
|
||||
lua_rawgeti(L, 1, u);
|
||||
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
|
||||
set2(L, i, u);
|
||||
else
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
if (u-l == 2) break; /* only 3 elements */
|
||||
lua_rawgeti(L, 1, i); /* Pivot */
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawgeti(L, 1, u-1);
|
||||
set2(L, i, u-1);
|
||||
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
|
||||
i = l; j = u-1;
|
||||
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
|
||||
/* repeat ++i until a[i] >= P */
|
||||
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
|
||||
if (i>u) lua_error(L, "invalid order function for sorting");
|
||||
lua_pop(L, 1); /* remove a[i] */
|
||||
}
|
||||
/* repeat --j until a[j] <= P */
|
||||
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
|
||||
if (j<l) lua_error(L, "invalid order function for sorting");
|
||||
lua_pop(L, 1); /* remove a[j] */
|
||||
}
|
||||
if (j<i) {
|
||||
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
|
||||
break;
|
||||
}
|
||||
set2(L, i, j);
|
||||
}
|
||||
lua_rawgeti(L, 1, u-1);
|
||||
lua_rawgeti(L, 1, i);
|
||||
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
|
||||
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
|
||||
/* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
|
||||
if (i-l < u-i) {
|
||||
j=l; i=i-1; l=i+2;
|
||||
}
|
||||
else {
|
||||
j=i+1; i=u; u=j-2;
|
||||
}
|
||||
auxsort(L, j, i); /* call recursively the smaller one */
|
||||
} /* repeat the routine for the larger one */
|
||||
}
|
||||
|
||||
static int luaB_sort (lua_State *L) {
|
||||
int n;
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
n = lua_getn(L, 1);
|
||||
if (!lua_isnull(L, 2)) /* is there a 2nd argument? */
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
lua_settop(L, 2); /* make sure there is two arguments */
|
||||
auxsort(L, 1, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Deprecated functions to manipulate global environment.
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
#define num_deprecated 4
|
||||
|
||||
static const struct luaL_reg deprecated_names [num_deprecated] = {
|
||||
{"foreachvar", luaB_foreach},
|
||||
{"nextvar", luaB_next},
|
||||
{"rawgetglobal", luaB_rawget},
|
||||
{"rawsetglobal", luaB_rawset}
|
||||
};
|
||||
|
||||
|
||||
#ifdef LUA_DEPRECATEDFUNCS
|
||||
|
||||
/*
|
||||
** call corresponding function inserting `globals' as first argument
|
||||
*/
|
||||
static int deprecated_func (lua_State *L) {
|
||||
lua_insert(L, 1); /* upvalue is the function to be called */
|
||||
lua_getglobals(L);
|
||||
lua_insert(L, 2); /* table of globals is 1o argument */
|
||||
lua_rawcall(L, lua_gettop(L)-1, LUA_MULTRET);
|
||||
return lua_gettop(L); /* return all results */
|
||||
}
|
||||
|
||||
|
||||
static void deprecated_funcs (lua_State *L) {
|
||||
int i;
|
||||
for (i=0; i<num_deprecated; i++) {
|
||||
lua_pushcfunction(L, deprecated_names[i].func);
|
||||
lua_pushcclosure(L, deprecated_func, 1);
|
||||
lua_setglobal(L, deprecated_names[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
** gives an explicit error in any attempt to call a deprecated function
|
||||
*/
|
||||
static int deprecated_func (lua_State *L) {
|
||||
luaL_verror(L, "function `%.20s' is deprecated", lua_tostring(L, -1));
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
||||
|
||||
static void deprecated_funcs (lua_State *L) {
|
||||
int i;
|
||||
for (i=0; i<num_deprecated; i++) {
|
||||
lua_pushstring(L, deprecated_names[i].name);
|
||||
lua_pushcclosure(L, deprecated_func, 1);
|
||||
lua_setglobal(L, deprecated_names[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
static const struct luaL_reg base_funcs[] = {
|
||||
{LUA_ALERT, luaB__ALERT},
|
||||
{LUA_ERRORMESSAGE, luaB__ERRORMESSAGE},
|
||||
{"call", luaB_call},
|
||||
{"collectgarbage", luaB_collectgarbage},
|
||||
{"copytagmethods", luaB_copytagmethods},
|
||||
{"dofile", luaB_dofile},
|
||||
{"dostring", luaB_dostring},
|
||||
{"error", luaB_error},
|
||||
{"foreach", luaB_foreach},
|
||||
{"foreachi", luaB_foreachi},
|
||||
{"gcinfo", luaB_gcinfo},
|
||||
{"getglobal", luaB_getglobal},
|
||||
{"gettagmethod", luaB_gettagmethod},
|
||||
{"globals", luaB_globals},
|
||||
{"newtag", luaB_newtag},
|
||||
{"next", luaB_next},
|
||||
{"print", luaB_print},
|
||||
{"rawget", luaB_rawget},
|
||||
{"rawset", luaB_rawset},
|
||||
{"rawgettable", luaB_rawget}, /* for compatibility */
|
||||
{"rawsettable", luaB_rawset}, /* for compatibility */
|
||||
{"setglobal", luaB_setglobal},
|
||||
{"settag", luaB_settag},
|
||||
{"settagmethod", luaB_settagmethod},
|
||||
{"tag", luaB_tag},
|
||||
{"tonumber", luaB_tonumber},
|
||||
{"tostring", luaB_tostring},
|
||||
{"type", luaB_type},
|
||||
{"assert", luaB_assert},
|
||||
{"getn", luaB_getn},
|
||||
{"sort", luaB_sort},
|
||||
{"tinsert", luaB_tinsert},
|
||||
{"tremove", luaB_tremove}
|
||||
};
|
||||
|
||||
|
||||
|
||||
LUALIB_API void lua_baselibopen (lua_State *L) {
|
||||
luaL_openl(L, base_funcs);
|
||||
lua_pushstring(L, LUA_VERSION);
|
||||
lua_setglobal(L, "_VERSION");
|
||||
deprecated_funcs(L);
|
||||
}
|
||||
|
@ -1,701 +0,0 @@
|
||||
/*
|
||||
** $Id: lcode.c,v 1.1 2003/01/24 16:26:00 jason379 Exp $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include "stdlib.h"
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lcode.h"
|
||||
#include "ldo.h"
|
||||
#include "llex.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lopcodes.h"
|
||||
#include "lparser.h"
|
||||
|
||||
|
||||
void luaK_error (LexState *ls, const char *msg) {
|
||||
luaX_error(ls, msg, ls->t.token);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Returns the the previous instruction, for optimizations.
|
||||
** If there is a jump target between this and the current instruction,
|
||||
** returns a dummy instruction to avoid wrong optimizations.
|
||||
*/
|
||||
static Instruction previous_instruction (FuncState *fs) {
|
||||
if (fs->pc > fs->lasttarget) /* no jumps to current position? */
|
||||
return fs->f->code[fs->pc-1]; /* returns previous instruction */
|
||||
else
|
||||
return CREATE_0(OP_END); /* no optimizations after an `END' */
|
||||
}
|
||||
|
||||
|
||||
int luaK_jump (FuncState *fs) {
|
||||
int j = luaK_code1(fs, OP_JMP, NO_JUMP);
|
||||
if (j == fs->lasttarget) { /* possible jumps to this jump? */
|
||||
luaK_concat(fs, &j, fs->jlt); /* keep them on hold */
|
||||
fs->jlt = NO_JUMP;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
static void luaK_fixjump (FuncState *fs, int pc, int dest) {
|
||||
Instruction *jmp = &fs->f->code[pc];
|
||||
if (dest == NO_JUMP)
|
||||
SETARG_S(*jmp, NO_JUMP); /* point to itself to represent end of list */
|
||||
else { /* jump is relative to position following jump instruction */
|
||||
int offset = dest-(pc+1);
|
||||
if (abs(offset) > MAXARG_S)
|
||||
luaK_error(fs->ls, "control structure too long");
|
||||
SETARG_S(*jmp, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int luaK_getjump (FuncState *fs, int pc) {
|
||||
int offset = GETARG_S(fs->f->code[pc]);
|
||||
if (offset == NO_JUMP) /* point to itself represents end of list */
|
||||
return NO_JUMP; /* end of list */
|
||||
else
|
||||
return (pc+1)+offset; /* turn offset into absolute position */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** returns current `pc' and marks it as a jump target (to avoid wrong
|
||||
** optimizations with consecutive instructions not in the same basic block).
|
||||
** discharge list of jumps to last target.
|
||||
*/
|
||||
int luaK_getlabel (FuncState *fs) {
|
||||
if (fs->pc != fs->lasttarget) {
|
||||
int lasttarget = fs->lasttarget;
|
||||
fs->lasttarget = fs->pc;
|
||||
luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */
|
||||
fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */
|
||||
}
|
||||
return fs->pc;
|
||||
}
|
||||
|
||||
|
||||
void luaK_deltastack (FuncState *fs, int delta) {
|
||||
fs->stacklevel += delta;
|
||||
if (fs->stacklevel > fs->f->maxstacksize) {
|
||||
if (fs->stacklevel > MAXSTACK)
|
||||
luaK_error(fs->ls, "function or expression too complex");
|
||||
fs->f->maxstacksize = fs->stacklevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaK_kstr (LexState *ls, int c) {
|
||||
luaK_code1(ls->fs, OP_PUSHSTRING, c);
|
||||
}
|
||||
|
||||
|
||||
static int number_constant (FuncState *fs, Number r) {
|
||||
/* check whether `r' has appeared within the last LOOKBACKNUMS entries */
|
||||
Proto *f = fs->f;
|
||||
int c = f->nknum;
|
||||
int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
|
||||
while (--c >= lim)
|
||||
if (f->knum[c] == r) return c;
|
||||
/* not found; create a new entry */
|
||||
luaM_growvector(fs->L, f->knum, f->nknum, 1, Number,
|
||||
"constant table overflow", MAXARG_U);
|
||||
c = f->nknum++;
|
||||
f->knum[c] = r;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void luaK_number (FuncState *fs, Number f) {
|
||||
if (f <= (Number)MAXARG_S && (Number)(int)f == f)
|
||||
luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */
|
||||
else
|
||||
luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f));
|
||||
}
|
||||
|
||||
|
||||
void luaK_adjuststack (FuncState *fs, int n) {
|
||||
if (n > 0)
|
||||
luaK_code1(fs, OP_POP, n);
|
||||
else
|
||||
luaK_code1(fs, OP_PUSHNIL, -n);
|
||||
}
|
||||
|
||||
|
||||
int luaK_lastisopen (FuncState *fs) {
|
||||
/* check whether last instruction is an open function call */
|
||||
Instruction i = previous_instruction(fs);
|
||||
if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET)
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
void luaK_setcallreturns (FuncState *fs, int nresults) {
|
||||
if (luaK_lastisopen(fs)) { /* expression is an open function call? */
|
||||
SETARG_B(fs->f->code[fs->pc-1], nresults); /* set number of results */
|
||||
luaK_deltastack(fs, nresults); /* push results */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int discharge (FuncState *fs, expdesc *var) {
|
||||
switch (var->k) {
|
||||
case VLOCAL:
|
||||
luaK_code1(fs, OP_GETLOCAL, var->u.index);
|
||||
break;
|
||||
case VGLOBAL:
|
||||
luaK_code1(fs, OP_GETGLOBAL, var->u.index);
|
||||
break;
|
||||
case VINDEXED:
|
||||
luaK_code0(fs, OP_GETTABLE);
|
||||
break;
|
||||
case VEXP:
|
||||
return 0; /* nothing to do */
|
||||
}
|
||||
var->k = VEXP;
|
||||
var->u.l.t = var->u.l.f = NO_JUMP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void discharge1 (FuncState *fs, expdesc *var) {
|
||||
discharge(fs, var);
|
||||
/* if it has jumps then it is already discharged */
|
||||
if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP)
|
||||
luaK_setcallreturns(fs, 1); /* call must return 1 value */
|
||||
}
|
||||
|
||||
|
||||
void luaK_storevar (LexState *ls, const expdesc *var) {
|
||||
FuncState *fs = ls->fs;
|
||||
switch (var->k) {
|
||||
case VLOCAL:
|
||||
luaK_code1(fs, OP_SETLOCAL, var->u.index);
|
||||
break;
|
||||
case VGLOBAL:
|
||||
luaK_code1(fs, OP_SETGLOBAL, var->u.index);
|
||||
break;
|
||||
case VINDEXED: /* table is at top-3; pop 3 elements after operation */
|
||||
luaK_code2(fs, OP_SETTABLE, 3, 3);
|
||||
break;
|
||||
default:
|
||||
LUA_INTERNALERROR("invalid var kind to store");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static OpCode invertjump (OpCode op) {
|
||||
switch (op) {
|
||||
case OP_JMPNE: return OP_JMPEQ;
|
||||
case OP_JMPEQ: return OP_JMPNE;
|
||||
case OP_JMPLT: return OP_JMPGE;
|
||||
case OP_JMPLE: return OP_JMPGT;
|
||||
case OP_JMPGT: return OP_JMPLE;
|
||||
case OP_JMPGE: return OP_JMPLT;
|
||||
case OP_JMPT: case OP_JMPONT: return OP_JMPF;
|
||||
case OP_JMPF: case OP_JMPONF: return OP_JMPT;
|
||||
default:
|
||||
LUA_INTERNALERROR("invalid jump instruction");
|
||||
return OP_END; /* to avoid warnings */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void luaK_patchlistaux (FuncState *fs, int list, int target,
|
||||
OpCode special, int special_target) {
|
||||
Instruction *code = fs->f->code;
|
||||
while (list != NO_JUMP) {
|
||||
int next = luaK_getjump(fs, list);
|
||||
Instruction *i = &code[list];
|
||||
OpCode op = GET_OPCODE(*i);
|
||||
if (op == special) /* this `op' already has a value */
|
||||
luaK_fixjump(fs, list, special_target);
|
||||
else {
|
||||
luaK_fixjump(fs, list, target); /* do the patch */
|
||||
if (op == OP_JMPONT) /* remove eventual values */
|
||||
SET_OPCODE(*i, OP_JMPT);
|
||||
else if (op == OP_JMPONF)
|
||||
SET_OPCODE(*i, OP_JMPF);
|
||||
}
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaK_patchlist (FuncState *fs, int list, int target) {
|
||||
if (target == fs->lasttarget) /* same target that list `jlt'? */
|
||||
luaK_concat(fs, &fs->jlt, list); /* delay fixing */
|
||||
else
|
||||
luaK_patchlistaux(fs, list, target, OP_END, 0);
|
||||
}
|
||||
|
||||
|
||||
static int need_value (FuncState *fs, int list, OpCode hasvalue) {
|
||||
/* check whether list has a jump without a value */
|
||||
for (; list != NO_JUMP; list = luaK_getjump(fs, list))
|
||||
if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1;
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
|
||||
void luaK_concat (FuncState *fs, int *l1, int l2) {
|
||||
if (*l1 == NO_JUMP)
|
||||
*l1 = l2;
|
||||
else {
|
||||
int list = *l1;
|
||||
for (;;) { /* traverse `l1' */
|
||||
int next = luaK_getjump(fs, list);
|
||||
if (next == NO_JUMP) { /* end of list? */
|
||||
luaK_fixjump(fs, list, l2);
|
||||
return;
|
||||
}
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
|
||||
int prevpos; /* position of last instruction */
|
||||
Instruction *previous;
|
||||
int *golist, *exitlist;
|
||||
if (!invert) {
|
||||
golist = &v->u.l.f; /* go if false */
|
||||
exitlist = &v->u.l.t; /* exit if true */
|
||||
}
|
||||
else {
|
||||
golist = &v->u.l.t; /* go if true */
|
||||
exitlist = &v->u.l.f; /* exit if false */
|
||||
}
|
||||
discharge1(fs, v);
|
||||
prevpos = fs->pc-1;
|
||||
previous = &fs->f->code[prevpos];
|
||||
LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here");
|
||||
if (!ISJUMP(GET_OPCODE(*previous)))
|
||||
prevpos = luaK_code1(fs, jump, NO_JUMP);
|
||||
else { /* last instruction is already a jump */
|
||||
if (invert)
|
||||
SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
|
||||
}
|
||||
luaK_concat(fs, exitlist, prevpos); /* insert last jump in `exitlist' */
|
||||
luaK_patchlist(fs, *golist, luaK_getlabel(fs));
|
||||
*golist = NO_JUMP;
|
||||
}
|
||||
|
||||
|
||||
void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) {
|
||||
luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF);
|
||||
}
|
||||
|
||||
|
||||
static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
|
||||
luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT);
|
||||
}
|
||||
|
||||
|
||||
static int code_label (FuncState *fs, OpCode op, int arg) {
|
||||
luaK_getlabel(fs); /* those instructions may be jump targets */
|
||||
return luaK_code1(fs, op, arg);
|
||||
}
|
||||
|
||||
|
||||
void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
|
||||
FuncState *fs = ls->fs;
|
||||
if (!discharge(fs, v)) { /* `v' is an expression? */
|
||||
OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);
|
||||
if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {
|
||||
/* expression has no jumps */
|
||||
if (onlyone)
|
||||
luaK_setcallreturns(fs, 1); /* call must return 1 value */
|
||||
}
|
||||
else { /* expression has jumps */
|
||||
int final; /* position after whole expression */
|
||||
int j = NO_JUMP; /* eventual jump over values */
|
||||
int p_nil = NO_JUMP; /* position of an eventual PUSHNIL */
|
||||
int p_1 = NO_JUMP; /* position of an eventual PUSHINT */
|
||||
if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF)
|
||||
|| need_value(fs, v->u.l.t, OP_JMPONT)) {
|
||||
/* expression needs values */
|
||||
if (ISJUMP(previous))
|
||||
luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */
|
||||
else {
|
||||
j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */
|
||||
/* correct stack for compiler and symbolic execution */
|
||||
luaK_adjuststack(fs, 1);
|
||||
}
|
||||
p_nil = code_label(fs, OP_PUSHNILJMP, 0);
|
||||
p_1 = code_label(fs, OP_PUSHINT, 1);
|
||||
luaK_patchlist(fs, j, luaK_getlabel(fs));
|
||||
}
|
||||
final = luaK_getlabel(fs);
|
||||
luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final);
|
||||
luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final);
|
||||
v->u.l.f = v->u.l.t = NO_JUMP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaK_prefix (LexState *ls, UnOpr op, expdesc *v) {
|
||||
FuncState *fs = ls->fs;
|
||||
if (op == OPR_MINUS) {
|
||||
luaK_tostack(ls, v, 1);
|
||||
luaK_code0(fs, OP_MINUS);
|
||||
}
|
||||
else { /* op == NOT */
|
||||
Instruction *previous;
|
||||
discharge1(fs, v);
|
||||
previous = &fs->f->code[fs->pc-1];
|
||||
if (ISJUMP(GET_OPCODE(*previous)))
|
||||
SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
|
||||
else
|
||||
luaK_code0(fs, OP_NOT);
|
||||
/* interchange true and false lists */
|
||||
{ int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaK_infix (LexState *ls, BinOpr op, expdesc *v) {
|
||||
FuncState *fs = ls->fs;
|
||||
switch (op) {
|
||||
case OPR_AND:
|
||||
luaK_goiftrue(fs, v, 1);
|
||||
break;
|
||||
case OPR_OR:
|
||||
luaK_goiffalse(fs, v, 1);
|
||||
break;
|
||||
default:
|
||||
luaK_tostack(ls, v, 1); /* all other binary operators need a value */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const struct {
|
||||
OpCode opcode; /* opcode for each binary operator */
|
||||
int arg; /* default argument for the opcode */
|
||||
} codes[] = { /* ORDER OPR */
|
||||
{OP_ADD, 0}, {OP_SUB, 0}, {OP_MULT, 0}, {OP_DIV, 0},
|
||||
{OP_POW, 0}, {OP_CONCAT, 2},
|
||||
{OP_JMPNE, NO_JUMP}, {OP_JMPEQ, NO_JUMP},
|
||||
{OP_JMPLT, NO_JUMP}, {OP_JMPLE, NO_JUMP},
|
||||
{OP_JMPGT, NO_JUMP}, {OP_JMPGE, NO_JUMP}
|
||||
};
|
||||
|
||||
|
||||
void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) {
|
||||
FuncState *fs = ls->fs;
|
||||
switch (op) {
|
||||
case OPR_AND: {
|
||||
LUA_ASSERT(v1->u.l.t == NO_JUMP, "list must be closed");
|
||||
discharge1(fs, v2);
|
||||
v1->u.l.t = v2->u.l.t;
|
||||
luaK_concat(fs, &v1->u.l.f, v2->u.l.f);
|
||||
break;
|
||||
}
|
||||
case OPR_OR: {
|
||||
LUA_ASSERT(v1->u.l.f == NO_JUMP, "list must be closed");
|
||||
discharge1(fs, v2);
|
||||
v1->u.l.f = v2->u.l.f;
|
||||
luaK_concat(fs, &v1->u.l.t, v2->u.l.t);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
luaK_tostack(ls, v2, 1); /* `v2' must be a value */
|
||||
luaK_code1(fs, codes[op].opcode, codes[op].arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void codelineinfo (FuncState *fs) {
|
||||
Proto *f = fs->f;
|
||||
LexState *ls = fs->ls;
|
||||
if (ls->lastline > fs->lastline) {
|
||||
luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int,
|
||||
"line info overflow", MAX_INT);
|
||||
if (ls->lastline > fs->lastline+1)
|
||||
f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1));
|
||||
f->lineinfo[f->nlineinfo++] = fs->pc;
|
||||
fs->lastline = ls->lastline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaK_code0 (FuncState *fs, OpCode o) {
|
||||
return luaK_code2(fs, o, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
|
||||
return luaK_code2(fs, o, arg1, 0);
|
||||
}
|
||||
|
||||
|
||||
int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
|
||||
Instruction i = previous_instruction(fs);
|
||||
int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop;
|
||||
int optm = 0; /* 1 when there is an optimization */
|
||||
switch (o) {
|
||||
case OP_CLOSURE: {
|
||||
delta = -arg2+1;
|
||||
break;
|
||||
}
|
||||
case OP_SETTABLE: {
|
||||
delta = -arg2;
|
||||
break;
|
||||
}
|
||||
case OP_SETLIST: {
|
||||
if (arg2 == 0) return NO_JUMP; /* nothing to do */
|
||||
delta = -arg2;
|
||||
break;
|
||||
}
|
||||
case OP_SETMAP: {
|
||||
if (arg1 == 0) return NO_JUMP; /* nothing to do */
|
||||
delta = -2*arg1;
|
||||
break;
|
||||
}
|
||||
case OP_RETURN: {
|
||||
if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
|
||||
SET_OPCODE(i, OP_TAILCALL);
|
||||
SETARG_B(i, arg1);
|
||||
optm = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_PUSHNIL: {
|
||||
if (arg1 == 0) return NO_JUMP; /* nothing to do */
|
||||
delta = arg1;
|
||||
switch(GET_OPCODE(i)) {
|
||||
case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_POP: {
|
||||
if (arg1 == 0) return NO_JUMP; /* nothing to do */
|
||||
delta = -arg1;
|
||||
switch(GET_OPCODE(i)) {
|
||||
case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_GETTABLE: {
|
||||
switch(GET_OPCODE(i)) {
|
||||
case OP_PUSHSTRING: /* `t.x' */
|
||||
SET_OPCODE(i, OP_GETDOTTED);
|
||||
optm = 1;
|
||||
break;
|
||||
case OP_GETLOCAL: /* `t[i]' */
|
||||
SET_OPCODE(i, OP_GETINDEXED);
|
||||
optm = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_ADD: {
|
||||
switch(GET_OPCODE(i)) {
|
||||
case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break; /* `a+k' */
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_SUB: {
|
||||
switch(GET_OPCODE(i)) {
|
||||
case OP_PUSHINT: /* `a-k' */
|
||||
i = CREATE_S(OP_ADDI, -GETARG_S(i));
|
||||
optm = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_CONCAT: {
|
||||
delta = -arg1+1;
|
||||
switch(GET_OPCODE(i)) {
|
||||
case OP_CONCAT: /* `a..b..c' */
|
||||
SETARG_U(i, GETARG_U(i)+1);
|
||||
optm = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_MINUS: {
|
||||
switch(GET_OPCODE(i)) {
|
||||
case OP_PUSHINT: /* `-k' */
|
||||
SETARG_S(i, -GETARG_S(i));
|
||||
optm = 1;
|
||||
break;
|
||||
case OP_PUSHNUM: /* `-k' */
|
||||
SET_OPCODE(i, OP_PUSHNEGNUM);
|
||||
optm = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_JMPNE: {
|
||||
if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a~=nil' */
|
||||
i = CREATE_S(OP_JMPT, NO_JUMP);
|
||||
optm = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_JMPEQ: {
|
||||
if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */
|
||||
i = CREATE_0(OP_NOT);
|
||||
delta = -1; /* just undo effect of previous PUSHNIL */
|
||||
optm = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_JMPT:
|
||||
case OP_JMPONT: {
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_NOT: {
|
||||
i = CREATE_S(OP_JMPF, NO_JUMP);
|
||||
optm = 1;
|
||||
break;
|
||||
}
|
||||
case OP_PUSHINT: {
|
||||
if (o == OP_JMPT) { /* JMPONT must keep original integer value */
|
||||
i = CREATE_S(OP_JMP, NO_JUMP);
|
||||
optm = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_PUSHNIL: {
|
||||
if (GETARG_U(i) == 1) {
|
||||
fs->pc--; /* erase previous instruction */
|
||||
luaK_deltastack(fs, -1); /* correct stack */
|
||||
return NO_JUMP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_JMPF:
|
||||
case OP_JMPONF: {
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_NOT: {
|
||||
i = CREATE_S(OP_JMPT, NO_JUMP);
|
||||
optm = 1;
|
||||
break;
|
||||
}
|
||||
case OP_PUSHINT: { /* `while 1 do ...' */
|
||||
fs->pc--; /* erase previous instruction */
|
||||
luaK_deltastack(fs, -1); /* correct stack */
|
||||
return NO_JUMP;
|
||||
}
|
||||
case OP_PUSHNIL: { /* `repeat ... until nil' */
|
||||
if (GETARG_U(i) == 1) {
|
||||
i = CREATE_S(OP_JMP, NO_JUMP);
|
||||
optm = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_GETDOTTED:
|
||||
case OP_GETINDEXED:
|
||||
case OP_TAILCALL:
|
||||
case OP_ADDI: {
|
||||
LUA_INTERNALERROR("instruction used only for optimizations");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LUA_ASSERT(delta != VD, "invalid delta");
|
||||
break;
|
||||
}
|
||||
}
|
||||
luaK_deltastack(fs, delta);
|
||||
if (optm) { /* optimize: put instruction in place of last one */
|
||||
fs->f->code[fs->pc-1] = i; /* change previous instruction */
|
||||
return fs->pc-1; /* do not generate new instruction */
|
||||
}
|
||||
/* else build new instruction */
|
||||
switch ((enum Mode)luaK_opproperties[o].mode) {
|
||||
case iO: i = CREATE_0(o); break;
|
||||
case iU: i = CREATE_U(o, arg1); break;
|
||||
case iS: i = CREATE_S(o, arg1); break;
|
||||
case iAB: i = CREATE_AB(o, arg1, arg2); break;
|
||||
}
|
||||
codelineinfo(fs);
|
||||
/* put new instruction in code array */
|
||||
luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
|
||||
"code size overflow", MAX_INT);
|
||||
fs->f->code[fs->pc] = i;
|
||||
return fs->pc++;
|
||||
}
|
||||
|
||||
|
||||
const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
|
||||
{iO, 0, 0}, /* OP_END */
|
||||
{iU, 0, 0}, /* OP_RETURN */
|
||||
{iAB, 0, 0}, /* OP_CALL */
|
||||
{iAB, 0, 0}, /* OP_TAILCALL */
|
||||
{iU, VD, 0}, /* OP_PUSHNIL */
|
||||
{iU, VD, 0}, /* OP_POP */
|
||||
{iS, 1, 0}, /* OP_PUSHINT */
|
||||
{iU, 1, 0}, /* OP_PUSHSTRING */
|
||||
{iU, 1, 0}, /* OP_PUSHNUM */
|
||||
{iU, 1, 0}, /* OP_PUSHNEGNUM */
|
||||
{iU, 1, 0}, /* OP_PUSHUPVALUE */
|
||||
{iU, 1, 0}, /* OP_GETLOCAL */
|
||||
{iU, 1, 0}, /* OP_GETGLOBAL */
|
||||
{iO, 1, 2}, /* OP_GETTABLE */
|
||||
{iU, 1, 1}, /* OP_GETDOTTED */
|
||||
{iU, 1, 1}, /* OP_GETINDEXED */
|
||||
{iU, 2, 1}, /* OP_PUSHSELF */
|
||||
{iU, 1, 0}, /* OP_CREATETABLE */
|
||||
{iU, 0, 1}, /* OP_SETLOCAL */
|
||||
{iU, 0, 1}, /* OP_SETGLOBAL */
|
||||
{iAB, VD, 0}, /* OP_SETTABLE */
|
||||
{iAB, VD, 0}, /* OP_SETLIST */
|
||||
{iU, VD, 0}, /* OP_SETMAP */
|
||||
{iO, 1, 2}, /* OP_ADD */
|
||||
{iS, 1, 1}, /* OP_ADDI */
|
||||
{iO, 1, 2}, /* OP_SUB */
|
||||
{iO, 1, 2}, /* OP_MULT */
|
||||
{iO, 1, 2}, /* OP_DIV */
|
||||
{iO, 1, 2}, /* OP_POW */
|
||||
{iU, VD, 0}, /* OP_CONCAT */
|
||||
{iO, 1, 1}, /* OP_MINUS */
|
||||
{iO, 1, 1}, /* OP_NOT */
|
||||
{iS, 0, 2}, /* OP_JMPNE */
|
||||
{iS, 0, 2}, /* OP_JMPEQ */
|
||||
{iS, 0, 2}, /* OP_JMPLT */
|
||||
{iS, 0, 2}, /* OP_JMPLE */
|
||||
{iS, 0, 2}, /* OP_JMPGT */
|
||||
{iS, 0, 2}, /* OP_JMPGE */
|
||||
{iS, 0, 1}, /* OP_JMPT */
|
||||
{iS, 0, 1}, /* OP_JMPF */
|
||||
{iS, 0, 1}, /* OP_JMPONT */
|
||||
{iS, 0, 1}, /* OP_JMPONF */
|
||||
{iS, 0, 0}, /* OP_JMP */
|
||||
{iO, 0, 0}, /* OP_PUSHNILJMP */
|
||||
{iS, 0, 0}, /* OP_FORPREP */
|
||||
{iS, 0, 3}, /* OP_FORLOOP */
|
||||
{iS, 2, 0}, /* OP_LFORPREP */
|
||||
{iS, 0, 3}, /* OP_LFORLOOP */
|
||||
{iAB, VD, 0} /* OP_CLOSURE */
|
||||
};
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
** $Id: lcode.h,v 1.1 2003/01/24 16:26:01 jason379 Exp $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lcode_h
|
||||
#define lcode_h
|
||||
|
||||
#include "llex.h"
|
||||
#include "lobject.h"
|
||||
#include "lopcodes.h"
|
||||
#include "lparser.h"
|
||||
|
||||
|
||||
/*
|
||||
** Marks the end of a patch list. It is an invalid value both as an absolute
|
||||
** address, and as a list link (would link an element to itself).
|
||||
*/
|
||||
#define NO_JUMP (-1)
|
||||
|
||||
|
||||
/*
|
||||
** grep "ORDER OPR" if you change these enums
|
||||
*/
|
||||
typedef enum BinOpr {
|
||||
OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW,
|
||||
OPR_CONCAT,
|
||||
OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE,
|
||||
OPR_AND, OPR_OR,
|
||||
OPR_NOBINOPR
|
||||
} BinOpr;
|
||||
|
||||
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
|
||||
|
||||
|
||||
enum Mode {iO, iU, iS, iAB}; /* instruction format */
|
||||
|
||||
#define VD 100 /* flag for variable delta */
|
||||
|
||||
extern const struct OpProperties {
|
||||
char mode;
|
||||
unsigned char push;
|
||||
unsigned char pop;
|
||||
} luaK_opproperties[];
|
||||
|
||||
|
||||
void luaK_error (LexState *ls, const char *msg);
|
||||
int luaK_code0 (FuncState *fs, OpCode o);
|
||||
int luaK_code1 (FuncState *fs, OpCode o, int arg1);
|
||||
int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
|
||||
int luaK_jump (FuncState *fs);
|
||||
void luaK_patchlist (FuncState *fs, int list, int target);
|
||||
void luaK_concat (FuncState *fs, int *l1, int l2);
|
||||
void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
|
||||
int luaK_getlabel (FuncState *fs);
|
||||
void luaK_deltastack (FuncState *fs, int delta);
|
||||
void luaK_kstr (LexState *ls, int c);
|
||||
void luaK_number (FuncState *fs, Number f);
|
||||
void luaK_adjuststack (FuncState *fs, int n);
|
||||
int luaK_lastisopen (FuncState *fs);
|
||||
void luaK_setcallreturns (FuncState *fs, int nresults);
|
||||
void luaK_tostack (LexState *ls, expdesc *v, int onlyone);
|
||||
void luaK_storevar (LexState *ls, const expdesc *var);
|
||||
void luaK_prefix (LexState *ls, UnOpr op, expdesc *v);
|
||||
void luaK_infix (LexState *ls, BinOpr op, expdesc *v);
|
||||
void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2);
|
||||
|
||||
|
||||
#endif
|
@ -1,466 +0,0 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 1.1 2003/01/24 16:26:01 jason379 Exp $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lapi.h"
|
||||
#include "lcode.h"
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lobject.h"
|
||||
#include "lopcodes.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
#include "luadebug.h"
|
||||
|
||||
|
||||
|
||||
static const char *getfuncname (lua_State *L, StkId f, const char **name);
|
||||
|
||||
|
||||
static void setnormalized (TObject *d, const TObject *s) {
|
||||
if (ttype(s) == LUA_TMARK) {
|
||||
clvalue(d) = infovalue(s)->func;
|
||||
ttype(d) = LUA_TFUNCTION;
|
||||
}
|
||||
else *d = *s;
|
||||
}
|
||||
|
||||
|
||||
static int isLmark (StkId o) {
|
||||
return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC);
|
||||
}
|
||||
|
||||
|
||||
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
|
||||
lua_Hook oldhook = L->callhook;
|
||||
L->callhook = func;
|
||||
return oldhook;
|
||||
}
|
||||
|
||||
|
||||
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
|
||||
lua_Hook oldhook = L->linehook;
|
||||
L->linehook = func;
|
||||
return oldhook;
|
||||
}
|
||||
|
||||
|
||||
static StkId aux_stackedfunction (lua_State *L, int level, StkId top) {
|
||||
int i;
|
||||
for (i = (top-1) - L->stack; i>=0; i--) {
|
||||
if (is_T_MARK(L->stack[i].ttype)) {
|
||||
if (level == 0)
|
||||
return L->stack+i;
|
||||
level--;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
|
||||
StkId f = aux_stackedfunction(L, level, L->top);
|
||||
if (f == NULL) return 0; /* there is no such level */
|
||||
else {
|
||||
ar->_func = f;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int nups (StkId f) {
|
||||
switch (ttype(f)) {
|
||||
case LUA_TFUNCTION:
|
||||
return clvalue(f)->nupvalues;
|
||||
case LUA_TMARK:
|
||||
return infovalue(f)->func->nupvalues;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
|
||||
int refi;
|
||||
if (lineinfo == NULL || pc == -1)
|
||||
return -1; /* no line info or function is not active */
|
||||
refi = prefi ? *prefi : 0;
|
||||
if (lineinfo[refi] < 0)
|
||||
refline += -lineinfo[refi++];
|
||||
LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
|
||||
while (lineinfo[refi] > pc) {
|
||||
refline--;
|
||||
refi--;
|
||||
if (lineinfo[refi] < 0)
|
||||
refline -= -lineinfo[refi--];
|
||||
LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
|
||||
}
|
||||
for (;;) {
|
||||
int nextline = refline + 1;
|
||||
int nextref = refi + 1;
|
||||
if (lineinfo[nextref] < 0)
|
||||
nextline += -lineinfo[nextref++];
|
||||
LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info");
|
||||
if (lineinfo[nextref] > pc)
|
||||
break;
|
||||
refline = nextline;
|
||||
refi = nextref;
|
||||
}
|
||||
if (prefi) *prefi = refi;
|
||||
return refline;
|
||||
}
|
||||
|
||||
|
||||
static int currentpc (StkId f) {
|
||||
CallInfo *ci = infovalue(f);
|
||||
LUA_ASSERT(isLmark(f), "function has no pc");
|
||||
if (ci->pc)
|
||||
return (*ci->pc - ci->func->f.l->code) - 1;
|
||||
else
|
||||
return -1; /* function is not active */
|
||||
}
|
||||
|
||||
|
||||
static int currentline (StkId f) {
|
||||
if (!isLmark(f))
|
||||
return -1; /* only active lua functions have current-line information */
|
||||
else {
|
||||
CallInfo *ci = infovalue(f);
|
||||
int *lineinfo = ci->func->f.l->lineinfo;
|
||||
return luaG_getline(lineinfo, currentpc(f), 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static Proto *getluaproto (StkId f) {
|
||||
return (isLmark(f) ? infovalue(f)->func->f.l : NULL);
|
||||
}
|
||||
|
||||
|
||||
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||
const char *name;
|
||||
StkId f = ar->_func;
|
||||
Proto *fp = getluaproto(f);
|
||||
if (!fp) return NULL; /* `f' is not a Lua function? */
|
||||
name = luaF_getlocalname(fp, n, currentpc(f));
|
||||
if (!name) return NULL;
|
||||
luaA_pushobject(L, (f+1)+(n-1)); /* push value */
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||
const char *name;
|
||||
StkId f = ar->_func;
|
||||
Proto *fp = getluaproto(f);
|
||||
L->top--; /* pop new value */
|
||||
if (!fp) return NULL; /* `f' is not a Lua function? */
|
||||
name = luaF_getlocalname(fp, n, currentpc(f));
|
||||
if (!name || name[0] == '(') return NULL; /* `(' starts private locals */
|
||||
*((f+1)+(n-1)) = *L->top;
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
static void infoLproto (lua_Debug *ar, Proto *f) {
|
||||
ar->source = f->source->str;
|
||||
ar->linedefined = f->lineDefined;
|
||||
ar->what = "Lua";
|
||||
}
|
||||
|
||||
|
||||
static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
|
||||
Closure *cl = NULL;
|
||||
switch (ttype(func)) {
|
||||
case LUA_TFUNCTION:
|
||||
cl = clvalue(func);
|
||||
break;
|
||||
case LUA_TMARK:
|
||||
cl = infovalue(func)->func;
|
||||
break;
|
||||
default:
|
||||
lua_error(L, "value for `lua_getinfo' is not a function");
|
||||
}
|
||||
if (cl->isC) {
|
||||
ar->source = "=C";
|
||||
ar->linedefined = -1;
|
||||
ar->what = "C";
|
||||
}
|
||||
else
|
||||
infoLproto(ar, cl->f.l);
|
||||
luaO_chunkid(ar->short_src, ar->source, sizeof(ar->short_src));
|
||||
if (ar->linedefined == 0)
|
||||
ar->what = "main";
|
||||
}
|
||||
|
||||
|
||||
static const char *travtagmethods (lua_State *L, const TObject *o) {
|
||||
if (ttype(o) == LUA_TFUNCTION) {
|
||||
int e;
|
||||
for (e=0; e<TM_N; e++) {
|
||||
int t;
|
||||
for (t=0; t<=L->last_tag; t++)
|
||||
if (clvalue(o) == luaT_gettm(L, t, e))
|
||||
return luaT_eventname[e];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static const char *travglobals (lua_State *L, const TObject *o) {
|
||||
Hash *g = L->gt;
|
||||
int i;
|
||||
for (i=0; i<g->size; i++) {
|
||||
if (luaO_equalObj(o, val(node(g, i))) &&
|
||||
ttype(key(node(g, i))) == LUA_TSTRING)
|
||||
return tsvalue(key(node(g, i)))->str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void getname (lua_State *L, StkId f, lua_Debug *ar) {
|
||||
TObject o;
|
||||
setnormalized(&o, f);
|
||||
/* try to find a name for given function */
|
||||
if ((ar->name = travglobals(L, &o)) != NULL)
|
||||
ar->namewhat = "global";
|
||||
/* not found: try tag methods */
|
||||
else if ((ar->name = travtagmethods(L, &o)) != NULL)
|
||||
ar->namewhat = "tag-method";
|
||||
else ar->namewhat = ""; /* not found at all */
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||
StkId func;
|
||||
int isactive = (*what != '>');
|
||||
if (isactive)
|
||||
func = ar->_func;
|
||||
else {
|
||||
what++; /* skip the '>' */
|
||||
func = L->top - 1;
|
||||
}
|
||||
for (; *what; what++) {
|
||||
switch (*what) {
|
||||
case 'S': {
|
||||
funcinfo(L, ar, func);
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
ar->currentline = currentline(func);
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
ar->nups = nups(func);
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL;
|
||||
if (ar->namewhat == NULL)
|
||||
getname(L, func, ar);
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
setnormalized(L->top, func);
|
||||
incr_top; /* push function */
|
||||
break;
|
||||
}
|
||||
default: return 0; /* invalid option */
|
||||
}
|
||||
}
|
||||
if (!isactive) L->top--; /* pop function */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Symbolic Execution
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
static int pushpc (int *stack, int pc, int top, int n) {
|
||||
while (n--)
|
||||
stack[top++] = pc-1;
|
||||
return top;
|
||||
}
|
||||
|
||||
|
||||
static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
|
||||
int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */
|
||||
const Instruction *code = pt->code;
|
||||
int top = pt->numparams;
|
||||
int pc = 0;
|
||||
if (pt->is_vararg) /* varargs? */
|
||||
top++; /* `arg' */
|
||||
while (pc < lastpc) {
|
||||
const Instruction i = code[pc++];
|
||||
LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack");
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_RETURN: {
|
||||
LUA_ASSERT(top >= GETARG_U(i), "wrong stack");
|
||||
top = GETARG_U(i);
|
||||
break;
|
||||
}
|
||||
case OP_TAILCALL: {
|
||||
LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
|
||||
top = GETARG_B(i);
|
||||
break;
|
||||
}
|
||||
case OP_CALL: {
|
||||
int nresults = GETARG_B(i);
|
||||
if (nresults == MULT_RET) nresults = 1;
|
||||
LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
|
||||
top = pushpc(stack, pc, GETARG_A(i), nresults);
|
||||
break;
|
||||
}
|
||||
case OP_PUSHNIL: {
|
||||
top = pushpc(stack, pc, top, GETARG_U(i));
|
||||
break;
|
||||
}
|
||||
case OP_POP: {
|
||||
top -= GETARG_U(i);
|
||||
break;
|
||||
}
|
||||
case OP_SETTABLE:
|
||||
case OP_SETLIST: {
|
||||
top -= GETARG_B(i);
|
||||
break;
|
||||
}
|
||||
case OP_SETMAP: {
|
||||
top -= 2*GETARG_U(i);
|
||||
break;
|
||||
}
|
||||
case OP_CONCAT: {
|
||||
top -= GETARG_U(i);
|
||||
stack[top++] = pc-1;
|
||||
break;
|
||||
}
|
||||
case OP_CLOSURE: {
|
||||
top -= GETARG_B(i);
|
||||
stack[top++] = pc-1;
|
||||
break;
|
||||
}
|
||||
case OP_JMPONT:
|
||||
case OP_JMPONF: {
|
||||
int newpc = pc + GETARG_S(i);
|
||||
/* jump is forward and do not skip `lastpc'? */
|
||||
if (pc < newpc && newpc <= lastpc) {
|
||||
stack[top-1] = pc-1; /* value comes from `and'/`or' */
|
||||
pc = newpc; /* do the jump */
|
||||
}
|
||||
else
|
||||
top--; /* do not jump; pop value */
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
OpCode op = GET_OPCODE(i);
|
||||
LUA_ASSERT(luaK_opproperties[op].push != VD,
|
||||
"invalid opcode for default");
|
||||
top -= luaK_opproperties[op].pop;
|
||||
LUA_ASSERT(top >= 0, "wrong stack");
|
||||
top = pushpc(stack, pc, top, luaK_opproperties[op].push);
|
||||
}
|
||||
}
|
||||
}
|
||||
return code[stack[stackpos]];
|
||||
}
|
||||
|
||||
|
||||
static const char *getobjname (lua_State *L, StkId obj, const char **name) {
|
||||
StkId func = aux_stackedfunction(L, 0, obj);
|
||||
if (!isLmark(func))
|
||||
return NULL; /* not an active Lua function */
|
||||
else {
|
||||
Proto *p = infovalue(func)->func->f.l;
|
||||
int pc = currentpc(func);
|
||||
int stackpos = obj - (func+1); /* func+1 == function base */
|
||||
Instruction i = luaG_symbexec(p, pc, stackpos);
|
||||
LUA_ASSERT(pc != -1, "function must be active");
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_GETGLOBAL: {
|
||||
*name = p->kstr[GETARG_U(i)]->str;
|
||||
return "global";
|
||||
}
|
||||
case OP_GETLOCAL: {
|
||||
*name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
|
||||
LUA_ASSERT(*name, "local must exist");
|
||||
return "local";
|
||||
}
|
||||
case OP_PUSHSELF:
|
||||
case OP_GETDOTTED: {
|
||||
*name = p->kstr[GETARG_U(i)]->str;
|
||||
return "field";
|
||||
}
|
||||
default:
|
||||
return NULL; /* no useful name found */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *getfuncname (lua_State *L, StkId f, const char **name) {
|
||||
StkId func = aux_stackedfunction(L, 0, f); /* calling function */
|
||||
if (!isLmark(func))
|
||||
return NULL; /* not an active Lua function */
|
||||
else {
|
||||
Proto *p = infovalue(func)->func->f.l;
|
||||
int pc = currentpc(func);
|
||||
Instruction i;
|
||||
if (pc == -1) return NULL; /* function is not activated */
|
||||
i = p->code[pc];
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_CALL: case OP_TAILCALL:
|
||||
return getobjname(L, (func+1)+GETARG_A(i), name);
|
||||
default:
|
||||
return NULL; /* no useful name found */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
void luaG_typeerror (lua_State *L, StkId o, const char *op) {
|
||||
const char *name;
|
||||
const char *kind = getobjname(L, o, &name);
|
||||
const char *t = luaO_typename(o);
|
||||
if (kind)
|
||||
luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
|
||||
op, kind, name, t);
|
||||
else
|
||||
luaO_verror(L, "attempt to %.30s a %.10s value", op, t);
|
||||
}
|
||||
|
||||
|
||||
void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) {
|
||||
if (ttype(p1) == t) p1++;
|
||||
LUA_ASSERT(ttype(p1) != t, "must be an error");
|
||||
luaG_typeerror(L, p1, op);
|
||||
}
|
||||
|
||||
|
||||
void luaG_ordererror (lua_State *L, StkId top) {
|
||||
const char *t1 = luaO_typename(top-2);
|
||||
const char *t2 = luaO_typename(top-1);
|
||||
if (t1[2] == t2[2])
|
||||
luaO_verror(L, "attempt to compare two %.10s values", t1);
|
||||
else
|
||||
luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2);
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
** $Id: ldebug.h,v 1.1 2003/01/24 16:26:01 jason379 Exp $
|
||||
** Auxiliary functions from Debug Interface module
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef ldebug_h
|
||||
#define ldebug_h
|
||||
|
||||
|
||||
#include "lstate.h"
|
||||
#include "luadebug.h"
|
||||
|
||||
|
||||
void luaG_typeerror (lua_State *L, StkId o, const char *op);
|
||||
void luaG_binerror (lua_State *L, StkId p1, int t, const char *op);
|
||||
int luaG_getline (int *lineinfo, int pc, int refline, int *refi);
|
||||
void luaG_ordererror (lua_State *L, StkId top);
|
||||
|
||||
|
||||
#endif
|
@ -1,388 +0,0 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 1.1 2003/01/24 16:26:02 jason379 Exp $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lgc.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lparser.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
#include "lundump.h"
|
||||
#include "lvm.h"
|
||||
#include "lzio.h"
|
||||
|
||||
|
||||
/* space to handle stack overflow errors */
|
||||
#define EXTRA_STACK (2*LUA_MINSTACK)
|
||||
|
||||
|
||||
void luaD_init (lua_State *L, int stacksize) {
|
||||
L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
|
||||
L->nblocks += stacksize*sizeof(TObject);
|
||||
L->stack_last = L->stack+(stacksize-1);
|
||||
L->stacksize = stacksize;
|
||||
L->Cbase = L->top = L->stack;
|
||||
}
|
||||
|
||||
|
||||
void luaD_checkstack (lua_State *L, int n) {
|
||||
if (L->stack_last - L->top <= n) { /* stack overflow? */
|
||||
if (L->stack_last-L->stack > (L->stacksize-1)) {
|
||||
/* overflow while handling overflow */
|
||||
luaD_breakrun(L, LUA_ERRERR); /* break run without error message */
|
||||
}
|
||||
else {
|
||||
L->stack_last += EXTRA_STACK; /* to be used by error message */
|
||||
lua_error(L, "stack overflow");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void restore_stack_limit (lua_State *L) {
|
||||
if (L->top - L->stack < L->stacksize - 1)
|
||||
L->stack_last = L->stack + (L->stacksize-1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Adjust stack. Set top to base+extra, pushing NILs if needed.
|
||||
** (we cannot add base+extra unless we are sure it fits in the stack;
|
||||
** otherwise the result of such operation on pointers is undefined)
|
||||
*/
|
||||
void luaD_adjusttop (lua_State *L, StkId base, int extra) {
|
||||
int diff = extra-(L->top-base);
|
||||
if (diff <= 0)
|
||||
L->top = base+extra;
|
||||
else {
|
||||
luaD_checkstack(L, diff);
|
||||
while (diff--)
|
||||
ttype(L->top++) = LUA_TNIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Open a hole inside the stack at `pos'
|
||||
*/
|
||||
static void luaD_openstack (lua_State *L, StkId pos) {
|
||||
int i = L->top-pos;
|
||||
while (i--) pos[i+1] = pos[i];
|
||||
incr_top;
|
||||
}
|
||||
|
||||
|
||||
static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
|
||||
StkId old_Cbase = L->Cbase;
|
||||
StkId old_top = L->Cbase = L->top;
|
||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||
L->allowhooks = 0; /* cannot call hooks inside a hook */
|
||||
(*hook)(L, ar);
|
||||
LUA_ASSERT(L->allowhooks == 0, "invalid allow");
|
||||
L->allowhooks = 1;
|
||||
L->top = old_top;
|
||||
L->Cbase = old_Cbase;
|
||||
}
|
||||
|
||||
|
||||
void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
|
||||
if (L->allowhooks) {
|
||||
lua_Debug ar;
|
||||
ar._func = func;
|
||||
ar.event = "line";
|
||||
ar.currentline = line;
|
||||
dohook(L, &ar, linehook);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
|
||||
const char *event) {
|
||||
if (L->allowhooks) {
|
||||
lua_Debug ar;
|
||||
ar._func = func;
|
||||
ar.event = event;
|
||||
infovalue(func)->pc = NULL; /* function is not active */
|
||||
dohook(L, &ar, callhook);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
|
||||
int nup = cl->nupvalues; /* number of upvalues */
|
||||
StkId old_Cbase = L->Cbase;
|
||||
int n;
|
||||
L->Cbase = base; /* new base for C function */
|
||||
luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
|
||||
for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
|
||||
*(L->top++) = cl->upvalue[n];
|
||||
n = (*cl->f.c)(L); /* do the actual call */
|
||||
L->Cbase = old_Cbase; /* restore old C base */
|
||||
return L->top - n; /* return index of first result */
|
||||
}
|
||||
|
||||
|
||||
void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) {
|
||||
StkId base = L->top - nParams;
|
||||
luaD_openstack(L, base);
|
||||
clvalue(base) = f;
|
||||
ttype(base) = LUA_TFUNCTION;
|
||||
luaD_call(L, base, nResults);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Call a function (C or Lua). The function to be called is at *func.
|
||||
** The arguments are on the stack, right after the function.
|
||||
** When returns, the results are on the stack, starting at the original
|
||||
** function position.
|
||||
** The number of results is nResults, unless nResults=LUA_MULTRET.
|
||||
*/
|
||||
void luaD_call (lua_State *L, StkId func, int nResults) {
|
||||
lua_Hook callhook;
|
||||
StkId firstResult;
|
||||
CallInfo ci;
|
||||
Closure *cl;
|
||||
if (ttype(func) != LUA_TFUNCTION) {
|
||||
/* `func' is not a function; check the `function' tag method */
|
||||
Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION);
|
||||
if (tm == NULL)
|
||||
luaG_typeerror(L, func, "call");
|
||||
luaD_openstack(L, func);
|
||||
clvalue(func) = tm; /* tag method is the new function to be called */
|
||||
ttype(func) = LUA_TFUNCTION;
|
||||
}
|
||||
cl = clvalue(func);
|
||||
ci.func = cl;
|
||||
infovalue(func) = &ci;
|
||||
ttype(func) = LUA_TMARK;
|
||||
callhook = L->callhook;
|
||||
if (callhook)
|
||||
luaD_callHook(L, func, callhook, "call");
|
||||
firstResult = (cl->isC ? callCclosure(L, cl, func+1) :
|
||||
luaV_execute(L, cl, func+1));
|
||||
if (callhook) /* same hook that was active at entry */
|
||||
luaD_callHook(L, func, callhook, "return");
|
||||
LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag");
|
||||
/* move results to `func' (to erase parameters and function) */
|
||||
if (nResults == LUA_MULTRET) {
|
||||
while (firstResult < L->top) /* copy all results */
|
||||
*func++ = *firstResult++;
|
||||
L->top = func;
|
||||
}
|
||||
else { /* copy at most `nResults' */
|
||||
for (; nResults > 0 && firstResult < L->top; nResults--)
|
||||
*func++ = *firstResult++;
|
||||
L->top = func;
|
||||
for (; nResults > 0; nResults--) { /* if there are not enough results */
|
||||
ttype(L->top) = LUA_TNIL; /* adjust the stack */
|
||||
incr_top; /* must check stack space */
|
||||
}
|
||||
}
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Execute a protected call.
|
||||
*/
|
||||
struct CallS { /* data to `f_call' */
|
||||
StkId func;
|
||||
int nresults;
|
||||
};
|
||||
|
||||
static void f_call (lua_State *L, void *ud) {
|
||||
struct CallS *c = (struct CallS *)ud;
|
||||
luaD_call(L, c->func, c->nresults);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
|
||||
StkId func = L->top - (nargs+1); /* function to be called */
|
||||
struct CallS c;
|
||||
int status;
|
||||
c.func = func; c.nresults = nresults;
|
||||
status = luaD_runprotected(L, f_call, &c);
|
||||
if (status != 0) /* an error occurred? */
|
||||
L->top = func; /* remove parameters from the stack */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Execute a protected parser.
|
||||
*/
|
||||
struct ParserS { /* data to `f_parser' */
|
||||
ZIO *z;
|
||||
int bin;
|
||||
};
|
||||
|
||||
static void f_parser (lua_State *L, void *ud) {
|
||||
struct ParserS *p = (struct ParserS *)ud;
|
||||
Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
|
||||
luaV_Lclosure(L, tf, 0);
|
||||
}
|
||||
|
||||
|
||||
static int protectedparser (lua_State *L, ZIO *z, int bin) {
|
||||
struct ParserS p;
|
||||
unsigned long old_blocks;
|
||||
int status;
|
||||
p.z = z; p.bin = bin;
|
||||
/* before parsing, give a (good) chance to GC */
|
||||
if (L->nblocks/8 >= L->GCthreshold/10)
|
||||
luaC_collectgarbage(L);
|
||||
old_blocks = L->nblocks;
|
||||
status = luaD_runprotected(L, f_parser, &p);
|
||||
if (status == 0) {
|
||||
/* add new memory to threshold (as it probably will stay) */
|
||||
L->GCthreshold += (L->nblocks - old_blocks);
|
||||
}
|
||||
else if (status == LUA_ERRRUN) /* an error occurred: correct error code */
|
||||
status = LUA_ERRSYNTAX;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int parse_file (lua_State *L, const char *filename) {
|
||||
ZIO z;
|
||||
int status;
|
||||
int bin; /* flag for file mode */
|
||||
int c; /* look ahead char */
|
||||
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
|
||||
if (f == NULL) return LUA_ERRFILE; /* unable to open file */
|
||||
c = fgetc(f);
|
||||
ungetc(c, f);
|
||||
bin = (c == ID_CHUNK);
|
||||
if (bin && f != stdin) {
|
||||
f = freopen(filename, "rb", f); /* set binary mode */
|
||||
if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */
|
||||
}
|
||||
lua_pushstring(L, "@");
|
||||
lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
|
||||
lua_concat(L, 2);
|
||||
c = lua_gettop(L);
|
||||
filename = lua_tostring(L, c); /* filename = '@'..filename */
|
||||
luaZ_Fopen(&z, f, filename);
|
||||
status = protectedparser(L, &z, bin);
|
||||
lua_remove(L, c); /* remove `filename' from the stack */
|
||||
if (f != stdin)
|
||||
fclose(f);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_dofile (lua_State *L, const char *filename) {
|
||||
int status = parse_file(L, filename);
|
||||
if (status == 0) /* parse OK? */
|
||||
status = lua_call(L, 0, LUA_MULTRET); /* call main */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int parse_buffer (lua_State *L, const char *buff, size_t size,
|
||||
const char *name) {
|
||||
ZIO z;
|
||||
if (!name) name = "?";
|
||||
luaZ_mopen(&z, buff, size, name);
|
||||
return protectedparser(L, &z, buff[0]==ID_CHUNK);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
|
||||
int status = parse_buffer(L, buff, size, name);
|
||||
if (status == 0) /* parse OK? */
|
||||
status = lua_call(L, 0, LUA_MULTRET); /* call main */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_dostring (lua_State *L, const char *str) {
|
||||
return lua_dobuffer(L, str, strlen(str), str);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Error-recover functions (based on long jumps)
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
/* chain list of long jump buffers */
|
||||
struct lua_longjmp {
|
||||
jmp_buf b;
|
||||
struct lua_longjmp *previous;
|
||||
volatile int status; /* error code */
|
||||
};
|
||||
|
||||
|
||||
static void message (lua_State *L, const char *s) {
|
||||
const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE);
|
||||
if (ttype(em) == LUA_TFUNCTION) {
|
||||
*L->top = *em;
|
||||
incr_top;
|
||||
lua_pushstring(L, s);
|
||||
luaD_call(L, L->top-2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Reports an error, and jumps up to the available recovery label
|
||||
*/
|
||||
LUA_API void lua_error (lua_State *L, const char *s) {
|
||||
if (s) message(L, s);
|
||||
luaD_breakrun(L, LUA_ERRRUN);
|
||||
}
|
||||
|
||||
|
||||
void luaD_breakrun (lua_State *L, int errcode) {
|
||||
if (L->errorJmp) {
|
||||
L->errorJmp->status = errcode;
|
||||
longjmp(L->errorJmp->b, 1);
|
||||
}
|
||||
else {
|
||||
if (errcode != LUA_ERRMEM)
|
||||
message(L, "unable to recover; exiting\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
|
||||
StkId oldCbase = L->Cbase;
|
||||
StkId oldtop = L->top;
|
||||
struct lua_longjmp lj;
|
||||
int allowhooks = L->allowhooks;
|
||||
lj.status = 0;
|
||||
lj.previous = L->errorJmp; /* chain new error handler */
|
||||
L->errorJmp = &lj;
|
||||
if (setjmp(lj.b) == 0)
|
||||
(*f)(L, ud);
|
||||
else { /* an error occurred: restore the state */
|
||||
L->allowhooks = allowhooks;
|
||||
L->Cbase = oldCbase;
|
||||
L->top = oldtop;
|
||||
restore_stack_limit(L);
|
||||
}
|
||||
L->errorJmp = lj.previous; /* restore old error handler */
|
||||
return lj.status;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
** $Id: ldo.h,v 1.1 2003/01/24 16:26:03 jason379 Exp $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef ldo_h
|
||||
#define ldo_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
|
||||
|
||||
/*
|
||||
** macro to increment stack top.
|
||||
** There must be always an empty slot at the L->stack.top
|
||||
*/
|
||||
#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}
|
||||
|
||||
|
||||
void luaD_init (lua_State *L, int stacksize);
|
||||
void luaD_adjusttop (lua_State *L, StkId base, int extra);
|
||||
void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
|
||||
void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults);
|
||||
void luaD_checkstack (lua_State *L, int n);
|
||||
|
||||
void luaD_breakrun (lua_State *L, int errcode);
|
||||
int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud);
|
||||
|
||||
|
||||
#endif
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
** $Id: lfunc.c,v 1.1 2003/01/24 16:26:03 jason379 Exp $
|
||||
** Auxiliary functions to manipulate prototypes and closures
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lfunc.h"
|
||||
#include "lmem.h"
|
||||
#include "lstate.h"
|
||||
|
||||
|
||||
#define sizeclosure(n) ((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1))
|
||||
|
||||
|
||||
Closure *luaF_newclosure (lua_State *L, int nelems) {
|
||||
int size = sizeclosure(nelems);
|
||||
Closure *c = (Closure *)luaM_malloc(L, size);
|
||||
c->next = L->rootcl;
|
||||
L->rootcl = c;
|
||||
c->mark = c;
|
||||
c->nupvalues = nelems;
|
||||
L->nblocks += size;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
Proto *luaF_newproto (lua_State *L) {
|
||||
Proto *f = luaM_new(L, Proto);
|
||||
f->knum = NULL;
|
||||
f->nknum = 0;
|
||||
f->kstr = NULL;
|
||||
f->nkstr = 0;
|
||||
f->kproto = NULL;
|
||||
f->nkproto = 0;
|
||||
f->code = NULL;
|
||||
f->ncode = 0;
|
||||
f->numparams = 0;
|
||||
f->is_vararg = 0;
|
||||
f->maxstacksize = 0;
|
||||
f->marked = 0;
|
||||
f->lineinfo = NULL;
|
||||
f->nlineinfo = 0;
|
||||
f->nlocvars = 0;
|
||||
f->locvars = NULL;
|
||||
f->lineDefined = 0;
|
||||
f->source = NULL;
|
||||
f->next = L->rootproto; /* chain in list of protos */
|
||||
L->rootproto = f;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static size_t protosize (Proto *f) {
|
||||
return sizeof(Proto)
|
||||
+ f->nknum*sizeof(Number)
|
||||
+ f->nkstr*sizeof(TString *)
|
||||
+ f->nkproto*sizeof(Proto *)
|
||||
+ f->ncode*sizeof(Instruction)
|
||||
+ f->nlocvars*sizeof(struct LocVar)
|
||||
+ f->nlineinfo*sizeof(int);
|
||||
}
|
||||
|
||||
|
||||
void luaF_protook (lua_State *L, Proto *f, int pc) {
|
||||
f->ncode = pc; /* signal that proto was properly created */
|
||||
L->nblocks += protosize(f);
|
||||
}
|
||||
|
||||
|
||||
void luaF_freeproto (lua_State *L, Proto *f) {
|
||||
if (f->ncode > 0) /* function was properly created? */
|
||||
L->nblocks -= protosize(f);
|
||||
luaM_free(L, f->code);
|
||||
luaM_free(L, f->locvars);
|
||||
luaM_free(L, f->kstr);
|
||||
luaM_free(L, f->knum);
|
||||
luaM_free(L, f->kproto);
|
||||
luaM_free(L, f->lineinfo);
|
||||
luaM_free(L, f);
|
||||
}
|
||||
|
||||
|
||||
void luaF_freeclosure (lua_State *L, Closure *c) {
|
||||
L->nblocks -= sizeclosure(c->nupvalues);
|
||||
luaM_free(L, c);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Look for n-th local variable at line `line' in function `func'.
|
||||
** Returns NULL if not found.
|
||||
*/
|
||||
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
|
||||
int i;
|
||||
for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
|
||||
if (pc < f->locvars[i].endpc) { /* is variable active? */
|
||||
local_number--;
|
||||
if (local_number == 0)
|
||||
return f->locvars[i].varname->str;
|
||||
}
|
||||
}
|
||||
return NULL; /* not found */
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
** $Id: lfunc.h,v 1.1 2003/01/24 16:26:04 jason379 Exp $
|
||||
** Auxiliary functions to manipulate prototypes and closures
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lfunc_h
|
||||
#define lfunc_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
|
||||
Proto *luaF_newproto (lua_State *L);
|
||||
void luaF_protook (lua_State *L, Proto *f, int pc);
|
||||
Closure *luaF_newclosure (lua_State *L, int nelems);
|
||||
void luaF_freeproto (lua_State *L, Proto *f);
|
||||
void luaF_freeclosure (lua_State *L, Closure *c);
|
||||
|
||||
const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
|
||||
|
||||
|
||||
#endif
|
@ -1,353 +0,0 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 1.1 2003/01/24 16:26:05 jason379 Exp $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lgc.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
|
||||
|
||||
typedef struct GCState {
|
||||
Hash *tmark; /* list of marked tables to be visited */
|
||||
Closure *cmark; /* list of marked closures to be visited */
|
||||
} GCState;
|
||||
|
||||
|
||||
|
||||
static void markobject (GCState *st, TObject *o);
|
||||
|
||||
|
||||
/* mark a string; marks larger than 1 cannot be changed */
|
||||
#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;}
|
||||
|
||||
|
||||
|
||||
static void protomark (Proto *f) {
|
||||
if (!f->marked) {
|
||||
int i;
|
||||
f->marked = 1;
|
||||
strmark(f->source);
|
||||
for (i=0; i<f->nkstr; i++)
|
||||
strmark(f->kstr[i]);
|
||||
for (i=0; i<f->nkproto; i++)
|
||||
protomark(f->kproto[i]);
|
||||
for (i=0; i<f->nlocvars; i++) /* mark local-variable names */
|
||||
strmark(f->locvars[i].varname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void markstack (lua_State *L, GCState *st) {
|
||||
StkId o;
|
||||
for (o=L->stack; o<L->top; o++)
|
||||
markobject(st, o);
|
||||
}
|
||||
|
||||
|
||||
static void marklock (lua_State *L, GCState *st) {
|
||||
int i;
|
||||
for (i=0; i<L->refSize; i++) {
|
||||
if (L->refArray[i].st == LOCK)
|
||||
markobject(st, &L->refArray[i].o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void markclosure (GCState *st, Closure *cl) {
|
||||
if (!ismarked(cl)) {
|
||||
if (!cl->isC)
|
||||
protomark(cl->f.l);
|
||||
cl->mark = st->cmark; /* chain it for later traversal */
|
||||
st->cmark = cl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void marktagmethods (lua_State *L, GCState *st) {
|
||||
int e;
|
||||
for (e=0; e<TM_N; e++) {
|
||||
int t;
|
||||
for (t=0; t<=L->last_tag; t++) {
|
||||
Closure *cl = luaT_gettm(L, t, e);
|
||||
if (cl) markclosure(st, cl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void markobject (GCState *st, TObject *o) {
|
||||
switch (ttype(o)) {
|
||||
case LUA_TUSERDATA: case LUA_TSTRING:
|
||||
strmark(tsvalue(o));
|
||||
break;
|
||||
case LUA_TMARK:
|
||||
markclosure(st, infovalue(o)->func);
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
markclosure(st, clvalue(o));
|
||||
break;
|
||||
case LUA_TTABLE: {
|
||||
if (!ismarked(hvalue(o))) {
|
||||
hvalue(o)->mark = st->tmark; /* chain it in list of marked */
|
||||
st->tmark = hvalue(o);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break; /* numbers, etc */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void markall (lua_State *L) {
|
||||
GCState st;
|
||||
st.cmark = NULL;
|
||||
st.tmark = L->gt; /* put table of globals in mark list */
|
||||
L->gt->mark = NULL;
|
||||
marktagmethods(L, &st); /* mark tag methods */
|
||||
markstack(L, &st); /* mark stack objects */
|
||||
marklock(L, &st); /* mark locked objects */
|
||||
for (;;) { /* mark tables and closures */
|
||||
if (st.cmark) {
|
||||
int i;
|
||||
Closure *f = st.cmark; /* get first closure from list */
|
||||
st.cmark = f->mark; /* remove it from list */
|
||||
for (i=0; i<f->nupvalues; i++) /* mark its upvalues */
|
||||
markobject(&st, &f->upvalue[i]);
|
||||
}
|
||||
else if (st.tmark) {
|
||||
int i;
|
||||
Hash *h = st.tmark; /* get first table from list */
|
||||
st.tmark = h->mark; /* remove it from list */
|
||||
for (i=0; i<h->size; i++) {
|
||||
Node *n = node(h, i);
|
||||
if (ttype(key(n)) != LUA_TNIL) {
|
||||
if (ttype(val(n)) == LUA_TNIL)
|
||||
luaH_remove(h, key(n)); /* dead element; try to remove it */
|
||||
markobject(&st, &n->key);
|
||||
markobject(&st, &n->val);
|
||||
}
|
||||
}
|
||||
}
|
||||
else break; /* nothing else to mark */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int hasmark (const TObject *o) {
|
||||
/* valid only for locked objects */
|
||||
switch (o->ttype) {
|
||||
case LUA_TSTRING: case LUA_TUSERDATA:
|
||||
return tsvalue(o)->marked;
|
||||
case LUA_TTABLE:
|
||||
return ismarked(hvalue(o));
|
||||
case LUA_TFUNCTION:
|
||||
return ismarked(clvalue(o));
|
||||
default: /* number */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* macro for internal debugging; check if a link of free refs is valid */
|
||||
#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
|
||||
|
||||
static void invalidaterefs (lua_State *L) {
|
||||
int n = L->refSize;
|
||||
int i;
|
||||
for (i=0; i<n; i++) {
|
||||
struct Ref *r = &L->refArray[i];
|
||||
if (r->st == HOLD && !hasmark(&r->o))
|
||||
r->st = COLLECTED;
|
||||
LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
|
||||
(r->st == HOLD && hasmark(&r->o)) ||
|
||||
r->st == COLLECTED ||
|
||||
r->st == NONEXT ||
|
||||
(r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
|
||||
"inconsistent ref table");
|
||||
}
|
||||
LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void collectproto (lua_State *L) {
|
||||
Proto **p = &L->rootproto;
|
||||
Proto *next;
|
||||
while ((next = *p) != NULL) {
|
||||
if (next->marked) {
|
||||
next->marked = 0;
|
||||
p = &next->next;
|
||||
}
|
||||
else {
|
||||
*p = next->next;
|
||||
luaF_freeproto(L, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void collectclosure (lua_State *L) {
|
||||
Closure **p = &L->rootcl;
|
||||
Closure *next;
|
||||
while ((next = *p) != NULL) {
|
||||
if (ismarked(next)) {
|
||||
next->mark = next; /* unmark */
|
||||
p = &next->next;
|
||||
}
|
||||
else {
|
||||
*p = next->next;
|
||||
luaF_freeclosure(L, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void collecttable (lua_State *L) {
|
||||
Hash **p = &L->roottable;
|
||||
Hash *next;
|
||||
while ((next = *p) != NULL) {
|
||||
if (ismarked(next)) {
|
||||
next->mark = next; /* unmark */
|
||||
p = &next->next;
|
||||
}
|
||||
else {
|
||||
*p = next->next;
|
||||
luaH_free(L, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void checktab (lua_State *L, stringtable *tb) {
|
||||
if (tb->nuse < (lint32)(tb->size/4) && tb->size > 10)
|
||||
luaS_resize(L, tb, tb->size/2); /* table is too big */
|
||||
}
|
||||
|
||||
|
||||
static void collectstrings (lua_State *L, int all) {
|
||||
int i;
|
||||
for (i=0; i<L->strt.size; i++) { /* for each list */
|
||||
TString **p = &L->strt.hash[i];
|
||||
TString *next;
|
||||
while ((next = *p) != NULL) {
|
||||
if (next->marked && !all) { /* preserve? */
|
||||
if (next->marked < FIXMARK) /* does not change FIXMARKs */
|
||||
next->marked = 0;
|
||||
p = &next->nexthash;
|
||||
}
|
||||
else { /* collect */
|
||||
*p = next->nexthash;
|
||||
L->strt.nuse--;
|
||||
L->nblocks -= sizestring(next->len);
|
||||
luaM_free(L, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
checktab(L, &L->strt);
|
||||
}
|
||||
|
||||
|
||||
static void collectudata (lua_State *L, int all) {
|
||||
int i;
|
||||
for (i=0; i<L->udt.size; i++) { /* for each list */
|
||||
TString **p = &L->udt.hash[i];
|
||||
TString *next;
|
||||
while ((next = *p) != NULL) {
|
||||
LUA_ASSERT(next->marked <= 1, "udata cannot be fixed");
|
||||
if (next->marked && !all) { /* preserve? */
|
||||
next->marked = 0;
|
||||
p = &next->nexthash;
|
||||
}
|
||||
else { /* collect */
|
||||
int tag = next->u.d.tag;
|
||||
*p = next->nexthash;
|
||||
next->nexthash = L->TMtable[tag].collected; /* chain udata */
|
||||
L->TMtable[tag].collected = next;
|
||||
L->nblocks -= sizestring(next->len);
|
||||
L->udt.nuse--;
|
||||
}
|
||||
}
|
||||
}
|
||||
checktab(L, &L->udt);
|
||||
}
|
||||
|
||||
|
||||
#define MINBUFFER 256
|
||||
static void checkMbuffer (lua_State *L) {
|
||||
if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
|
||||
size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */
|
||||
L->nblocks += (newsize - L->Mbuffsize)*sizeof(char);
|
||||
L->Mbuffsize = newsize;
|
||||
luaM_reallocvector(L, L->Mbuffer, newsize, char);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void callgcTM (lua_State *L, const TObject *o) {
|
||||
Closure *tm = luaT_gettmbyObj(L, o, TM_GC);
|
||||
if (tm != NULL) {
|
||||
int oldah = L->allowhooks;
|
||||
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
|
||||
luaD_checkstack(L, 2);
|
||||
clvalue(L->top) = tm;
|
||||
ttype(L->top) = LUA_TFUNCTION;
|
||||
*(L->top+1) = *o;
|
||||
L->top += 2;
|
||||
luaD_call(L, L->top-2, 0);
|
||||
L->allowhooks = oldah; /* restore hooks */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void callgcTMudata (lua_State *L) {
|
||||
int tag;
|
||||
TObject o;
|
||||
ttype(&o) = LUA_TUSERDATA;
|
||||
L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */
|
||||
for (tag=L->last_tag; tag>=0; tag--) { /* for each tag (in reverse order) */
|
||||
TString *udata;
|
||||
while ((udata = L->TMtable[tag].collected) != NULL) {
|
||||
L->TMtable[tag].collected = udata->nexthash; /* remove it from list */
|
||||
tsvalue(&o) = udata;
|
||||
callgcTM(L, &o);
|
||||
luaM_free(L, udata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaC_collect (lua_State *L, int all) {
|
||||
collectudata(L, all);
|
||||
callgcTMudata(L);
|
||||
collectstrings(L, all);
|
||||
collecttable(L);
|
||||
collectproto(L);
|
||||
collectclosure(L);
|
||||
}
|
||||
|
||||
|
||||
void luaC_collectgarbage (lua_State *L) {
|
||||
markall(L);
|
||||
invalidaterefs(L); /* check unlocked references */
|
||||
luaC_collect(L, 0);
|
||||
checkMbuffer(L);
|
||||
L->GCthreshold = 2*L->nblocks; /* set new threshold */
|
||||
callgcTM(L, &luaO_nilobject);
|
||||
}
|
||||
|
||||
|
||||
void luaC_checkGC (lua_State *L) {
|
||||
if (L->nblocks >= L->GCthreshold)
|
||||
luaC_collectgarbage(L);
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
** $Id: lgc.h,v 1.1 2003/01/24 16:26:06 jason379 Exp $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lgc_h
|
||||
#define lgc_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
void luaC_collect (lua_State *L, int all);
|
||||
void luaC_collectgarbage (lua_State *L);
|
||||
void luaC_checkGC (lua_State *L);
|
||||
|
||||
|
||||
#endif
|
@ -1,718 +0,0 @@
|
||||
/*
|
||||
** $Id: liolib.c,v 1.1 2003/04/23 12:16:05 jason379 Exp $
|
||||
** Standard I/O (and system) library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "luadebug.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
#ifndef OLD_ANSI
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
|
||||
#define free(b) if (b) (free)(b)
|
||||
#else
|
||||
/* no support for locale and for strerror: fake them */
|
||||
#define setlocale(a,b) ((void)a, strcmp((b),"C")==0?"C":NULL)
|
||||
#define LC_ALL 0
|
||||
#define LC_COLLATE 0
|
||||
#define LC_CTYPE 0
|
||||
#define LC_MONETARY 0
|
||||
#define LC_NUMERIC 0
|
||||
#define LC_TIME 0
|
||||
#define strerror(e) "generic I/O error"
|
||||
#define errno (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef POPEN
|
||||
/* FILE *popen();
|
||||
int pclose(); */
|
||||
#define CLOSEFILE(L, f) ((pclose(f) == -1) ? fclose(f) : 0)
|
||||
#else
|
||||
/* no support for popen */
|
||||
#define popen(x,y) NULL /* that is, popen always fails */
|
||||
#define CLOSEFILE(L, f) (fclose(f))
|
||||
#endif
|
||||
|
||||
|
||||
#define INFILE 0
|
||||
#define OUTFILE 1
|
||||
|
||||
typedef struct IOCtrl {
|
||||
int ref[2]; /* ref for strings _INPUT/_OUTPUT */
|
||||
int iotag; /* tag for file handles */
|
||||
int closedtag; /* tag for closed handles */
|
||||
} IOCtrl;
|
||||
|
||||
|
||||
|
||||
static const char *const filenames[] = {"_INPUT", "_OUTPUT"};
|
||||
|
||||
|
||||
static int pushresult (lua_State *L, int i) {
|
||||
if (i) {
|
||||
lua_pushuserdata(L, NULL);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
lua_pushnumber(L, errno);
|
||||
return 3;;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** FILE Operations
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) {
|
||||
void *p = lua_touserdata(L, f);
|
||||
if (p != NULL) { /* is `f' a userdata ? */
|
||||
int ftag = lua_tag(L, f);
|
||||
if (ftag == ctrl->iotag) /* does it have the correct tag? */
|
||||
return (FILE *)p;
|
||||
else if (ftag == ctrl->closedtag)
|
||||
lua_error(L, "cannot access a closed file");
|
||||
/* else go through */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
|
||||
FILE *f = gethandle(L, ctrl, arg);
|
||||
luaL_arg_check(L, f, arg, "invalid file handle");
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) {
|
||||
FILE *f;
|
||||
lua_getglobals(L);
|
||||
lua_getref(L, ctrl->ref[inout]);
|
||||
lua_rawget(L, -2);
|
||||
f = gethandle(L, ctrl, -1);
|
||||
if (f == NULL)
|
||||
luaL_verror(L, "global variable `%.10s' is not a file handle",
|
||||
filenames[inout]);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f,
|
||||
const char *name) {
|
||||
lua_pushusertag(L, f, ctrl->iotag);
|
||||
lua_setglobal(L, name);
|
||||
}
|
||||
|
||||
|
||||
#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout]))
|
||||
|
||||
|
||||
static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
|
||||
if (f == NULL)
|
||||
return pushresult(L, 0);
|
||||
else {
|
||||
setfile(L, ctrl, f, inout);
|
||||
lua_pushusertag(L, f, ctrl->iotag);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
|
||||
if (f == stdin || f == stdout || f == stderr)
|
||||
return 1;
|
||||
else {
|
||||
lua_pushusertag(L, f, ctrl->iotag);
|
||||
lua_settag(L, ctrl->closedtag);
|
||||
return (CLOSEFILE(L, f) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int io_close (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
lua_pop(L, 1); /* remove upvalue */
|
||||
return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1)));
|
||||
}
|
||||
|
||||
|
||||
static int file_collect (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
FILE *f = getnonullfile(L, ctrl, 1);
|
||||
if (f != stdin && f != stdout && f != stderr)
|
||||
CLOSEFILE(L, f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int io_open (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
FILE *f;
|
||||
lua_pop(L, 1); /* remove upvalue */
|
||||
f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2));
|
||||
if (f) {
|
||||
lua_pushusertag(L, f, ctrl->iotag);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return pushresult(L, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int io_fromto (lua_State *L, int inout, const char *mode) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
FILE *current;
|
||||
lua_pop(L, 1); /* remove upvalue */
|
||||
if (lua_isnull(L, 1)) {
|
||||
closefile(L, ctrl, getfilebyref(L, ctrl, inout));
|
||||
current = (inout == 0) ? stdin : stdout;
|
||||
}
|
||||
else if (lua_tag(L, 1) == ctrl->iotag) /* deprecated option */
|
||||
current = (FILE *)lua_touserdata(L, 1);
|
||||
else {
|
||||
const char *s = luaL_check_string(L, 1);
|
||||
current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode);
|
||||
}
|
||||
return setreturn(L, ctrl, current, inout);
|
||||
}
|
||||
|
||||
|
||||
static int io_readfrom (lua_State *L) {
|
||||
return io_fromto(L, INFILE, "r");
|
||||
}
|
||||
|
||||
|
||||
static int io_writeto (lua_State *L) {
|
||||
return io_fromto(L, OUTFILE, "w");
|
||||
}
|
||||
|
||||
|
||||
static int io_appendto (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
FILE *current;
|
||||
lua_pop(L, 1); /* remove upvalue */
|
||||
current = fopen(luaL_check_string(L, 1), "a");
|
||||
return setreturn(L, ctrl, current, OUTFILE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** READ
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifdef LUA_COMPAT_READPATTERN
|
||||
|
||||
/*
|
||||
** We cannot lookahead without need, because this can lock stdin.
|
||||
** This flag signals when we need to read a next char.
|
||||
*/
|
||||
#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
|
||||
|
||||
|
||||
static int read_pattern (lua_State *L, FILE *f, const char *p) {
|
||||
int inskip = 0; /* {skip} level */
|
||||
int c = NEED_OTHER;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
while (*p != '\0') {
|
||||
switch (*p) {
|
||||
case '{':
|
||||
inskip++;
|
||||
p++;
|
||||
continue;
|
||||
case '}':
|
||||
if (!inskip) lua_error(L, "unbalanced braces in read pattern");
|
||||
inskip--;
|
||||
p++;
|
||||
continue;
|
||||
default: {
|
||||
const char *ep = luaI_classend(L, p); /* get what is next */
|
||||
int m; /* match result */
|
||||
if (c == NEED_OTHER) c = getc(f);
|
||||
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
|
||||
if (m) {
|
||||
if (!inskip) luaL_putchar(&b, c);
|
||||
c = NEED_OTHER;
|
||||
}
|
||||
switch (*ep) {
|
||||
case '+': /* repetition (1 or more) */
|
||||
if (!m) goto break_while; /* pattern fails? */
|
||||
/* else go through */
|
||||
case '*': /* repetition (0 or more) */
|
||||
while (m) { /* reads the same item until it fails */
|
||||
c = getc(f);
|
||||
m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
|
||||
if (m && !inskip) luaL_putchar(&b, c);
|
||||
}
|
||||
/* go through to continue reading the pattern */
|
||||
case '?': /* optional */
|
||||
p = ep+1; /* continues reading the pattern */
|
||||
continue;
|
||||
default:
|
||||
if (!m) goto break_while; /* pattern fails? */
|
||||
p = ep; /* else continues reading the pattern */
|
||||
}
|
||||
}
|
||||
}
|
||||
} break_while:
|
||||
if (c != NEED_OTHER) ungetc(c, f);
|
||||
luaL_pushresult(&b); /* close buffer */
|
||||
return (*p == '\0');
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define read_pattern(L, f, p) (lua_error(L, "read patterns are deprecated"), 0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int read_number (lua_State *L, FILE *f) {
|
||||
double d;
|
||||
if (fscanf(f, "%lf", &d) == 1) {
|
||||
lua_pushnumber(L, d);
|
||||
return 1;
|
||||
}
|
||||
else return 0; /* read fails */
|
||||
}
|
||||
|
||||
|
||||
static int read_word (lua_State *L, FILE *f) {
|
||||
int c;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
do { c = fgetc(f); } while (isspace(c)); /* skip spaces */
|
||||
while (c != EOF && !isspace(c)) {
|
||||
luaL_putchar(&b, c);
|
||||
c = fgetc(f);
|
||||
}
|
||||
ungetc(c, f);
|
||||
luaL_pushresult(&b); /* close buffer */
|
||||
return (lua_strlen(L, -1) > 0);
|
||||
}
|
||||
|
||||
|
||||
static int read_line (lua_State *L, FILE *f) {
|
||||
int n = 0;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
for (;;) {
|
||||
char *p = luaL_prepbuffer(&b);
|
||||
if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */
|
||||
break;
|
||||
n = strlen(p);
|
||||
if (p[n-1] != '\n')
|
||||
luaL_addsize(&b, n);
|
||||
else {
|
||||
luaL_addsize(&b, n-1); /* do not add the `\n' */
|
||||
break;
|
||||
}
|
||||
}
|
||||
luaL_pushresult(&b); /* close buffer */
|
||||
return (n > 0); /* read something? */
|
||||
}
|
||||
|
||||
|
||||
static void read_file (lua_State *L, FILE *f) {
|
||||
size_t len = 0;
|
||||
size_t size = BUFSIZ;
|
||||
char *buffer = NULL;
|
||||
for (;;) {
|
||||
char *newbuffer = (char *)realloc(buffer, size);
|
||||
if (newbuffer == NULL) {
|
||||
free(buffer);
|
||||
lua_error(L, "not enough memory to read a file");
|
||||
}
|
||||
buffer = newbuffer;
|
||||
len += fread(buffer+len, sizeof(char), size-len, f);
|
||||
if (len < size) break; /* did not read all it could */
|
||||
size *= 2;
|
||||
}
|
||||
lua_pushlstring(L, buffer, len);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static int read_chars (lua_State *L, FILE *f, size_t n) {
|
||||
char *buffer;
|
||||
size_t n1;
|
||||
char statbuff[BUFSIZ];
|
||||
if (n <= BUFSIZ)
|
||||
buffer = statbuff;
|
||||
else {
|
||||
buffer = (char *)malloc(n);
|
||||
if (buffer == NULL)
|
||||
lua_error(L, "not enough memory to read a file");
|
||||
}
|
||||
n1 = fread(buffer, sizeof(char), n, f);
|
||||
lua_pushlstring(L, buffer, n1);
|
||||
if (buffer != statbuff) free(buffer);
|
||||
return (n1 > 0 || n == 0);
|
||||
}
|
||||
|
||||
|
||||
static int io_read (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
int lastarg = lua_gettop(L) - 1;
|
||||
int firstarg = 1;
|
||||
FILE *f = gethandle(L, ctrl, firstarg);
|
||||
int n;
|
||||
if (f) firstarg++;
|
||||
else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */
|
||||
lua_pop(L, 1);
|
||||
if (firstarg > lastarg) { /* no arguments? */
|
||||
lua_settop(L, 0); /* erase upvalue and other eventual garbage */
|
||||
firstarg = lastarg = 1; /* correct indices */
|
||||
lua_pushstring(L, "*l"); /* push default argument */
|
||||
}
|
||||
else /* ensure stack space for all results and for auxlib's buffer */
|
||||
luaL_checkstack(L, lastarg-firstarg+1+LUA_MINSTACK, "too many arguments");
|
||||
for (n = firstarg; n<=lastarg; n++) {
|
||||
int success;
|
||||
if (lua_isnumber(L, n))
|
||||
success = read_chars(L, f, (size_t)lua_tonumber(L, n));
|
||||
else {
|
||||
const char *p = luaL_check_string(L, n);
|
||||
if (p[0] != '*')
|
||||
success = read_pattern(L, f, p); /* deprecated! */
|
||||
else {
|
||||
switch (p[1]) {
|
||||
case 'n': /* number */
|
||||
if (!read_number(L, f)) goto endloop; /* read fails */
|
||||
continue; /* number is already pushed; avoid the "pushstring" */
|
||||
case 'l': /* line */
|
||||
success = read_line(L, f);
|
||||
break;
|
||||
case 'a': /* file */
|
||||
read_file(L, f);
|
||||
success = 1; /* always success */
|
||||
break;
|
||||
case 'w': /* word */
|
||||
success = read_word(L, f);
|
||||
break;
|
||||
default:
|
||||
luaL_argerror(L, n, "invalid format");
|
||||
success = 0; /* to avoid warnings */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
lua_pop(L, 1); /* remove last result */
|
||||
break; /* read fails */
|
||||
}
|
||||
} endloop:
|
||||
return n - firstarg;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
static int io_write (lua_State *L) {
|
||||
int lastarg = lua_gettop(L) - 1;
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
int arg = 1;
|
||||
int status = 1;
|
||||
FILE *f = gethandle(L, ctrl, arg);
|
||||
if (f) arg++;
|
||||
else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */
|
||||
for (; arg <= lastarg; arg++) {
|
||||
if (lua_type(L, arg) == LUA_TNUMBER) { /* LUA_NUMBER */
|
||||
/* optimization: could be done exactly as for strings */
|
||||
status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0;
|
||||
}
|
||||
else {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, arg, &l);
|
||||
status = status && (fwrite(s, sizeof(char), l, f) == l);
|
||||
}
|
||||
}
|
||||
pushresult(L, status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int io_seek (lua_State *L) {
|
||||
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
static const char *const modenames[] = {"set", "cur", "end", NULL};
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
FILE *f;
|
||||
int op;
|
||||
long offset;
|
||||
lua_pop(L, 1); /* remove upvalue */
|
||||
f = getnonullfile(L, ctrl, 1);
|
||||
op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames);
|
||||
offset = luaL_opt_long(L, 3, 0);
|
||||
luaL_arg_check(L, op != -1, 2, "invalid mode");
|
||||
op = fseek(f, offset, mode[op]);
|
||||
if (op)
|
||||
return pushresult(L, 0); /* error */
|
||||
else {
|
||||
lua_pushnumber(L, ftell(f));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int io_flush (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
|
||||
FILE *f;
|
||||
lua_pop(L, 1); /* remove upvalue */
|
||||
f = gethandle(L, ctrl, 1);
|
||||
luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle");
|
||||
return pushresult(L, fflush(f) == 0);
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Other O.S. Operations
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
static int io_execute (lua_State *L) {
|
||||
lua_pushnumber(L, system(luaL_check_string(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int io_remove (lua_State *L) {
|
||||
return pushresult(L, remove(luaL_check_string(L, 1)) == 0);
|
||||
}
|
||||
|
||||
|
||||
static int io_rename (lua_State *L) {
|
||||
return pushresult(L, rename(luaL_check_string(L, 1),
|
||||
luaL_check_string(L, 2)) == 0);
|
||||
}
|
||||
|
||||
|
||||
static int io_tmpname (lua_State *L) {
|
||||
lua_pushstring(L, tmpnam(NULL));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int io_getenv (lua_State *L) {
|
||||
lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int io_clock (lua_State *L) {
|
||||
lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int io_date (lua_State *L) {
|
||||
char b[256];
|
||||
const char *s = luaL_opt_string(L, 1, "%c");
|
||||
struct tm *stm;
|
||||
time_t t;
|
||||
time(&t); stm = localtime(&t);
|
||||
if (strftime(b, sizeof(b), s, stm))
|
||||
lua_pushstring(L, b);
|
||||
else
|
||||
lua_error(L, "invalid `date' format");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int setloc (lua_State *L) {
|
||||
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
|
||||
LC_NUMERIC, LC_TIME};
|
||||
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
|
||||
"numeric", "time", NULL};
|
||||
int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames);
|
||||
luaL_arg_check(L, op != -1, 2, "invalid option");
|
||||
lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int io_exit (lua_State *L) {
|
||||
exit(luaL_opt_int(L, 1, EXIT_SUCCESS));
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
static int io_debug (lua_State *L) {
|
||||
for (;;) {
|
||||
char buffer[250];
|
||||
fprintf(stderr, "lua_debug> ");
|
||||
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
|
||||
strcmp(buffer, "cont\n") == 0)
|
||||
return 0;
|
||||
lua_dostring(L, buffer);
|
||||
lua_settop(L, 0); /* remove eventual returns */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define LEVELS1 12 /* size of the first part of the stack */
|
||||
#define LEVELS2 10 /* size of the second part of the stack */
|
||||
|
||||
static int errorfb (lua_State *L) {
|
||||
int level = 1; /* skip level 0 (it's this function) */
|
||||
int firstpart = 1; /* still before eventual `...' */
|
||||
lua_Debug ar;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
luaL_addstring(&b, "error: ");
|
||||
luaL_addstring(&b, luaL_check_string(L, 1));
|
||||
luaL_addstring(&b, "\n");
|
||||
while (lua_getstack(L, level++, &ar)) {
|
||||
char buff[120]; /* enough to fit following `sprintf's */
|
||||
if (level == 2)
|
||||
luaL_addstring(&b, "stack traceback:\n");
|
||||
else if (level > LEVELS1 && firstpart) {
|
||||
/* no more than `LEVELS2' more levels? */
|
||||
if (!lua_getstack(L, level+LEVELS2, &ar))
|
||||
level--; /* keep going */
|
||||
else {
|
||||
luaL_addstring(&b, " ...\n"); /* too many levels */
|
||||
while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */
|
||||
level++;
|
||||
}
|
||||
firstpart = 0;
|
||||
continue;
|
||||
}
|
||||
sprintf(buff, "%4d: ", level-1);
|
||||
luaL_addstring(&b, buff);
|
||||
lua_getinfo(L, "Snl", &ar);
|
||||
switch (*ar.namewhat) {
|
||||
case 'g': case 'l': /* global, local */
|
||||
sprintf(buff, "function `%.50s'", ar.name);
|
||||
break;
|
||||
case 'f': /* field */
|
||||
sprintf(buff, "method `%.50s'", ar.name);
|
||||
break;
|
||||
case 't': /* tag method */
|
||||
sprintf(buff, "`%.50s' tag method", ar.name);
|
||||
break;
|
||||
default: {
|
||||
if (*ar.what == 'm') /* main? */
|
||||
sprintf(buff, "main of %.70s", ar.short_src);
|
||||
else if (*ar.what == 'C') /* C function? */
|
||||
sprintf(buff, "%.70s", ar.short_src);
|
||||
else
|
||||
sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src);
|
||||
ar.source = NULL; /* do not print source again */
|
||||
}
|
||||
}
|
||||
luaL_addstring(&b, buff);
|
||||
if (ar.currentline > 0) {
|
||||
sprintf(buff, " at line %d", ar.currentline);
|
||||
luaL_addstring(&b, buff);
|
||||
}
|
||||
if (ar.source) {
|
||||
sprintf(buff, " [%.70s]", ar.short_src);
|
||||
luaL_addstring(&b, buff);
|
||||
}
|
||||
luaL_addstring(&b, "\n");
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
lua_getglobal(L, LUA_ALERT);
|
||||
if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */
|
||||
lua_pushvalue(L, -2); /* error message */
|
||||
lua_rawcall(L, 1, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const struct luaL_reg iolib[] = {
|
||||
{LUA_ERRORMESSAGE, errorfb},
|
||||
{"clock", io_clock},
|
||||
{"date", io_date},
|
||||
{"debug", io_debug},
|
||||
{"execute", io_execute},
|
||||
{"exit", io_exit},
|
||||
{"getenv", io_getenv},
|
||||
{"remove", io_remove},
|
||||
{"rename", io_rename},
|
||||
{"setlocale", setloc},
|
||||
{"tmpname", io_tmpname}
|
||||
};
|
||||
|
||||
|
||||
static const struct luaL_reg iolibtag[] = {
|
||||
{"appendto", io_appendto},
|
||||
{"closefile", io_close},
|
||||
{"flush", io_flush},
|
||||
{"openfile", io_open},
|
||||
{"read", io_read},
|
||||
{"readfrom", io_readfrom},
|
||||
{"seek", io_seek},
|
||||
{"write", io_write},
|
||||
{"writeto", io_writeto}
|
||||
};
|
||||
|
||||
|
||||
static void openwithcontrol (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl));
|
||||
unsigned int i;
|
||||
ctrl->iotag = lua_newtag(L);
|
||||
ctrl->closedtag = lua_newtag(L);
|
||||
for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
|
||||
/* put `ctrl' as upvalue for these functions */
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushcclosure(L, iolibtag[i].func, 1);
|
||||
lua_setglobal(L, iolibtag[i].name);
|
||||
}
|
||||
/* create references to variable names */
|
||||
lua_pushstring(L, filenames[INFILE]);
|
||||
ctrl->ref[INFILE] = lua_ref(L, 1);
|
||||
lua_pushstring(L, filenames[OUTFILE]);
|
||||
ctrl->ref[OUTFILE] = lua_ref(L, 1);
|
||||
/* predefined file handles */
|
||||
setfile(L, ctrl, stdin, INFILE);
|
||||
setfile(L, ctrl, stdout, OUTFILE);
|
||||
setfilebyname(L, ctrl, stdin, "_STDIN");
|
||||
setfilebyname(L, ctrl, stdout, "_STDOUT");
|
||||
setfilebyname(L, ctrl, stderr, "_STDERR");
|
||||
/* close files when collected */
|
||||
lua_pushcclosure(L, file_collect, 1); /* pops `ctrl' from stack */
|
||||
lua_settagmethod(L, ctrl->iotag, "gc");
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void lua_iolibopen (lua_State *L) {
|
||||
luaL_openl(L, iolib);
|
||||
openwithcontrol(L);
|
||||
}
|
||||
|
@ -1,380 +0,0 @@
|
||||
/*
|
||||
** $Id: llex.c,v 1.1 2003/01/24 16:26:06 jason379 Exp $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "llex.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lparser.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "luadebug.h"
|
||||
#include "lzio.h"
|
||||
|
||||
|
||||
|
||||
#define next(LS) (LS->current = zgetc(LS->z))
|
||||
|
||||
|
||||
|
||||
/* ORDER RESERVED */
|
||||
static const char *const token2string [] = {
|
||||
"and", "break", "do", "else", "elseif", "end", "for",
|
||||
"function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
|
||||
"until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", "<eof>"};
|
||||
|
||||
|
||||
void luaX_init (lua_State *L) {
|
||||
int i;
|
||||
for (i=0; i<NUM_RESERVED; i++) {
|
||||
TString *ts = luaS_new(L, token2string[i]);
|
||||
ts->marked = (unsigned char)(RESERVEDMARK+i); /* reserved word */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MAXSRC 80
|
||||
|
||||
|
||||
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
|
||||
if (val > limit) {
|
||||
char buff[100];
|
||||
sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
|
||||
luaX_error(ls, buff, ls->t.token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
|
||||
char buff[MAXSRC];
|
||||
luaO_chunkid(buff, ls->source->str, sizeof(buff));
|
||||
luaO_verror(ls->L, "%.99s;\n last token read: `%.30s' at line %d in %.80s",
|
||||
s, token, ls->linenumber, buff);
|
||||
}
|
||||
|
||||
|
||||
void luaX_error (LexState *ls, const char *s, int token) {
|
||||
char buff[TOKEN_LEN];
|
||||
luaX_token2str(token, buff);
|
||||
if (buff[0] == '\0')
|
||||
luaX_syntaxerror(ls, s, ls->L->Mbuffer);
|
||||
else
|
||||
luaX_syntaxerror(ls, s, buff);
|
||||
}
|
||||
|
||||
|
||||
void luaX_token2str (int token, char *s) {
|
||||
if (token < 256) {
|
||||
s[0] = (char)token;
|
||||
s[1] = '\0';
|
||||
}
|
||||
else
|
||||
strcpy(s, token2string[token-FIRST_RESERVED]);
|
||||
}
|
||||
|
||||
|
||||
static void luaX_invalidchar (LexState *ls, int c) {
|
||||
char buff[8];
|
||||
sprintf(buff, "0x%02X", c);
|
||||
luaX_syntaxerror(ls, "invalid control char", buff);
|
||||
}
|
||||
|
||||
|
||||
static void inclinenumber (LexState *LS) {
|
||||
next(LS); /* skip '\n' */
|
||||
++LS->linenumber;
|
||||
luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
|
||||
}
|
||||
|
||||
|
||||
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
|
||||
LS->L = L;
|
||||
LS->lookahead.token = TK_EOS; /* no look-ahead token */
|
||||
LS->z = z;
|
||||
LS->fs = NULL;
|
||||
LS->linenumber = 1;
|
||||
LS->lastline = 1;
|
||||
LS->source = source;
|
||||
next(LS); /* read first char */
|
||||
if (LS->current == '#') {
|
||||
do { /* skip first line */
|
||||
next(LS);
|
||||
} while (LS->current != '\n' && LS->current != EOZ);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** =======================================================
|
||||
** LEXICAL ANALYZER
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
/* use Mbuffer to store names, literal strings and numbers */
|
||||
|
||||
#define EXTRABUFF 128
|
||||
#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \
|
||||
luaO_openspace(L, (len)+(n)+EXTRABUFF)
|
||||
|
||||
#define save(L, c, l) (L->Mbuffer[l++] = (char)c)
|
||||
#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS))
|
||||
|
||||
|
||||
static const char *readname (LexState *LS) {
|
||||
lua_State *L = LS->L;
|
||||
size_t l = 0;
|
||||
checkbuffer(L, 10, l);
|
||||
do {
|
||||
checkbuffer(L, 10, l);
|
||||
save_and_next(L, LS, l);
|
||||
} while (isalnum(LS->current) || LS->current == '_');
|
||||
save(L, '\0', l);
|
||||
return L->Mbuffer;
|
||||
}
|
||||
|
||||
|
||||
/* LUA_NUMBER */
|
||||
static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
|
||||
lua_State *L = LS->L;
|
||||
size_t l = 0;
|
||||
checkbuffer(L, 10, l);
|
||||
if (comma) save(L, '.', l);
|
||||
while (isdigit(LS->current)) {
|
||||
checkbuffer(L, 10, l);
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
if (LS->current == '.') {
|
||||
save_and_next(L, LS, l);
|
||||
if (LS->current == '.') {
|
||||
save_and_next(L, LS, l);
|
||||
save(L, '\0', l);
|
||||
luaX_error(LS, "ambiguous syntax"
|
||||
" (decimal point x string concatenation)", TK_NUMBER);
|
||||
}
|
||||
}
|
||||
while (isdigit(LS->current)) {
|
||||
checkbuffer(L, 10, l);
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
if (LS->current == 'e' || LS->current == 'E') {
|
||||
save_and_next(L, LS, l); /* read 'E' */
|
||||
if (LS->current == '+' || LS->current == '-')
|
||||
save_and_next(L, LS, l); /* optional exponent sign */
|
||||
while (isdigit(LS->current)) {
|
||||
checkbuffer(L, 10, l);
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
}
|
||||
save(L, '\0', l);
|
||||
if (!luaO_str2d(L->Mbuffer, &seminfo->r))
|
||||
luaX_error(LS, "malformed number", TK_NUMBER);
|
||||
}
|
||||
|
||||
|
||||
static void read_long_string (LexState *LS, SemInfo *seminfo) {
|
||||
lua_State *L = LS->L;
|
||||
int cont = 0;
|
||||
size_t l = 0;
|
||||
checkbuffer(L, 10, l);
|
||||
save(L, '[', l); /* save first '[' */
|
||||
save_and_next(L, LS, l); /* pass the second '[' */
|
||||
for (;;) {
|
||||
checkbuffer(L, 10, l);
|
||||
switch (LS->current) {
|
||||
case EOZ:
|
||||
save(L, '\0', l);
|
||||
luaX_error(LS, "unfinished long string", TK_STRING);
|
||||
break; /* to avoid warnings */
|
||||
case '[':
|
||||
save_and_next(L, LS, l);
|
||||
if (LS->current == '[') {
|
||||
cont++;
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
continue;
|
||||
case ']':
|
||||
save_and_next(L, LS, l);
|
||||
if (LS->current == ']') {
|
||||
if (cont == 0) goto endloop;
|
||||
cont--;
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
continue;
|
||||
case '\n':
|
||||
save(L, '\n', l);
|
||||
inclinenumber(LS);
|
||||
continue;
|
||||
default:
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
} endloop:
|
||||
save_and_next(L, LS, l); /* skip the second ']' */
|
||||
save(L, '\0', l);
|
||||
seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
|
||||
}
|
||||
|
||||
|
||||
static void read_string (LexState *LS, int del, SemInfo *seminfo) {
|
||||
lua_State *L = LS->L;
|
||||
size_t l = 0;
|
||||
checkbuffer(L, 10, l);
|
||||
save_and_next(L, LS, l);
|
||||
while (LS->current != del) {
|
||||
checkbuffer(L, 10, l);
|
||||
switch (LS->current) {
|
||||
case EOZ: case '\n':
|
||||
save(L, '\0', l);
|
||||
luaX_error(LS, "unfinished string", TK_STRING);
|
||||
break; /* to avoid warnings */
|
||||
case '\\':
|
||||
next(LS); /* do not save the '\' */
|
||||
switch (LS->current) {
|
||||
case 'a': save(L, '\a', l); next(LS); break;
|
||||
case 'b': save(L, '\b', l); next(LS); break;
|
||||
case 'f': save(L, '\f', l); next(LS); break;
|
||||
case 'n': save(L, '\n', l); next(LS); break;
|
||||
case 'r': save(L, '\r', l); next(LS); break;
|
||||
case 't': save(L, '\t', l); next(LS); break;
|
||||
case 'v': save(L, '\v', l); next(LS); break;
|
||||
case '\n': save(L, '\n', l); inclinenumber(LS); break;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9': {
|
||||
int c = 0;
|
||||
int i = 0;
|
||||
do {
|
||||
c = 10*c + (LS->current-'0');
|
||||
next(LS);
|
||||
} while (++i<3 && isdigit(LS->current));
|
||||
if (c != (unsigned char)c) {
|
||||
save(L, '\0', l);
|
||||
luaX_error(LS, "escape sequence too large", TK_STRING);
|
||||
}
|
||||
save(L, c, l);
|
||||
break;
|
||||
}
|
||||
default: /* handles \\, \", \', and \? */
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
save_and_next(L, LS, l);
|
||||
}
|
||||
}
|
||||
save_and_next(L, LS, l); /* skip delimiter */
|
||||
save(L, '\0', l);
|
||||
seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
|
||||
}
|
||||
|
||||
|
||||
int luaX_lex (LexState *LS, SemInfo *seminfo) {
|
||||
for (;;) {
|
||||
switch (LS->current) {
|
||||
|
||||
case ' ': case '\t': case '\r': /* `\r' to avoid problems with DOS */
|
||||
next(LS);
|
||||
continue;
|
||||
|
||||
case '\n':
|
||||
inclinenumber(LS);
|
||||
continue;
|
||||
|
||||
case '$':
|
||||
luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$');
|
||||
break;
|
||||
|
||||
case '-':
|
||||
next(LS);
|
||||
if (LS->current != '-') return '-';
|
||||
do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
|
||||
continue;
|
||||
|
||||
case '[':
|
||||
next(LS);
|
||||
if (LS->current != '[') return '[';
|
||||
else {
|
||||
read_long_string(LS, seminfo);
|
||||
return TK_STRING;
|
||||
}
|
||||
|
||||
case '=':
|
||||
next(LS);
|
||||
if (LS->current != '=') return '=';
|
||||
else { next(LS); return TK_EQ; }
|
||||
|
||||
case '<':
|
||||
next(LS);
|
||||
if (LS->current != '=') return '<';
|
||||
else { next(LS); return TK_LE; }
|
||||
|
||||
case '>':
|
||||
next(LS);
|
||||
if (LS->current != '=') return '>';
|
||||
else { next(LS); return TK_GE; }
|
||||
|
||||
case '~':
|
||||
next(LS);
|
||||
if (LS->current != '=') return '~';
|
||||
else { next(LS); return TK_NE; }
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
read_string(LS, LS->current, seminfo);
|
||||
return TK_STRING;
|
||||
|
||||
case '.':
|
||||
next(LS);
|
||||
if (LS->current == '.') {
|
||||
next(LS);
|
||||
if (LS->current == '.') {
|
||||
next(LS);
|
||||
return TK_DOTS; /* ... */
|
||||
}
|
||||
else return TK_CONCAT; /* .. */
|
||||
}
|
||||
else if (!isdigit(LS->current)) return '.';
|
||||
else {
|
||||
read_number(LS, 1, seminfo);
|
||||
return TK_NUMBER;
|
||||
}
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
read_number(LS, 0, seminfo);
|
||||
return TK_NUMBER;
|
||||
|
||||
case EOZ:
|
||||
return TK_EOS;
|
||||
|
||||
case '_': goto tname;
|
||||
|
||||
default:
|
||||
if (!isalpha(LS->current)) {
|
||||
int c = LS->current;
|
||||
if (iscntrl(c))
|
||||
luaX_invalidchar(LS, c);
|
||||
next(LS);
|
||||
return c;
|
||||
}
|
||||
tname: { /* identifier or reserved word */
|
||||
TString *ts = luaS_new(LS->L, readname(LS));
|
||||
if (ts->marked >= RESERVEDMARK) /* reserved word? */
|
||||
return ts->marked-RESERVEDMARK+FIRST_RESERVED;
|
||||
seminfo->ts = ts;
|
||||
return TK_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
** $Id: llex.h,v 1.1 2003/01/24 16:26:06 jason379 Exp $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef llex_h
|
||||
#define llex_h
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lzio.h"
|
||||
|
||||
|
||||
#define FIRST_RESERVED 257
|
||||
|
||||
/* maximum length of a reserved word (+1 for final 0) */
|
||||
#define TOKEN_LEN 15
|
||||
|
||||
|
||||
/*
|
||||
* WARNING: if you change the order of this enumeration,
|
||||
* grep "ORDER RESERVED"
|
||||
*/
|
||||
enum RESERVED {
|
||||
/* terminal symbols denoted by reserved words */
|
||||
TK_AND = FIRST_RESERVED, TK_BREAK,
|
||||
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_IF, TK_LOCAL,
|
||||
TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_UNTIL, TK_WHILE,
|
||||
/* other terminal symbols */
|
||||
TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
|
||||
TK_STRING, TK_EOS
|
||||
};
|
||||
|
||||
/* number of reserved words */
|
||||
#define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1))
|
||||
|
||||
|
||||
typedef union {
|
||||
Number r;
|
||||
TString *ts;
|
||||
} SemInfo; /* semantics information */
|
||||
|
||||
|
||||
typedef struct Token {
|
||||
int token;
|
||||
SemInfo seminfo;
|
||||
} Token;
|
||||
|
||||
|
||||
typedef struct LexState {
|
||||
int current; /* current character */
|
||||
Token t; /* current token */
|
||||
Token lookahead; /* look ahead token */
|
||||
struct FuncState *fs; /* `FuncState' is private to the parser */
|
||||
struct lua_State *L;
|
||||
struct zio *z; /* input stream */
|
||||
int linenumber; /* input line counter */
|
||||
int lastline; /* line of last token `consumed' */
|
||||
TString *source; /* current source name */
|
||||
} LexState;
|
||||
|
||||
|
||||
void luaX_init (lua_State *L);
|
||||
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
|
||||
int luaX_lex (LexState *LS, SemInfo *seminfo);
|
||||
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
|
||||
void luaX_syntaxerror (LexState *ls, const char *s, const char *token);
|
||||
void luaX_error (LexState *ls, const char *s, int token);
|
||||
void luaX_token2str (int token, char *s);
|
||||
|
||||
|
||||
#endif
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
** $Id: llimits.h,v 1.1 2003/01/24 16:26:06 jason379 Exp $
|
||||
** Limits, basic types, and some other "installation-dependent" definitions
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef llimits_h
|
||||
#define llimits_h
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** try to find number of bits in an integer
|
||||
*/
|
||||
#ifndef BITS_INT
|
||||
/* avoid overflows in comparison */
|
||||
#if INT_MAX-20 < 32760
|
||||
#define BITS_INT 16
|
||||
#else
|
||||
#if INT_MAX > 2147483640L
|
||||
/* machine has at least 32 bits */
|
||||
#define BITS_INT 32
|
||||
#else
|
||||
#error "you must define BITS_INT with number of bits in an integer"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Define the type `number' of Lua
|
||||
** GREP LUA_NUMBER to change that
|
||||
*/
|
||||
#ifndef LUA_NUM_TYPE
|
||||
#define LUA_NUM_TYPE double
|
||||
#endif
|
||||
|
||||
typedef LUA_NUM_TYPE Number;
|
||||
|
||||
/* function to convert a Number to a string */
|
||||
#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
|
||||
#define lua_number2str(s,n) sprintf((s), NUMBER_FMT, (n))
|
||||
|
||||
/* function to convert a string to a Number */
|
||||
#define lua_str2number(s,p) strtod((s), (p))
|
||||
|
||||
|
||||
|
||||
typedef unsigned long lint32; /* unsigned int with at least 32 bits */
|
||||
|
||||
|
||||
#define MAX_SIZET ((size_t)(~(size_t)0)-2)
|
||||
|
||||
|
||||
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
|
||||
|
||||
/*
|
||||
** conversion of pointer to int (for hashing only)
|
||||
** (the shift removes bits that are usually 0 because of alignment)
|
||||
*/
|
||||
#define IntPoint(p) (((unsigned long)(p)) >> 3)
|
||||
|
||||
|
||||
|
||||
#define MINPOWER2 4 /* minimum size for "growing" vectors */
|
||||
|
||||
|
||||
|
||||
#ifndef DEFAULT_STACK_SIZE
|
||||
#define DEFAULT_STACK_SIZE 1024
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* type to ensure maximum alignment */
|
||||
union L_Umaxalign { double d; char *s; long l; };
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** type for virtual-machine instructions
|
||||
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
|
||||
** For a very small machine, you may change that to 2 bytes (and adjust
|
||||
** the following limits accordingly)
|
||||
*/
|
||||
typedef unsigned long Instruction;
|
||||
|
||||
|
||||
/*
|
||||
** size and position of opcode arguments.
|
||||
** For an instruction with 2 bytes, size is 16, and size_b can be 5
|
||||
** (accordingly, size_u will be 10, and size_a will be 5)
|
||||
*/
|
||||
#define SIZE_INSTRUCTION 32
|
||||
#define SIZE_B 9
|
||||
|
||||
#define SIZE_OP 6
|
||||
#define SIZE_U (SIZE_INSTRUCTION-SIZE_OP)
|
||||
#define POS_U SIZE_OP
|
||||
#define POS_B SIZE_OP
|
||||
#define SIZE_A (SIZE_INSTRUCTION-(SIZE_OP+SIZE_B))
|
||||
#define POS_A (SIZE_OP+SIZE_B)
|
||||
|
||||
|
||||
/*
|
||||
** limits for opcode arguments.
|
||||
** we use (signed) int to manipulate most arguments,
|
||||
** so they must fit in BITS_INT-1 bits (-1 for sign)
|
||||
*/
|
||||
#if SIZE_U < BITS_INT-1
|
||||
#define MAXARG_U ((1<<SIZE_U)-1)
|
||||
#define MAXARG_S (MAXARG_U>>1) /* `S' is signed */
|
||||
#else
|
||||
#define MAXARG_U MAX_INT
|
||||
#define MAXARG_S MAX_INT
|
||||
#endif
|
||||
|
||||
#if SIZE_A < BITS_INT-1
|
||||
#define MAXARG_A ((1<<SIZE_A)-1)
|
||||
#else
|
||||
#define MAXARG_A MAX_INT
|
||||
#endif
|
||||
|
||||
#if SIZE_B < BITS_INT-1
|
||||
#define MAXARG_B ((1<<SIZE_B)-1)
|
||||
#else
|
||||
#define MAXARG_B MAX_INT
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum stack size in a function */
|
||||
#ifndef MAXSTACK
|
||||
#define MAXSTACK 250
|
||||
#endif
|
||||
|
||||
#if MAXSTACK > MAXARG_B
|
||||
#undef MAXSTACK
|
||||
#define MAXSTACK MAXARG_B
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum number of local variables */
|
||||
#ifndef MAXLOCALS
|
||||
#define MAXLOCALS 200 /* arbitrary limit (<MAXSTACK) */
|
||||
#endif
|
||||
#if MAXLOCALS>=MAXSTACK
|
||||
#undef MAXLOCALS
|
||||
#define MAXLOCALS (MAXSTACK-1)
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum number of upvalues */
|
||||
#ifndef MAXUPVALUES
|
||||
#define MAXUPVALUES 32 /* arbitrary limit (<=MAXARG_B) */
|
||||
#endif
|
||||
#if MAXUPVALUES>MAXARG_B
|
||||
#undef MAXUPVALUES
|
||||
#define MAXUPVALUES MAXARG_B
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum number of variables in the left side of an assignment */
|
||||
#ifndef MAXVARSLH
|
||||
#define MAXVARSLH 100 /* arbitrary limit (<MULT_RET) */
|
||||
#endif
|
||||
#if MAXVARSLH>=MULT_RET
|
||||
#undef MAXVARSLH
|
||||
#define MAXVARSLH (MULT_RET-1)
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum number of parameters in a function */
|
||||
#ifndef MAXPARAMS
|
||||
#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
|
||||
#endif
|
||||
#if MAXPARAMS>=MAXLOCALS
|
||||
#undef MAXPARAMS
|
||||
#define MAXPARAMS (MAXLOCALS-1)
|
||||
#endif
|
||||
|
||||
|
||||
/* number of list items to accumulate before a SETLIST instruction */
|
||||
#define LFIELDS_PER_FLUSH 64
|
||||
#if LFIELDS_PER_FLUSH>(MAXSTACK/4)
|
||||
#undef LFIELDS_PER_FLUSH
|
||||
#define LFIELDS_PER_FLUSH (MAXSTACK/4)
|
||||
#endif
|
||||
|
||||
/* number of record items to accumulate before a SETMAP instruction */
|
||||
/* (each item counts 2 elements on the stack: an index and a value) */
|
||||
#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2)
|
||||
|
||||
|
||||
/* maximum lookback to find a real constant (for code generation) */
|
||||
#ifndef LOOKBACKNUMS
|
||||
#define LOOKBACKNUMS 20 /* arbitrary constant */
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
@ -1,238 +0,0 @@
|
||||
/*
|
||||
** $Id: lmathlib.c,v 1.1 2003/04/23 12:16:05 jason379 Exp $
|
||||
** Standard mathematical library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
#undef PI
|
||||
#define PI (3.14159265358979323846)
|
||||
#define RADIANS_PER_DEGREE (PI/180.0)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** If you want Lua to operate in radians (instead of degrees),
|
||||
** define RADIANS
|
||||
*/
|
||||
#ifdef RADIANS
|
||||
#define FROMRAD(a) (a)
|
||||
#define TORAD(a) (a)
|
||||
#else
|
||||
#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
|
||||
#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
|
||||
#endif
|
||||
|
||||
|
||||
static int math_abs (lua_State *L) {
|
||||
lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_sin (lua_State *L) {
|
||||
lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_cos (lua_State *L) {
|
||||
lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_tan (lua_State *L) {
|
||||
lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_asin (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_acos (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_atan (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_atan2 (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_ceil (lua_State *L) {
|
||||
lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_floor (lua_State *L) {
|
||||
lua_pushnumber(L, floor(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_mod (lua_State *L) {
|
||||
lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_sqrt (lua_State *L) {
|
||||
lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_pow (lua_State *L) {
|
||||
lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_log (lua_State *L) {
|
||||
lua_pushnumber(L, log(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_log10 (lua_State *L) {
|
||||
lua_pushnumber(L, log10(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_exp (lua_State *L) {
|
||||
lua_pushnumber(L, exp(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_deg (lua_State *L) {
|
||||
lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_rad (lua_State *L) {
|
||||
lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int math_frexp (lua_State *L) {
|
||||
int e;
|
||||
lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e));
|
||||
lua_pushnumber(L, e);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int math_ldexp (lua_State *L) {
|
||||
lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int math_min (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
double dmin = luaL_check_number(L, 1);
|
||||
int i;
|
||||
for (i=2; i<=n; i++) {
|
||||
double d = luaL_check_number(L, i);
|
||||
if (d < dmin)
|
||||
dmin = d;
|
||||
}
|
||||
lua_pushnumber(L, dmin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int math_max (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
double dmax = luaL_check_number(L, 1);
|
||||
int i;
|
||||
for (i=2; i<=n; i++) {
|
||||
double d = luaL_check_number(L, i);
|
||||
if (d > dmax)
|
||||
dmax = d;
|
||||
}
|
||||
lua_pushnumber(L, dmax);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int math_random (lua_State *L) {
|
||||
/* the '%' avoids the (rare) case of r==1, and is needed also because on
|
||||
some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
|
||||
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
|
||||
switch (lua_gettop(L)) { /* check number of arguments */
|
||||
case 0: { /* no arguments */
|
||||
lua_pushnumber(L, r); /* Number between 0 and 1 */
|
||||
break;
|
||||
}
|
||||
case 1: { /* only upper limit */
|
||||
int u = luaL_check_int(L, 1);
|
||||
luaL_arg_check(L, 1<=u, 1, "interval is empty");
|
||||
lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */
|
||||
break;
|
||||
}
|
||||
case 2: { /* lower and upper limits */
|
||||
int l = luaL_check_int(L, 1);
|
||||
int u = luaL_check_int(L, 2);
|
||||
luaL_arg_check(L, l<=u, 2, "interval is empty");
|
||||
lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */
|
||||
break;
|
||||
}
|
||||
default: lua_error(L, "wrong number of arguments");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int math_randomseed (lua_State *L) {
|
||||
srand(luaL_check_int(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct luaL_reg mathlib[] = {
|
||||
{"abs", math_abs},
|
||||
{"sin", math_sin},
|
||||
{"cos", math_cos},
|
||||
{"tan", math_tan},
|
||||
{"asin", math_asin},
|
||||
{"acos", math_acos},
|
||||
{"atan", math_atan},
|
||||
{"atan2", math_atan2},
|
||||
{"ceil", math_ceil},
|
||||
{"floor", math_floor},
|
||||
{"mod", math_mod},
|
||||
{"frexp", math_frexp},
|
||||
{"ldexp", math_ldexp},
|
||||
{"sqrt", math_sqrt},
|
||||
{"min", math_min},
|
||||
{"max", math_max},
|
||||
{"log", math_log},
|
||||
{"log10", math_log10},
|
||||
{"exp", math_exp},
|
||||
{"deg", math_deg},
|
||||
{"rad", math_rad},
|
||||
{"random", math_random},
|
||||
{"randomseed", math_randomseed}
|
||||
};
|
||||
|
||||
/*
|
||||
** Open math library
|
||||
*/
|
||||
LUALIB_API void lua_mathlibopen (lua_State *L) {
|
||||
luaL_openl(L, mathlib);
|
||||
lua_pushcfunction(L, math_pow);
|
||||
lua_settagmethod(L, LUA_TNUMBER, "pow");
|
||||
lua_pushnumber(L, PI);
|
||||
lua_setglobal(L, "PI");
|
||||
}
|
||||
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
** $Id: lmem.c,v 1.1 2003/01/24 16:26:06 jason379 Exp $
|
||||
** Interface to Memory Manager
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "ldo.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
/*
|
||||
** {======================================================================
|
||||
** Controlled version for realloc.
|
||||
** =======================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#define realloc(b, s) debug_realloc(b, s)
|
||||
#define malloc(b) debug_realloc(NULL, b)
|
||||
#define free(b) debug_realloc(b, 0)
|
||||
|
||||
|
||||
/* ensures maximum alignment for HEADER */
|
||||
#define HEADER (sizeof(union L_Umaxalign))
|
||||
|
||||
#define MARKSIZE 16
|
||||
#define MARK 0x55 /* 01010101 (a nice pattern) */
|
||||
|
||||
|
||||
#define blocksize(b) ((unsigned long *)((char *)(b) - HEADER))
|
||||
|
||||
unsigned long memdebug_numblocks = 0;
|
||||
unsigned long memdebug_total = 0;
|
||||
unsigned long memdebug_maxmem = 0;
|
||||
unsigned long memdebug_memlimit = LONG_MAX;
|
||||
|
||||
|
||||
static void *checkblock (void *block) {
|
||||
unsigned long *b = blocksize(block);
|
||||
unsigned long size = *b;
|
||||
int i;
|
||||
for (i=0;i<MARKSIZE;i++)
|
||||
assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */
|
||||
memdebug_numblocks--;
|
||||
memdebug_total -= size;
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
static void freeblock (void *block) {
|
||||
if (block) {
|
||||
size_t size = *blocksize(block);
|
||||
block = checkblock(block);
|
||||
memset(block, -1, size+HEADER+MARKSIZE); /* erase block */
|
||||
(free)(block); /* free original block */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *debug_realloc (void *block, size_t size) {
|
||||
if (size == 0) {
|
||||
freeblock(block);
|
||||
return NULL;
|
||||
}
|
||||
else if (memdebug_total+size > memdebug_memlimit)
|
||||
return NULL; /* to test memory allocation errors */
|
||||
else {
|
||||
size_t realsize = HEADER+size+MARKSIZE;
|
||||
char *newblock = (char *)(malloc)(realsize); /* alloc a new block */
|
||||
int i;
|
||||
if (realsize < size) return NULL; /* overflow! */
|
||||
if (newblock == NULL) return NULL;
|
||||
if (block) {
|
||||
size_t oldsize = *blocksize(block);
|
||||
if (oldsize > size) oldsize = size;
|
||||
memcpy(newblock+HEADER, block, oldsize);
|
||||
freeblock(block); /* erase (and check) old copy */
|
||||
}
|
||||
memdebug_total += size;
|
||||
if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total;
|
||||
memdebug_numblocks++;
|
||||
*(unsigned long *)newblock = size;
|
||||
for (i=0;i<MARKSIZE;i++)
|
||||
*(newblock+HEADER+size+i) = (char)(MARK+i);
|
||||
return newblock+HEADER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* }====================================================================== */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Real ISO (ANSI) systems do not need these tests;
|
||||
** but some systems (Sun OS) are not that ISO...
|
||||
*/
|
||||
#ifdef OLD_ANSI
|
||||
#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
|
||||
#define free(b) if (b) (free)(b)
|
||||
#endif
|
||||
|
||||
|
||||
void *luaM_growaux (lua_State *L, void *block, size_t nelems,
|
||||
int inc, size_t size, const char *errormsg, size_t limit) {
|
||||
size_t newn = nelems+inc;
|
||||
if (nelems >= limit-inc) lua_error(L, errormsg);
|
||||
if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */
|
||||
(nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */
|
||||
return block; /* do not need to reallocate */
|
||||
else /* it crossed a power-of-2 boundary; grow to next power */
|
||||
return luaM_realloc(L, block, luaO_power2(newn)*size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** generic allocation routine.
|
||||
*/
|
||||
void *luaM_realloc (lua_State *L, void *block, lint32 size) {
|
||||
if (size == 0) {
|
||||
free(block); /* block may be NULL; that is OK for free */
|
||||
return NULL;
|
||||
}
|
||||
else if (size >= MAX_SIZET)
|
||||
lua_error(L, "memory allocation error: block too big");
|
||||
block = realloc(block, size);
|
||||
if (block == NULL) {
|
||||
if (L)
|
||||
luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */
|
||||
else return NULL; /* error before creating state! */
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
** $Id: lmem.h,v 1.1 2003/01/24 16:26:07 jason379 Exp $
|
||||
** Interface to Memory Manager
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lmem_h
|
||||
#define lmem_h
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "llimits.h"
|
||||
#include "lua.h"
|
||||
|
||||
void *luaM_realloc (lua_State *L, void *oldblock, lint32 size);
|
||||
void *luaM_growaux (lua_State *L, void *block, size_t nelems,
|
||||
int inc, size_t size, const char *errormsg,
|
||||
size_t limit);
|
||||
|
||||
#define luaM_free(L, b) luaM_realloc(L, (b), 0)
|
||||
#define luaM_malloc(L, t) luaM_realloc(L, NULL, (t))
|
||||
#define luaM_new(L, t) ((t *)luaM_malloc(L, sizeof(t)))
|
||||
#define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, (n)*(lint32)sizeof(t)))
|
||||
|
||||
#define luaM_growvector(L, v,nelems,inc,t,e,l) \
|
||||
((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l))
|
||||
|
||||
#define luaM_reallocvector(L, v,n,t) \
|
||||
((v)=(t *)luaM_realloc(L, v,(n)*(lint32)sizeof(t)))
|
||||
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
extern unsigned long memdebug_numblocks;
|
||||
extern unsigned long memdebug_total;
|
||||
extern unsigned long memdebug_maxmem;
|
||||
extern unsigned long memdebug_memlimit;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
** $Id: lobject.c,v 1.1 2003/01/24 16:26:09 jason379 Exp $
|
||||
** Some generic functions over Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
|
||||
|
||||
|
||||
const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
|
||||
|
||||
|
||||
const char *const luaO_typenames[] = {
|
||||
"userdata", "nil", "number", "string", "table", "function"
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** returns smaller power of 2 larger than `n' (minimum is MINPOWER2)
|
||||
*/
|
||||
lint32 luaO_power2 (lint32 n) {
|
||||
lint32 p = MINPOWER2;
|
||||
while (p<=n) p<<=1;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
int luaO_equalObj (const TObject *t1, const TObject *t2) {
|
||||
if (ttype(t1) != ttype(t2)) return 0;
|
||||
switch (ttype(t1)) {
|
||||
case LUA_TNUMBER:
|
||||
return nvalue(t1) == nvalue(t2);
|
||||
case LUA_TSTRING: case LUA_TUSERDATA:
|
||||
return tsvalue(t1) == tsvalue(t2);
|
||||
case LUA_TTABLE:
|
||||
return hvalue(t1) == hvalue(t2);
|
||||
case LUA_TFUNCTION:
|
||||
return clvalue(t1) == clvalue(t2);
|
||||
default:
|
||||
LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type");
|
||||
return 1; /* LUA_TNIL */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *luaO_openspace (lua_State *L, size_t n) {
|
||||
if (n > L->Mbuffsize) {
|
||||
luaM_reallocvector(L, L->Mbuffer, n, char);
|
||||
L->nblocks += (n - L->Mbuffsize)*sizeof(char);
|
||||
L->Mbuffsize = n;
|
||||
}
|
||||
return L->Mbuffer;
|
||||
}
|
||||
|
||||
|
||||
int luaO_str2d (const char *s, Number *result) { /* LUA_NUMBER */
|
||||
char *endptr;
|
||||
Number res = lua_str2number(s, &endptr);
|
||||
if (endptr == s) return 0; /* no conversion */
|
||||
while (isspace((unsigned char)*endptr)) endptr++;
|
||||
if (*endptr != '\0') return 0; /* invalid trailing characters? */
|
||||
*result = res;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* maximum length of a string format for `luaO_verror' */
|
||||
#define MAX_VERROR 280
|
||||
|
||||
/* this function needs to handle only '%d' and '%.XXs' formats */
|
||||
void luaO_verror (lua_State *L, const char *fmt, ...) {
|
||||
va_list argp;
|
||||
char buff[MAX_VERROR]; /* to hold formatted message */
|
||||
va_start(argp, fmt);
|
||||
vsprintf(buff, fmt, argp);
|
||||
va_end(argp);
|
||||
lua_error(L, buff);
|
||||
}
|
||||
|
||||
|
||||
void luaO_chunkid (char *out, const char *source, int bufflen) {
|
||||
if (*source == '=') {
|
||||
strncpy(out, source+1, bufflen); /* remove first char */
|
||||
out[bufflen-1] = '\0'; /* ensures null termination */
|
||||
}
|
||||
else {
|
||||
if (*source == '@') {
|
||||
int l;
|
||||
source++; /* skip the `@' */
|
||||
bufflen -= sizeof("file `...%s'");
|
||||
l = strlen(source);
|
||||
if (l>bufflen) {
|
||||
source += (l-bufflen); /* get last part of file name */
|
||||
sprintf(out, "file `...%.99s'", source);
|
||||
}
|
||||
else
|
||||
sprintf(out, "file `%.99s'", source);
|
||||
}
|
||||
else {
|
||||
int len = strcspn(source, "\n"); /* stop at first newline */
|
||||
bufflen -= sizeof("string \"%.*s...\"");
|
||||
if (len > bufflen) len = bufflen;
|
||||
if (source[len] != '\0') { /* must truncate? */
|
||||
strcpy(out, "string \"");
|
||||
out += strlen(out);
|
||||
strncpy(out, source, len);
|
||||
strcpy(out+len, "...\"");
|
||||
}
|
||||
else
|
||||
sprintf(out, "string \"%.99s\"", source);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
** $Id: lobject.h,v 1.1 2003/01/24 16:26:09 jason379 Exp $
|
||||
** Type definitions for Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lobject_h
|
||||
#define lobject_h
|
||||
|
||||
|
||||
#include "llimits.h"
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#define LUA_INTERNALERROR(s) assert(((void)s,0))
|
||||
#define LUA_ASSERT(c,s) assert(((void)s,(c)))
|
||||
#else
|
||||
#define LUA_INTERNALERROR(s) /* empty */
|
||||
#define LUA_ASSERT(c,s) /* empty */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
/* to avoid warnings, and make sure value is really unused */
|
||||
#define UNUSED(x) (x=0, (void)(x))
|
||||
#else
|
||||
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
|
||||
#endif
|
||||
|
||||
|
||||
/* mark for closures active in the stack */
|
||||
#define LUA_TMARK 6
|
||||
|
||||
|
||||
/* tags for values visible from Lua == first user-created tag */
|
||||
#define NUM_TAGS 6
|
||||
|
||||
|
||||
/* check whether `t' is a mark */
|
||||
#define is_T_MARK(t) ((t) == LUA_TMARK)
|
||||
|
||||
|
||||
typedef union {
|
||||
struct TString *ts; /* LUA_TSTRING, LUA_TUSERDATA */
|
||||
struct Closure *cl; /* LUA_TFUNCTION */
|
||||
struct Hash *a; /* LUA_TTABLE */
|
||||
struct CallInfo *i; /* LUA_TLMARK */
|
||||
Number n; /* LUA_TNUMBER */
|
||||
} Value;
|
||||
|
||||
|
||||
/* Macros to access values */
|
||||
#define ttype(o) ((o)->ttype)
|
||||
#define nvalue(o) ((o)->value.n)
|
||||
#define tsvalue(o) ((o)->value.ts)
|
||||
#define clvalue(o) ((o)->value.cl)
|
||||
#define hvalue(o) ((o)->value.a)
|
||||
#define infovalue(o) ((o)->value.i)
|
||||
#define svalue(o) (tsvalue(o)->str)
|
||||
|
||||
|
||||
typedef struct lua_TObject {
|
||||
int ttype;
|
||||
Value value;
|
||||
} TObject;
|
||||
|
||||
|
||||
/*
|
||||
** String headers for string table
|
||||
*/
|
||||
|
||||
/*
|
||||
** most `malloc' libraries allocate memory in blocks of 8 bytes. TSPACK
|
||||
** tries to make sizeof(TString) a multiple of this granularity, to reduce
|
||||
** waste of space.
|
||||
*/
|
||||
#define TSPACK ((int)sizeof(int))
|
||||
|
||||
typedef struct TString {
|
||||
union {
|
||||
struct { /* for strings */
|
||||
unsigned long hash;
|
||||
int constindex; /* hint to reuse constants */
|
||||
} s;
|
||||
struct { /* for userdata */
|
||||
int tag;
|
||||
void *value;
|
||||
} d;
|
||||
} u;
|
||||
size_t len;
|
||||
struct TString *nexthash; /* chain for hash table */
|
||||
int marked;
|
||||
char str[TSPACK]; /* variable length string!! must be the last field! */
|
||||
} TString;
|
||||
|
||||
|
||||
/*
|
||||
** Function Prototypes
|
||||
*/
|
||||
typedef struct Proto {
|
||||
Number *knum; /* Number numbers used by the function */
|
||||
int nknum; /* size of `knum' */
|
||||
struct TString **kstr; /* strings used by the function */
|
||||
int nkstr; /* size of `kstr' */
|
||||
struct Proto **kproto; /* functions defined inside the function */
|
||||
int nkproto; /* size of `kproto' */
|
||||
Instruction *code;
|
||||
int ncode; /* size of `code'; when 0 means an incomplete `Proto' */
|
||||
short numparams;
|
||||
short is_vararg;
|
||||
short maxstacksize;
|
||||
short marked;
|
||||
struct Proto *next;
|
||||
/* debug information */
|
||||
int *lineinfo; /* map from opcodes to source lines */
|
||||
int nlineinfo; /* size of `lineinfo' */
|
||||
int nlocvars;
|
||||
struct LocVar *locvars; /* information about local variables */
|
||||
int lineDefined;
|
||||
TString *source;
|
||||
} Proto;
|
||||
|
||||
|
||||
typedef struct LocVar {
|
||||
TString *varname;
|
||||
int startpc; /* first point where variable is active */
|
||||
int endpc; /* first point where variable is dead */
|
||||
} LocVar;
|
||||
|
||||
|
||||
/*
|
||||
** Closures
|
||||
*/
|
||||
typedef struct Closure {
|
||||
union {
|
||||
lua_CFunction c; /* C functions */
|
||||
struct Proto *l; /* Lua functions */
|
||||
} f;
|
||||
struct Closure *next;
|
||||
struct Closure *mark; /* marked closures (point to itself when not marked) */
|
||||
short isC; /* 0 for Lua functions, 1 for C functions */
|
||||
short nupvalues;
|
||||
TObject upvalue[1];
|
||||
} Closure;
|
||||
|
||||
|
||||
#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)
|
||||
|
||||
|
||||
typedef struct Node {
|
||||
TObject key;
|
||||
TObject val;
|
||||
struct Node *next; /* for chaining */
|
||||
} Node;
|
||||
|
||||
typedef struct Hash {
|
||||
Node *node;
|
||||
int htag;
|
||||
int size;
|
||||
Node *firstfree; /* this position is free; all positions after it are full */
|
||||
struct Hash *next;
|
||||
struct Hash *mark; /* marked tables (point to itself when not marked) */
|
||||
} Hash;
|
||||
|
||||
|
||||
/* unmarked tables and closures are represented by pointing `mark' to
|
||||
** themselves
|
||||
*/
|
||||
#define ismarked(x) ((x)->mark != (x))
|
||||
|
||||
|
||||
/*
|
||||
** informations about a call (for debugging)
|
||||
*/
|
||||
typedef struct CallInfo {
|
||||
struct Closure *func; /* function being called */
|
||||
const Instruction **pc; /* current pc of called function */
|
||||
int lastpc; /* last pc traced */
|
||||
int line; /* current line */
|
||||
int refi; /* current index in `lineinfo' */
|
||||
} CallInfo;
|
||||
|
||||
|
||||
extern const TObject luaO_nilobject;
|
||||
extern const char *const luaO_typenames[];
|
||||
|
||||
|
||||
#define luaO_typename(o) (luaO_typenames[ttype(o)])
|
||||
|
||||
|
||||
lint32 luaO_power2 (lint32 n);
|
||||
char *luaO_openspace (lua_State *L, size_t n);
|
||||
|
||||
int luaO_equalObj (const TObject *t1, const TObject *t2);
|
||||
int luaO_str2d (const char *s, Number *result);
|
||||
|
||||
void luaO_verror (lua_State *L, const char *fmt, ...);
|
||||
void luaO_chunkid (char *out, const char *source, int len);
|
||||
|
||||
|
||||
#endif
|
@ -1,168 +0,0 @@
|
||||
/*
|
||||
** $Id: lopcodes.h,v 1.1 2003/01/24 16:26:10 jason379 Exp $
|
||||
** Opcodes for Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lopcodes_h
|
||||
#define lopcodes_h
|
||||
|
||||
#include "llimits.h"
|
||||
|
||||
|
||||
/*===========================================================================
|
||||
We assume that instructions are unsigned numbers.
|
||||
All instructions have an opcode in the first 6 bits. Moreover,
|
||||
an instruction can have 0, 1, or 2 arguments. Instructions can
|
||||
have the following types:
|
||||
type 0: no arguments
|
||||
type 1: 1 unsigned argument in the higher bits (called `U')
|
||||
type 2: 1 signed argument in the higher bits (`S')
|
||||
type 3: 1st unsigned argument in the higher bits (`A')
|
||||
2nd unsigned argument in the middle bits (`B')
|
||||
|
||||
A signed argument is represented in excess K; that is, the number
|
||||
value is the unsigned value minus K. K is exactly the maximum value
|
||||
for that argument (so that -max is represented by 0, and +max is
|
||||
represented by 2*max), which is half the maximum for the corresponding
|
||||
unsigned argument.
|
||||
|
||||
The size of each argument is defined in `llimits.h'. The usual is an
|
||||
instruction with 32 bits, U arguments with 26 bits (32-6), B arguments
|
||||
with 9 bits, and A arguments with 17 bits (32-6-9). For small
|
||||
installations, the instruction size can be 16, so U has 10 bits,
|
||||
and A and B have 5 bits each.
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* creates a mask with `n' 1 bits at position `p' */
|
||||
#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
|
||||
|
||||
/* creates a mask with `n' 0 bits at position `p' */
|
||||
#define MASK0(n,p) (~MASK1(n,p))
|
||||
|
||||
/*
|
||||
** the following macros help to manipulate instructions
|
||||
*/
|
||||
|
||||
#define CREATE_0(o) ((Instruction)(o))
|
||||
#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0)))
|
||||
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o)))
|
||||
|
||||
#define CREATE_U(o,u) ((Instruction)(o) | ((Instruction)(u)<<POS_U))
|
||||
#define GETARG_U(i) ((int)((i)>>POS_U))
|
||||
#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \
|
||||
((Instruction)(u)<<POS_U)))
|
||||
|
||||
#define CREATE_S(o,s) CREATE_U((o),(s)+MAXARG_S)
|
||||
#define GETARG_S(i) (GETARG_U(i)-MAXARG_S)
|
||||
#define SETARG_S(i,s) SETARG_U((i),(s)+MAXARG_S)
|
||||
|
||||
|
||||
#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \
|
||||
| ((Instruction)(b)<<POS_B))
|
||||
#define GETARG_A(i) ((int)((i)>>POS_A))
|
||||
#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
|
||||
((Instruction)(a)<<POS_A)))
|
||||
#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0)))
|
||||
#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
|
||||
((Instruction)(b)<<POS_B)))
|
||||
|
||||
|
||||
/*
|
||||
** K = U argument used as index to `kstr'
|
||||
** J = S argument used as jump offset (relative to pc of next instruction)
|
||||
** L = unsigned argument used as index of local variable
|
||||
** N = U argument used as index to `knum'
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/*----------------------------------------------------------------------
|
||||
name args stack before stack after side effects
|
||||
------------------------------------------------------------------------*/
|
||||
OP_END,/* - - (return) no results */
|
||||
OP_RETURN,/* U v_n-v_x(at u) (return) returns v_x-v_n */
|
||||
|
||||
OP_CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */
|
||||
OP_TAILCALL,/* A B v_n-v_1 f(at a) (return) f(v1,...,v_n) */
|
||||
|
||||
OP_PUSHNIL,/* U - nil_1-nil_u */
|
||||
OP_POP,/* U a_u-a_1 - */
|
||||
|
||||
OP_PUSHINT,/* S - (Number)s */
|
||||
OP_PUSHSTRING,/* K - KSTR[k] */
|
||||
OP_PUSHNUM,/* N - KNUM[n] */
|
||||
OP_PUSHNEGNUM,/* N - -KNUM[n] */
|
||||
|
||||
OP_PUSHUPVALUE,/* U - Closure[u] */
|
||||
|
||||
OP_GETLOCAL,/* L - LOC[l] */
|
||||
OP_GETGLOBAL,/* K - VAR[KSTR[k]] */
|
||||
|
||||
OP_GETTABLE,/* - i t t[i] */
|
||||
OP_GETDOTTED,/* K t t[KSTR[k]] */
|
||||
OP_GETINDEXED,/* L t t[LOC[l]] */
|
||||
OP_PUSHSELF,/* K t t t[KSTR[k]] */
|
||||
|
||||
OP_CREATETABLE,/* U - newarray(size = u) */
|
||||
|
||||
OP_SETLOCAL,/* L x - LOC[l]=x */
|
||||
OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */
|
||||
OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */
|
||||
|
||||
OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */
|
||||
OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */
|
||||
|
||||
OP_ADD,/* - y x x+y */
|
||||
OP_ADDI,/* S x x+s */
|
||||
OP_SUB,/* - y x x-y */
|
||||
OP_MULT,/* - y x x*y */
|
||||
OP_DIV,/* - y x x/y */
|
||||
OP_POW,/* - y x x^y */
|
||||
OP_CONCAT,/* U v_u-v_1 v1..-..v_u */
|
||||
OP_MINUS,/* - x -x */
|
||||
OP_NOT,/* - x (x==nil)? 1 : nil */
|
||||
|
||||
OP_JMPNE,/* J y x - (x~=y)? PC+=s */
|
||||
OP_JMPEQ,/* J y x - (x==y)? PC+=s */
|
||||
OP_JMPLT,/* J y x - (x<y)? PC+=s */
|
||||
OP_JMPLE,/* J y x - (x<y)? PC+=s */
|
||||
OP_JMPGT,/* J y x - (x>y)? PC+=s */
|
||||
OP_JMPGE,/* J y x - (x>=y)? PC+=s */
|
||||
|
||||
OP_JMPT,/* J x - (x~=nil)? PC+=s */
|
||||
OP_JMPF,/* J x - (x==nil)? PC+=s */
|
||||
OP_JMPONT,/* J x (x~=nil)? x : - (x~=nil)? PC+=s */
|
||||
OP_JMPONF,/* J x (x==nil)? x : - (x==nil)? PC+=s */
|
||||
OP_JMP,/* J - - PC+=s */
|
||||
|
||||
OP_PUSHNILJMP,/* - - nil PC++; */
|
||||
|
||||
OP_FORPREP,/* J */
|
||||
OP_FORLOOP,/* J */
|
||||
|
||||
OP_LFORPREP,/* J */
|
||||
OP_LFORLOOP,/* J */
|
||||
|
||||
OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */
|
||||
|
||||
} OpCode;
|
||||
|
||||
#define NUM_OPCODES ((int)OP_CLOSURE+1)
|
||||
|
||||
|
||||
#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP)
|
||||
|
||||
|
||||
|
||||
/* special code to fit a LUA_MULTRET inside an argB */
|
||||
#define MULT_RET 255 /* (<=MAXARG_B) */
|
||||
#if MULT_RET>MAXARG_B
|
||||
#undef MULT_RET
|
||||
#define MULT_RET MAXARG_B
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,60 +0,0 @@
|
||||
/*
|
||||
** $Id: lparser.h,v 1.1 2003/01/24 16:26:12 jason379 Exp $
|
||||
** LL(1) Parser and code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lparser_h
|
||||
#define lparser_h
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lzio.h"
|
||||
|
||||
|
||||
/*
|
||||
** Expression descriptor
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
VGLOBAL,
|
||||
VLOCAL,
|
||||
VINDEXED,
|
||||
VEXP
|
||||
} expkind;
|
||||
|
||||
typedef struct expdesc {
|
||||
expkind k;
|
||||
union {
|
||||
int index; /* VGLOBAL: `kstr' index of global name; VLOCAL: stack index */
|
||||
struct {
|
||||
int t; /* patch list of `exit when true' */
|
||||
int f; /* patch list of `exit when false' */
|
||||
} l;
|
||||
} u;
|
||||
} expdesc;
|
||||
|
||||
|
||||
|
||||
/* state needed to generate code for a given function */
|
||||
typedef struct FuncState {
|
||||
Proto *f; /* current function header */
|
||||
struct FuncState *prev; /* enclosing function */
|
||||
struct LexState *ls; /* lexical state */
|
||||
struct lua_State *L; /* copy of the Lua state */
|
||||
int pc; /* next position to code */
|
||||
int lasttarget; /* `pc' of last `jump target' */
|
||||
int jlt; /* list of jumps to `lasttarget' */
|
||||
short stacklevel; /* number of values on activation register */
|
||||
short nactloc; /* number of active local variables */
|
||||
short nupvalues; /* number of upvalues */
|
||||
int lastline; /* line where last `lineinfo' was generated */
|
||||
struct Breaklabel *bl; /* chain of breakable blocks */
|
||||
expdesc upvalues[MAXUPVALUES]; /* upvalues */
|
||||
int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */
|
||||
} FuncState;
|
||||
|
||||
|
||||
Proto *luaY_parser (lua_State *L, ZIO *z);
|
||||
|
||||
|
||||
#endif
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
** $Id: lstate.c,v 1.1 2003/01/24 16:26:12 jason379 Exp $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "ldo.h"
|
||||
#include "lgc.h"
|
||||
#include "llex.h"
|
||||
#include "lmem.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
static lua_State *lua_state = NULL;
|
||||
void luaB_opentests (lua_State *L);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** built-in implementation for ERRORMESSAGE. In a "correct" environment
|
||||
** ERRORMESSAGE should have an external definition, and so this function
|
||||
** would not be used.
|
||||
*/
|
||||
static int errormessage (lua_State *L) {
|
||||
const char *s = lua_tostring(L, 1);
|
||||
if (s == NULL) s = "(no message)";
|
||||
fprintf(stderr, "error: %s\n", s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** open parts that may cause memory-allocation errors
|
||||
*/
|
||||
static void f_luaopen (lua_State *L, void *ud) {
|
||||
int stacksize = *(int *)ud;
|
||||
if (stacksize == 0)
|
||||
stacksize = DEFAULT_STACK_SIZE;
|
||||
else
|
||||
stacksize += LUA_MINSTACK;
|
||||
L->gt = luaH_new(L, 10); /* table of globals */
|
||||
luaD_init(L, stacksize);
|
||||
luaS_init(L);
|
||||
luaX_init(L);
|
||||
luaT_init(L);
|
||||
lua_newtable(L);
|
||||
lua_ref(L, 1); /* create registry */
|
||||
lua_register(L, LUA_ERRORMESSAGE, errormessage);
|
||||
#ifdef LUA_DEBUG
|
||||
luaB_opentests(L);
|
||||
if (lua_state == NULL) lua_state = L; /* keep first state to be opened */
|
||||
#endif
|
||||
LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack");
|
||||
}
|
||||
|
||||
|
||||
LUA_API lua_State *lua_open (int stacksize) {
|
||||
lua_State *L = luaM_new(NULL, lua_State);
|
||||
if (L == NULL) return NULL; /* memory allocation error */
|
||||
L->stack = NULL;
|
||||
L->strt.size = L->udt.size = 0;
|
||||
L->strt.nuse = L->udt.nuse = 0;
|
||||
L->strt.hash = NULL;
|
||||
L->udt.hash = NULL;
|
||||
L->Mbuffer = NULL;
|
||||
L->Mbuffsize = 0;
|
||||
L->rootproto = NULL;
|
||||
L->rootcl = NULL;
|
||||
L->roottable = NULL;
|
||||
L->TMtable = NULL;
|
||||
L->last_tag = -1;
|
||||
L->refArray = NULL;
|
||||
L->refSize = 0;
|
||||
L->refFree = NONEXT;
|
||||
L->nblocks = sizeof(lua_State);
|
||||
L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */
|
||||
L->callhook = NULL;
|
||||
L->linehook = NULL;
|
||||
L->allowhooks = 1;
|
||||
L->errorJmp = NULL;
|
||||
if (luaD_runprotected(L, f_luaopen, &stacksize) != 0) {
|
||||
/* memory allocation error: free partial state */
|
||||
lua_close(L);
|
||||
return NULL;
|
||||
}
|
||||
L->GCthreshold = 2*L->nblocks;
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_close (lua_State *L) {
|
||||
LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack");
|
||||
luaC_collect(L, 1); /* collect all elements */
|
||||
LUA_ASSERT(L->rootproto == NULL, "list should be empty");
|
||||
LUA_ASSERT(L->rootcl == NULL, "list should be empty");
|
||||
LUA_ASSERT(L->roottable == NULL, "list should be empty");
|
||||
luaS_freeall(L);
|
||||
if (L->stack)
|
||||
L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject);
|
||||
luaM_free(L, L->stack);
|
||||
L->nblocks -= (L->last_tag+1)*sizeof(struct TM);
|
||||
luaM_free(L, L->TMtable);
|
||||
L->nblocks -= (L->refSize)*sizeof(struct Ref);
|
||||
luaM_free(L, L->refArray);
|
||||
L->nblocks -= (L->Mbuffsize)*sizeof(char);
|
||||
luaM_free(L, L->Mbuffer);
|
||||
LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks");
|
||||
luaM_free(L, L);
|
||||
LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
|
||||
LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!");
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
** $Id: lstate.h,v 1.1 2003/01/24 16:26:12 jason379 Exp $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lstate_h
|
||||
#define lstate_h
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lua.h"
|
||||
#include "luadebug.h"
|
||||
|
||||
|
||||
|
||||
typedef TObject *StkId; /* index to stack elements */
|
||||
|
||||
|
||||
/*
|
||||
** marks for Reference array
|
||||
*/
|
||||
#define NONEXT -1 /* to end the free list */
|
||||
#define HOLD -2
|
||||
#define COLLECTED -3
|
||||
#define LOCK -4
|
||||
|
||||
|
||||
struct Ref {
|
||||
TObject o;
|
||||
int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
|
||||
};
|
||||
|
||||
|
||||
struct lua_longjmp; /* defined in ldo.c */
|
||||
struct TM; /* defined in ltm.h */
|
||||
|
||||
|
||||
typedef struct stringtable {
|
||||
int size;
|
||||
lint32 nuse; /* number of elements */
|
||||
TString **hash;
|
||||
} stringtable;
|
||||
|
||||
|
||||
|
||||
struct lua_State {
|
||||
/* thread-specific state */
|
||||
StkId top; /* first free slot in the stack */
|
||||
StkId stack; /* stack base */
|
||||
StkId stack_last; /* last free slot in the stack */
|
||||
int stacksize;
|
||||
StkId Cbase; /* base for current C function */
|
||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||
char *Mbuffer; /* global buffer */
|
||||
size_t Mbuffsize; /* size of Mbuffer */
|
||||
/* global state */
|
||||
Proto *rootproto; /* list of all prototypes */
|
||||
Closure *rootcl; /* list of all closures */
|
||||
Hash *roottable; /* list of all tables */
|
||||
stringtable strt; /* hash table for strings */
|
||||
stringtable udt; /* hash table for udata */
|
||||
Hash *gt; /* table for globals */
|
||||
struct TM *TMtable; /* table for tag methods */
|
||||
int last_tag; /* last used tag in TMtable */
|
||||
struct Ref *refArray; /* locked objects */
|
||||
int refSize; /* size of refArray */
|
||||
int refFree; /* list of free positions in refArray */
|
||||
unsigned long GCthreshold;
|
||||
unsigned long nblocks; /* number of `bytes' currently allocated */
|
||||
lua_Hook callhook;
|
||||
lua_Hook linehook;
|
||||
int allowhooks;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
** $Id: lstring.c,v 1.1 2003/01/24 16:26:12 jason379 Exp $
|
||||
** String table (keeps all strings handled by Lua)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
|
||||
|
||||
/*
|
||||
** type equivalent to TString, but with maximum alignment requirements
|
||||
*/
|
||||
union L_UTString {
|
||||
TString ts;
|
||||
union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
|
||||
};
|
||||
|
||||
|
||||
|
||||
void luaS_init (lua_State *L) {
|
||||
L->strt.hash = luaM_newvector(L, 1, TString *);
|
||||
L->udt.hash = luaM_newvector(L, 1, TString *);
|
||||
L->nblocks += 2*sizeof(TString *);
|
||||
L->strt.size = L->udt.size = 1;
|
||||
L->strt.nuse = L->udt.nuse = 0;
|
||||
L->strt.hash[0] = L->udt.hash[0] = NULL;
|
||||
}
|
||||
|
||||
|
||||
void luaS_freeall (lua_State *L) {
|
||||
LUA_ASSERT(L->strt.nuse==0, "non-empty string table");
|
||||
L->nblocks -= (L->strt.size + L->udt.size)*sizeof(TString *);
|
||||
luaM_free(L, L->strt.hash);
|
||||
LUA_ASSERT(L->udt.nuse==0, "non-empty udata table");
|
||||
luaM_free(L, L->udt.hash);
|
||||
}
|
||||
|
||||
|
||||
static unsigned long hash_s (const char *s, size_t l) {
|
||||
unsigned long h = l; /* seed */
|
||||
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
|
||||
for (; l>=step; l-=step)
|
||||
h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
|
||||
TString **newhash = luaM_newvector(L, newsize, TString *);
|
||||
int i;
|
||||
for (i=0; i<newsize; i++) newhash[i] = NULL;
|
||||
/* rehash */
|
||||
for (i=0; i<tb->size; i++) {
|
||||
TString *p = tb->hash[i];
|
||||
while (p) { /* for each node in the list */
|
||||
TString *next = p->nexthash; /* save next */
|
||||
unsigned long h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value);
|
||||
int h1 = h&(newsize-1); /* new position */
|
||||
LUA_ASSERT(h%newsize == (h&(newsize-1)),
|
||||
"a&(x-1) == a%x, for x power of 2");
|
||||
p->nexthash = newhash[h1]; /* chain it in new position */
|
||||
newhash[h1] = p;
|
||||
p = next;
|
||||
}
|
||||
}
|
||||
luaM_free(L, tb->hash);
|
||||
L->nblocks += (newsize - tb->size)*sizeof(TString *);
|
||||
tb->size = newsize;
|
||||
tb->hash = newhash;
|
||||
}
|
||||
|
||||
|
||||
static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) {
|
||||
ts->nexthash = tb->hash[h]; /* chain new entry */
|
||||
tb->hash[h] = ts;
|
||||
tb->nuse++;
|
||||
if (tb->nuse > (lint32)tb->size && tb->size < MAX_INT/2) /* too crowded? */
|
||||
luaS_resize(L, tb, tb->size*2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
||||
unsigned long h = hash_s(str, l);
|
||||
int h1 = h & (L->strt.size-1);
|
||||
TString *ts;
|
||||
for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) {
|
||||
if (ts->len == l && (memcmp(str, ts->str, l) == 0))
|
||||
return ts;
|
||||
}
|
||||
/* not found */
|
||||
ts = (TString *)luaM_malloc(L, sizestring(l));
|
||||
ts->marked = 0;
|
||||
ts->nexthash = NULL;
|
||||
ts->len = l;
|
||||
ts->u.s.hash = h;
|
||||
ts->u.s.constindex = 0;
|
||||
memcpy(ts->str, str, l);
|
||||
ts->str[l] = 0; /* ending 0 */
|
||||
L->nblocks += sizestring(l);
|
||||
newentry(L, &L->strt, ts, h1); /* insert it on table */
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
TString *luaS_newudata (lua_State *L, size_t s, void *udata) {
|
||||
union L_UTString *uts = (union L_UTString *)luaM_malloc(L,
|
||||
(lint32)sizeof(union L_UTString)+s);
|
||||
TString *ts = &uts->ts;
|
||||
ts->marked = 0;
|
||||
ts->nexthash = NULL;
|
||||
ts->len = s;
|
||||
ts->u.d.tag = 0;
|
||||
ts->u.d.value = (s > 0) ? uts+1 : udata;
|
||||
L->nblocks += sizestring(s);
|
||||
/* insert it on table */
|
||||
newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
TString *luaS_createudata (lua_State *L, void *udata, int tag) {
|
||||
int h1 = IntPoint(udata) & (L->udt.size-1);
|
||||
TString *ts;
|
||||
for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) {
|
||||
if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG))
|
||||
return ts;
|
||||
}
|
||||
/* not found */
|
||||
ts = luaS_newudata(L, 0, udata);
|
||||
if (tag != LUA_ANYTAG)
|
||||
ts->u.d.tag = tag;
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
TString *luaS_new (lua_State *L, const char *str) {
|
||||
return luaS_newlstr(L, str, strlen(str));
|
||||
}
|
||||
|
||||
|
||||
TString *luaS_newfixed (lua_State *L, const char *str) {
|
||||
TString *ts = luaS_new(L, str);
|
||||
if (ts->marked == 0) ts->marked = FIXMARK; /* avoid GC */
|
||||
return ts;
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
** $Id: lstring.h,v 1.1 2003/01/24 16:26:13 jason379 Exp $
|
||||
** String table (keep all strings handled by Lua)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lstring_h
|
||||
#define lstring_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
|
||||
|
||||
/*
|
||||
** any TString with mark>=FIXMARK is never collected.
|
||||
** Marks>=RESERVEDMARK are used to identify reserved words.
|
||||
*/
|
||||
#define FIXMARK 2
|
||||
#define RESERVEDMARK 3
|
||||
|
||||
|
||||
#define sizestring(l) ((long)sizeof(TString) + \
|
||||
((long)(l+1)-TSPACK)*(long)sizeof(char))
|
||||
|
||||
|
||||
void luaS_init (lua_State *L);
|
||||
void luaS_resize (lua_State *L, stringtable *tb, int newsize);
|
||||
TString *luaS_newudata (lua_State *L, size_t s, void *udata);
|
||||
TString *luaS_createudata (lua_State *L, void *udata, int tag);
|
||||
void luaS_freeall (lua_State *L);
|
||||
TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
|
||||
TString *luaS_new (lua_State *L, const char *str);
|
||||
TString *luaS_newfixed (lua_State *L, const char *str);
|
||||
|
||||
|
||||
#endif
|
@ -1,621 +0,0 @@
|
||||
/*
|
||||
** $Id: lstrlib.c,v 1.1 2003/04/23 12:16:05 jason379 Exp $
|
||||
** Standard library for string operations and pattern-matching
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
|
||||
static int str_len (lua_State *L) {
|
||||
size_t l;
|
||||
luaL_check_lstr(L, 1, &l);
|
||||
lua_pushnumber(L, l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static long posrelat (long pos, size_t len) {
|
||||
/* relative string position: negative means back from end */
|
||||
return (pos>=0) ? pos : (long)len+pos+1;
|
||||
}
|
||||
|
||||
|
||||
static int str_sub (lua_State *L) {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
long start = posrelat(luaL_check_long(L, 2), l);
|
||||
long end = posrelat(luaL_opt_long(L, 3, -1), l);
|
||||
if (start < 1) start = 1;
|
||||
if (end > (long)l) end = l;
|
||||
if (start <= end)
|
||||
lua_pushlstring(L, s+start-1, end-start+1);
|
||||
else lua_pushstring(L, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int str_lower (lua_State *L) {
|
||||
size_t l;
|
||||
size_t i;
|
||||
luaL_Buffer b;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
luaL_buffinit(L, &b);
|
||||
for (i=0; i<l; i++)
|
||||
luaL_putchar(&b, tolower((unsigned char)(s[i])));
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int str_upper (lua_State *L) {
|
||||
size_t l;
|
||||
size_t i;
|
||||
luaL_Buffer b;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
luaL_buffinit(L, &b);
|
||||
for (i=0; i<l; i++)
|
||||
luaL_putchar(&b, toupper((unsigned char)(s[i])));
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int str_rep (lua_State *L) {
|
||||
size_t l;
|
||||
luaL_Buffer b;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
int n = luaL_check_int(L, 2);
|
||||
luaL_buffinit(L, &b);
|
||||
while (n-- > 0)
|
||||
luaL_addlstring(&b, s, l);
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int str_byte (lua_State *L) {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
long pos = posrelat(luaL_opt_long(L, 2, 1), l);
|
||||
luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range");
|
||||
lua_pushnumber(L, (unsigned char)s[pos-1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int str_char (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
int i;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
for (i=1; i<=n; i++) {
|
||||
int c = luaL_check_int(L, i);
|
||||
luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
|
||||
luaL_putchar(&b, (unsigned char)c);
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** PATTERN MATCHING
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
#ifndef MAX_CAPTURES
|
||||
#define MAX_CAPTURES 32 /* arbitrary limit */
|
||||
#endif
|
||||
|
||||
|
||||
struct Capture {
|
||||
const char *src_end; /* end ('\0') of source string */
|
||||
int level; /* total number of captures (finished or unfinished) */
|
||||
struct {
|
||||
const char *init;
|
||||
long len; /* -1 signals unfinished capture */
|
||||
} capture[MAX_CAPTURES];
|
||||
};
|
||||
|
||||
|
||||
#define ESC '%'
|
||||
#define SPECIALS "^$*+?.([%-"
|
||||
|
||||
|
||||
static int check_capture (lua_State *L, int l, struct Capture *cap) {
|
||||
l -= '1';
|
||||
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
|
||||
lua_error(L, "invalid capture index");
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
static int capture_to_close (lua_State *L, struct Capture *cap) {
|
||||
int level = cap->level;
|
||||
for (level--; level>=0; level--)
|
||||
if (cap->capture[level].len == -1) return level;
|
||||
lua_error(L, "invalid pattern capture");
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
||||
|
||||
const char *luaI_classend (lua_State *L, const char *p) {
|
||||
switch (*p++) {
|
||||
case ESC:
|
||||
if (*p == '\0') lua_error(L, "malformed pattern (ends with `%')");
|
||||
return p+1;
|
||||
case '[':
|
||||
if (*p == '^') p++;
|
||||
do { /* look for a ']' */
|
||||
if (*p == '\0') lua_error(L, "malformed pattern (missing `]')");
|
||||
if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. '%]') */
|
||||
} while (*p != ']');
|
||||
return p+1;
|
||||
default:
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int match_class (int c, int cl) {
|
||||
int res;
|
||||
switch (tolower(cl)) {
|
||||
case 'a' : res = isalpha(c); break;
|
||||
case 'c' : res = iscntrl(c); break;
|
||||
case 'd' : res = isdigit(c); break;
|
||||
case 'l' : res = islower(c); break;
|
||||
case 'p' : res = ispunct(c); break;
|
||||
case 's' : res = isspace(c); break;
|
||||
case 'u' : res = isupper(c); break;
|
||||
case 'w' : res = isalnum(c); break;
|
||||
case 'x' : res = isxdigit(c); break;
|
||||
case 'z' : res = (c == '\0'); break;
|
||||
default: return (cl == c);
|
||||
}
|
||||
return (islower(cl) ? res : !res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int matchbracketclass (int c, const char *p, const char *endclass) {
|
||||
int sig = 1;
|
||||
if (*(p+1) == '^') {
|
||||
sig = 0;
|
||||
p++; /* skip the '^' */
|
||||
}
|
||||
while (++p < endclass) {
|
||||
if (*p == ESC) {
|
||||
p++;
|
||||
if (match_class(c, (unsigned char)*p))
|
||||
return sig;
|
||||
}
|
||||
else if ((*(p+1) == '-') && (p+2 < endclass)) {
|
||||
p+=2;
|
||||
if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
|
||||
return sig;
|
||||
}
|
||||
else if ((int)(unsigned char)*p == c) return sig;
|
||||
}
|
||||
return !sig;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int luaI_singlematch (int c, const char *p, const char *ep) {
|
||||
switch (*p) {
|
||||
case '.': /* matches any char */
|
||||
return 1;
|
||||
case ESC:
|
||||
return match_class(c, (unsigned char)*(p+1));
|
||||
case '[':
|
||||
return matchbracketclass(c, p, ep-1);
|
||||
default:
|
||||
return ((unsigned char)*p == c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *match (lua_State *L, const char *s, const char *p,
|
||||
struct Capture *cap);
|
||||
|
||||
|
||||
static const char *matchbalance (lua_State *L, const char *s, const char *p,
|
||||
struct Capture *cap) {
|
||||
if (*p == 0 || *(p+1) == 0)
|
||||
lua_error(L, "unbalanced pattern");
|
||||
if (*s != *p) return NULL;
|
||||
else {
|
||||
int b = *p;
|
||||
int e = *(p+1);
|
||||
int cont = 1;
|
||||
while (++s < cap->src_end) {
|
||||
if (*s == e) {
|
||||
if (--cont == 0) return s+1;
|
||||
}
|
||||
else if (*s == b) cont++;
|
||||
}
|
||||
}
|
||||
return NULL; /* string ends out of balance */
|
||||
}
|
||||
|
||||
|
||||
static const char *max_expand (lua_State *L, const char *s, const char *p,
|
||||
const char *ep, struct Capture *cap) {
|
||||
long i = 0; /* counts maximum expand for item */
|
||||
while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
|
||||
i++;
|
||||
/* keeps trying to match with the maximum repetitions */
|
||||
while (i>=0) {
|
||||
const char *res = match(L, (s+i), ep+1, cap);
|
||||
if (res) return res;
|
||||
i--; /* else didn't match; reduce 1 repetition to try again */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static const char *min_expand (lua_State *L, const char *s, const char *p,
|
||||
const char *ep, struct Capture *cap) {
|
||||
for (;;) {
|
||||
const char *res = match(L, s, ep+1, cap);
|
||||
if (res != NULL)
|
||||
return res;
|
||||
else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep))
|
||||
s++; /* try with one more repetition */
|
||||
else return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *start_capture (lua_State *L, const char *s, const char *p,
|
||||
struct Capture *cap) {
|
||||
const char *res;
|
||||
int level = cap->level;
|
||||
if (level >= MAX_CAPTURES) lua_error(L, "too many captures");
|
||||
cap->capture[level].init = s;
|
||||
cap->capture[level].len = -1;
|
||||
cap->level = level+1;
|
||||
if ((res=match(L, s, p+1, cap)) == NULL) /* match failed? */
|
||||
cap->level--; /* undo capture */
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static const char *end_capture (lua_State *L, const char *s, const char *p,
|
||||
struct Capture *cap) {
|
||||
int l = capture_to_close(L, cap);
|
||||
const char *res;
|
||||
cap->capture[l].len = s - cap->capture[l].init; /* close capture */
|
||||
if ((res = match(L, s, p+1, cap)) == NULL) /* match failed? */
|
||||
cap->capture[l].len = -1; /* undo capture */
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static const char *match_capture (lua_State *L, const char *s, int level,
|
||||
struct Capture *cap) {
|
||||
int l = check_capture(L, level, cap);
|
||||
size_t len = cap->capture[l].len;
|
||||
if ((size_t)(cap->src_end-s) >= len &&
|
||||
memcmp(cap->capture[l].init, s, len) == 0)
|
||||
return s+len;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
static const char *match (lua_State *L, const char *s, const char *p,
|
||||
struct Capture *cap) {
|
||||
init: /* using goto's to optimize tail recursion */
|
||||
switch (*p) {
|
||||
case '(': /* start capture */
|
||||
return start_capture(L, s, p, cap);
|
||||
case ')': /* end capture */
|
||||
return end_capture(L, s, p, cap);
|
||||
case ESC: /* may be %[0-9] or %b */
|
||||
if (isdigit((unsigned char)(*(p+1)))) { /* capture? */
|
||||
s = match_capture(L, s, *(p+1), cap);
|
||||
if (s == NULL) return NULL;
|
||||
p+=2; goto init; /* else return match(L, s, p+2, cap) */
|
||||
}
|
||||
else if (*(p+1) == 'b') { /* balanced string? */
|
||||
s = matchbalance(L, s, p+2, cap);
|
||||
if (s == NULL) return NULL;
|
||||
p+=4; goto init; /* else return match(L, s, p+4, cap); */
|
||||
}
|
||||
else goto dflt; /* case default */
|
||||
case '\0': /* end of pattern */
|
||||
return s; /* match succeeded */
|
||||
case '$':
|
||||
if (*(p+1) == '\0') /* is the '$' the last char in pattern? */
|
||||
return (s == cap->src_end) ? s : NULL; /* check end of string */
|
||||
else goto dflt;
|
||||
default: dflt: { /* it is a pattern item */
|
||||
const char *ep = luaI_classend(L, p); /* points to what is next */
|
||||
int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep);
|
||||
switch (*ep) {
|
||||
case '?': { /* optional */
|
||||
const char *res;
|
||||
if (m && ((res=match(L, s+1, ep+1, cap)) != NULL))
|
||||
return res;
|
||||
p=ep+1; goto init; /* else return match(L, s, ep+1, cap); */
|
||||
}
|
||||
case '*': /* 0 or more repetitions */
|
||||
return max_expand(L, s, p, ep, cap);
|
||||
case '+': /* 1 or more repetitions */
|
||||
return (m ? max_expand(L, s+1, p, ep, cap) : NULL);
|
||||
case '-': /* 0 or more repetitions (minimum) */
|
||||
return min_expand(L, s, p, ep, cap);
|
||||
default:
|
||||
if (!m) return NULL;
|
||||
s++; p=ep; goto init; /* else return match(L, s+1, ep, cap); */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *lmemfind (const char *s1, size_t l1,
|
||||
const char *s2, size_t l2) {
|
||||
if (l2 == 0) return s1; /* empty strings are everywhere */
|
||||
else if (l2 > l1) return NULL; /* avoids a negative `l1' */
|
||||
else {
|
||||
const char *init; /* to search for a `*s2' inside `s1' */
|
||||
l2--; /* 1st char will be checked by `memchr' */
|
||||
l1 = l1-l2; /* `s2' cannot be found after that */
|
||||
while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
|
||||
init++; /* 1st char is already checked */
|
||||
if (memcmp(init, s2+1, l2) == 0)
|
||||
return init-1;
|
||||
else { /* correct `l1' and `s1' to try again */
|
||||
l1 -= init-s1;
|
||||
s1 = init;
|
||||
}
|
||||
}
|
||||
return NULL; /* not found */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int push_captures (lua_State *L, struct Capture *cap) {
|
||||
int i;
|
||||
luaL_checkstack(L, cap->level, "too many captures");
|
||||
for (i=0; i<cap->level; i++) {
|
||||
int l = cap->capture[i].len;
|
||||
if (l == -1) lua_error(L, "unfinished capture");
|
||||
lua_pushlstring(L, cap->capture[i].init, l);
|
||||
}
|
||||
return cap->level; /* number of strings pushed */
|
||||
}
|
||||
|
||||
|
||||
static int str_find (lua_State *L) {
|
||||
size_t l1, l2;
|
||||
const char *s = luaL_check_lstr(L, 1, &l1);
|
||||
const char *p = luaL_check_lstr(L, 2, &l2);
|
||||
long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1;
|
||||
struct Capture cap;
|
||||
luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range");
|
||||
if (lua_gettop(L) > 3 || /* extra argument? */
|
||||
strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
|
||||
const char *s2 = lmemfind(s+init, l1-init, p, l2);
|
||||
if (s2) {
|
||||
lua_pushnumber(L, s2-s+1);
|
||||
lua_pushnumber(L, s2-s+l2);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int anchor = (*p == '^') ? (p++, 1) : 0;
|
||||
const char *s1=s+init;
|
||||
cap.src_end = s+l1;
|
||||
do {
|
||||
const char *res;
|
||||
cap.level = 0;
|
||||
if ((res=match(L, s1, p, &cap)) != NULL) {
|
||||
lua_pushnumber(L, s1-s+1); /* start */
|
||||
lua_pushnumber(L, res-s); /* end */
|
||||
return push_captures(L, &cap) + 2;
|
||||
}
|
||||
} while (s1++<cap.src_end && !anchor);
|
||||
}
|
||||
lua_pushnil(L); /* not found */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) {
|
||||
if (lua_isstring(L, 3)) {
|
||||
const char *news = lua_tostring(L, 3);
|
||||
size_t l = lua_strlen(L, 3);
|
||||
size_t i;
|
||||
for (i=0; i<l; i++) {
|
||||
if (news[i] != ESC)
|
||||
luaL_putchar(b, news[i]);
|
||||
else {
|
||||
i++; /* skip ESC */
|
||||
if (!isdigit((unsigned char)news[i]))
|
||||
luaL_putchar(b, news[i]);
|
||||
else {
|
||||
int level = check_capture(L, news[i], cap);
|
||||
luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* is a function */
|
||||
int n;
|
||||
lua_pushvalue(L, 3);
|
||||
n = push_captures(L, cap);
|
||||
lua_rawcall(L, n, 1);
|
||||
if (lua_isstring(L, -1))
|
||||
luaL_addvalue(b); /* add return to accumulated result */
|
||||
else
|
||||
lua_pop(L, 1); /* function result is not a string: pop it */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int str_gsub (lua_State *L) {
|
||||
size_t srcl;
|
||||
const char *src = luaL_check_lstr(L, 1, &srcl);
|
||||
const char *p = luaL_check_string(L, 2);
|
||||
int max_s = luaL_opt_int(L, 4, srcl+1);
|
||||
int anchor = (*p == '^') ? (p++, 1) : 0;
|
||||
int n = 0;
|
||||
struct Capture cap;
|
||||
luaL_Buffer b;
|
||||
luaL_arg_check(L,
|
||||
lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
|
||||
3, "string or function expected");
|
||||
luaL_buffinit(L, &b);
|
||||
cap.src_end = src+srcl;
|
||||
while (n < max_s) {
|
||||
const char *e;
|
||||
cap.level = 0;
|
||||
e = match(L, src, p, &cap);
|
||||
if (e) {
|
||||
n++;
|
||||
add_s(L, &b, &cap);
|
||||
}
|
||||
if (e && e>src) /* non empty match? */
|
||||
src = e; /* skip it */
|
||||
else if (src < cap.src_end)
|
||||
luaL_putchar(&b, *src++);
|
||||
else break;
|
||||
if (anchor) break;
|
||||
}
|
||||
luaL_addlstring(&b, src, cap.src_end-src);
|
||||
luaL_pushresult(&b);
|
||||
lua_pushnumber(L, n); /* number of substitutions */
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, arg, &l);
|
||||
luaL_putchar(b, '"');
|
||||
while (l--) {
|
||||
switch (*s) {
|
||||
case '"': case '\\': case '\n':
|
||||
luaL_putchar(b, '\\');
|
||||
luaL_putchar(b, *s);
|
||||
break;
|
||||
case '\0': luaL_addlstring(b, "\\000", 4); break;
|
||||
default: luaL_putchar(b, *s);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
luaL_putchar(b, '"');
|
||||
}
|
||||
|
||||
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
|
||||
#define MAX_ITEM 512
|
||||
/* maximum size of each format specification (such as '%-099.99d') */
|
||||
#define MAX_FORMAT 20
|
||||
|
||||
static int str_format (lua_State *L) {
|
||||
int arg = 1;
|
||||
const char *strfrmt = luaL_check_string(L, arg);
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
while (*strfrmt) {
|
||||
if (*strfrmt != '%')
|
||||
luaL_putchar(&b, *strfrmt++);
|
||||
else if (*++strfrmt == '%')
|
||||
luaL_putchar(&b, *strfrmt++); /* %% */
|
||||
else { /* format item */
|
||||
struct Capture cap;
|
||||
char form[MAX_FORMAT]; /* to store the format ('%...') */
|
||||
char buff[MAX_ITEM]; /* to store the formatted item */
|
||||
const char *initf = strfrmt;
|
||||
form[0] = '%';
|
||||
if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
|
||||
arg = *initf - '0';
|
||||
initf += 2; /* skip the 'n$' */
|
||||
}
|
||||
arg++;
|
||||
cap.src_end = strfrmt+strlen(strfrmt)+1;
|
||||
cap.level = 0;
|
||||
strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
|
||||
if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
|
||||
strfrmt-initf > MAX_FORMAT-2)
|
||||
lua_error(L, "invalid format (width or precision too long)");
|
||||
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
|
||||
form[strfrmt-initf+2] = 0;
|
||||
switch (*strfrmt++) {
|
||||
case 'c': case 'd': case 'i':
|
||||
sprintf(buff, form, luaL_check_int(L, arg));
|
||||
break;
|
||||
case 'o': case 'u': case 'x': case 'X':
|
||||
sprintf(buff, form, (unsigned int)luaL_check_number(L, arg));
|
||||
break;
|
||||
case 'e': case 'E': case 'f': case 'g': case 'G':
|
||||
sprintf(buff, form, luaL_check_number(L, arg));
|
||||
break;
|
||||
case 'q':
|
||||
luaI_addquoted(L, &b, arg);
|
||||
continue; /* skip the "addsize" at the end */
|
||||
case 's': {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, arg, &l);
|
||||
if (cap.capture[1].len == 0 && l >= 100) {
|
||||
/* no precision and string is too long to be formatted;
|
||||
keep original string */
|
||||
lua_pushvalue(L, arg);
|
||||
luaL_addvalue(&b);
|
||||
continue; /* skip the "addsize" at the end */
|
||||
}
|
||||
else {
|
||||
sprintf(buff, form, s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default: /* also treat cases 'pnLlh' */
|
||||
lua_error(L, "invalid option in `format'");
|
||||
}
|
||||
luaL_addlstring(&b, buff, strlen(buff));
|
||||
}
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const struct luaL_reg strlib[] = {
|
||||
{"strlen", str_len},
|
||||
{"strsub", str_sub},
|
||||
{"strlower", str_lower},
|
||||
{"strupper", str_upper},
|
||||
{"strchar", str_char},
|
||||
{"strrep", str_rep},
|
||||
{"ascii", str_byte}, /* for compatibility with 3.0 and earlier */
|
||||
{"strbyte", str_byte},
|
||||
{"format", str_format},
|
||||
{"strfind", str_find},
|
||||
{"gsub", str_gsub}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Open string library
|
||||
*/
|
||||
LUALIB_API void lua_strlibopen (lua_State *L) {
|
||||
luaL_openl(L, strlib);
|
||||
}
|
@ -1,303 +0,0 @@
|
||||
/*
|
||||
** $Id: ltable.c,v 1.1 2003/01/24 16:26:13 jason379 Exp $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** Implementation of tables (aka arrays, objects, or hash tables);
|
||||
** uses a mix of chained scatter table with Brent's variation.
|
||||
** A main invariant of these tables is that, if an element is not
|
||||
** in its main position (i.e. the `original' position that its hash gives
|
||||
** to it), then the colliding element is in its own main position.
|
||||
** In other words, there are collisions only when two elements have the
|
||||
** same main position (i.e. the same hash values for that table size).
|
||||
** Because of that, the load factor of these tables can be 100% without
|
||||
** performance penalties.
|
||||
*/
|
||||
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
|
||||
|
||||
#define gcsize(L, n) (sizeof(Hash)+(n)*sizeof(Node))
|
||||
|
||||
|
||||
|
||||
#define TagDefault LUA_TTABLE
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** returns the `main' position of an element in a table (that is, the index
|
||||
** of its hash value)
|
||||
*/
|
||||
Node *luaH_mainposition (const Hash *t, const TObject *key) {
|
||||
unsigned long h;
|
||||
switch (ttype(key)) {
|
||||
case LUA_TNUMBER:
|
||||
h = (unsigned long)(long)nvalue(key);
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
h = tsvalue(key)->u.s.hash;
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
h = IntPoint(tsvalue(key));
|
||||
break;
|
||||
case LUA_TTABLE:
|
||||
h = IntPoint(hvalue(key));
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
h = IntPoint(clvalue(key));
|
||||
break;
|
||||
default:
|
||||
return NULL; /* invalid key */
|
||||
}
|
||||
LUA_ASSERT(h%(unsigned int)t->size == (h&((unsigned int)t->size-1)),
|
||||
"a&(x-1) == a%x, for x power of 2");
|
||||
return &t->node[h&(t->size-1)];
|
||||
}
|
||||
|
||||
|
||||
static const TObject *luaH_getany (lua_State *L, const Hash *t,
|
||||
const TObject *key) {
|
||||
Node *n = luaH_mainposition(t, key);
|
||||
if (!n)
|
||||
lua_error(L, "table index is nil");
|
||||
else do {
|
||||
if (luaO_equalObj(key, &n->key))
|
||||
return &n->val;
|
||||
n = n->next;
|
||||
} while (n);
|
||||
return &luaO_nilobject; /* key not found */
|
||||
}
|
||||
|
||||
|
||||
/* specialized version for numbers */
|
||||
const TObject *luaH_getnum (const Hash *t, Number key) {
|
||||
Node *n = &t->node[(unsigned long)(long)key&(t->size-1)];
|
||||
do {
|
||||
if (ttype(&n->key) == LUA_TNUMBER && nvalue(&n->key) == key)
|
||||
return &n->val;
|
||||
n = n->next;
|
||||
} while (n);
|
||||
return &luaO_nilobject; /* key not found */
|
||||
}
|
||||
|
||||
|
||||
/* specialized version for strings */
|
||||
const TObject *luaH_getstr (const Hash *t, TString *key) {
|
||||
Node *n = &t->node[key->u.s.hash&(t->size-1)];
|
||||
do {
|
||||
if (ttype(&n->key) == LUA_TSTRING && tsvalue(&n->key) == key)
|
||||
return &n->val;
|
||||
n = n->next;
|
||||
} while (n);
|
||||
return &luaO_nilobject; /* key not found */
|
||||
}
|
||||
|
||||
|
||||
const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) {
|
||||
switch (ttype(key)) {
|
||||
case LUA_TNUMBER: return luaH_getnum(t, nvalue(key));
|
||||
case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
|
||||
default: return luaH_getany(L, t, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
|
||||
int i;
|
||||
if (ttype(key) == LUA_TNIL)
|
||||
i = 0; /* first iteration */
|
||||
else {
|
||||
const TObject *v = luaH_get(L, t, key);
|
||||
if (v == &luaO_nilobject)
|
||||
lua_error(L, "invalid key for `next'");
|
||||
i = (int)(((const char *)v -
|
||||
(const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
|
||||
}
|
||||
for (; i<t->size; i++) {
|
||||
Node *n = node(t, i);
|
||||
if (ttype(val(n)) != LUA_TNIL)
|
||||
return n;
|
||||
}
|
||||
return NULL; /* no more elements */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** try to remove a key without value from a table. To avoid problems with
|
||||
** hash, change `key' for a number with the same hash.
|
||||
*/
|
||||
void luaH_remove (Hash *t, TObject *key) {
|
||||
if (ttype(key) == LUA_TNUMBER ||
|
||||
(ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30))
|
||||
return; /* do not remove numbers nor small strings */
|
||||
else {
|
||||
/* try to find a number `n' with the same hash as `key' */
|
||||
Node *mp = luaH_mainposition(t, key);
|
||||
int n = mp - &t->node[0];
|
||||
/* make sure `n' is not in `t' */
|
||||
while (luaH_getnum(t, n) != &luaO_nilobject) {
|
||||
if (n >= MAX_INT - t->size)
|
||||
return; /* give up; (to avoid overflow) */
|
||||
n += t->size;
|
||||
}
|
||||
ttype(key) = LUA_TNUMBER;
|
||||
nvalue(key) = n;
|
||||
LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void setnodevector (lua_State *L, Hash *t, lint32 size) {
|
||||
int i;
|
||||
if (size > MAX_INT)
|
||||
lua_error(L, "table overflow");
|
||||
t->node = luaM_newvector(L, size, Node);
|
||||
for (i=0; i<(int)size; i++) {
|
||||
ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL;
|
||||
t->node[i].next = NULL;
|
||||
}
|
||||
L->nblocks += gcsize(L, size) - gcsize(L, t->size);
|
||||
t->size = size;
|
||||
t->firstfree = &t->node[size-1]; /* first free position to be used */
|
||||
}
|
||||
|
||||
|
||||
Hash *luaH_new (lua_State *L, int size) {
|
||||
Hash *t = luaM_new(L, Hash);
|
||||
t->htag = TagDefault;
|
||||
t->next = L->roottable;
|
||||
L->roottable = t;
|
||||
t->mark = t;
|
||||
t->size = 0;
|
||||
L->nblocks += gcsize(L, 0);
|
||||
t->node = NULL;
|
||||
setnodevector(L, t, luaO_power2(size));
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void luaH_free (lua_State *L, Hash *t) {
|
||||
L->nblocks -= gcsize(L, t->size);
|
||||
luaM_free(L, t->node);
|
||||
luaM_free(L, t);
|
||||
}
|
||||
|
||||
|
||||
static int numuse (const Hash *t) {
|
||||
Node *v = t->node;
|
||||
int size = t->size;
|
||||
int realuse = 0;
|
||||
int i;
|
||||
for (i=0; i<size; i++) {
|
||||
if (ttype(&v[i].val) != LUA_TNIL)
|
||||
realuse++;
|
||||
}
|
||||
return realuse;
|
||||
}
|
||||
|
||||
|
||||
static void rehash (lua_State *L, Hash *t) {
|
||||
int oldsize = t->size;
|
||||
Node *nold = t->node;
|
||||
int nelems = numuse(t);
|
||||
int i;
|
||||
LUA_ASSERT(nelems<=oldsize, "wrong count");
|
||||
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
|
||||
setnodevector(L, t, (lint32)oldsize*2);
|
||||
else if (nelems <= oldsize/4 && /* less than 1/4? */
|
||||
oldsize > MINPOWER2)
|
||||
setnodevector(L, t, oldsize/2);
|
||||
else
|
||||
setnodevector(L, t, oldsize);
|
||||
for (i=0; i<oldsize; i++) {
|
||||
Node *old = nold+i;
|
||||
if (ttype(&old->val) != LUA_TNIL)
|
||||
*luaH_set(L, t, &old->key) = old->val;
|
||||
}
|
||||
luaM_free(L, nold); /* free old array */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** inserts a key into a hash table; first, check whether key is
|
||||
** already present; if not, check whether key's main position is free;
|
||||
** if not, check whether colliding node is in its main position or not;
|
||||
** if it is not, move colliding node to an empty place and put new key
|
||||
** in its main position; otherwise (colliding node is in its main position),
|
||||
** new key goes to an empty position.
|
||||
*/
|
||||
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
|
||||
Node *mp = luaH_mainposition(t, key);
|
||||
Node *n = mp;
|
||||
if (!mp)
|
||||
lua_error(L, "table index is nil");
|
||||
do { /* check whether `key' is somewhere in the chain */
|
||||
if (luaO_equalObj(key, &n->key))
|
||||
return &n->val; /* that's all */
|
||||
else n = n->next;
|
||||
} while (n);
|
||||
/* `key' not found; must insert it */
|
||||
if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */
|
||||
Node *othern; /* main position of colliding node */
|
||||
n = t->firstfree; /* get a free place */
|
||||
/* is colliding node out of its main position? (can only happens if
|
||||
its position is after "firstfree") */
|
||||
if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) {
|
||||
/* yes; move colliding node into free position */
|
||||
while (othern->next != mp) othern = othern->next; /* find previous */
|
||||
othern->next = n; /* redo the chain with `n' in place of `mp' */
|
||||
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
|
||||
mp->next = NULL; /* now `mp' is free */
|
||||
}
|
||||
else { /* colliding node is in its own main position */
|
||||
/* new node will go into free position */
|
||||
n->next = mp->next; /* chain new position */
|
||||
mp->next = n;
|
||||
mp = n;
|
||||
}
|
||||
}
|
||||
mp->key = *key;
|
||||
for (;;) { /* correct `firstfree' */
|
||||
if (ttype(&t->firstfree->key) == LUA_TNIL)
|
||||
return &mp->val; /* OK; table still has a free place */
|
||||
else if (t->firstfree == t->node) break; /* cannot decrement from here */
|
||||
else (t->firstfree)--;
|
||||
}
|
||||
rehash(L, t); /* no more free places */
|
||||
return luaH_set(L, t, key); /* `rehash' invalidates this insertion */
|
||||
}
|
||||
|
||||
|
||||
TObject *luaH_setint (lua_State *L, Hash *t, int key) {
|
||||
TObject index;
|
||||
ttype(&index) = LUA_TNUMBER;
|
||||
nvalue(&index) = key;
|
||||
return luaH_set(L, t, &index);
|
||||
}
|
||||
|
||||
|
||||
void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val) {
|
||||
TObject *value, index;
|
||||
ttype(&index) = LUA_TSTRING;
|
||||
tsvalue(&index) = key;
|
||||
value = luaH_set(L, t, &index);
|
||||
ttype(value) = LUA_TNUMBER;
|
||||
nvalue(value) = val;
|
||||
}
|
||||
|
||||
|
||||
const TObject *luaH_getglobal (lua_State *L, const char *name) {
|
||||
return luaH_getstr(L->gt, luaS_new(L, name));
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
** $Id: ltable.h,v 1.1 2003/01/24 16:26:15 jason379 Exp $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef ltable_h
|
||||
#define ltable_h
|
||||
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
#define node(t,i) (&(t)->node[i])
|
||||
#define key(n) (&(n)->key)
|
||||
#define val(n) (&(n)->val)
|
||||
|
||||
Hash *luaH_new (lua_State *L, int nhash);
|
||||
void luaH_free (lua_State *L, Hash *t);
|
||||
const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key);
|
||||
const TObject *luaH_getnum (const Hash *t, Number key);
|
||||
const TObject *luaH_getstr (const Hash *t, TString *key);
|
||||
void luaH_remove (Hash *t, TObject *key);
|
||||
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
|
||||
Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
|
||||
TObject *luaH_setint (lua_State *L, Hash *t, int key);
|
||||
void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val);
|
||||
unsigned long luaH_hash (lua_State *L, const TObject *key);
|
||||
const TObject *luaH_getglobal (lua_State *L, const char *name);
|
||||
|
||||
/* exported only for debugging */
|
||||
Node *luaH_mainposition (const Hash *t, const TObject *key);
|
||||
|
||||
|
||||
#endif
|
@ -1,543 +0,0 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 1.1 2003/01/24 16:26:16 jason379 Exp $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lapi.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lcode.h"
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lmem.h"
|
||||
#include "lopcodes.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "luadebug.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
void luaB_opentests (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** The whole module only makes sense with LUA_DEBUG on
|
||||
*/
|
||||
#ifdef LUA_DEBUG
|
||||
|
||||
|
||||
|
||||
static void setnameval (lua_State *L, const char *name, int val) {
|
||||
lua_pushstring(L, name);
|
||||
lua_pushnumber(L, val);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Disassembler
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
static const char *const instrname[NUM_OPCODES] = {
|
||||
"END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT",
|
||||
"PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL",
|
||||
"GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF",
|
||||
"CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP",
|
||||
"ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT",
|
||||
"JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF",
|
||||
"JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP",
|
||||
"LFORLOOP", "CLOSURE"
|
||||
};
|
||||
|
||||
|
||||
static int pushop (lua_State *L, Proto *p, int pc) {
|
||||
char buff[100];
|
||||
Instruction i = p->code[pc];
|
||||
OpCode o = GET_OPCODE(i);
|
||||
const char *name = instrname[o];
|
||||
sprintf(buff, "%5d - ", luaG_getline(p->lineinfo, pc, 1, NULL));
|
||||
switch ((enum Mode)luaK_opproperties[o].mode) {
|
||||
case iO:
|
||||
sprintf(buff+8, "%-12s", name);
|
||||
break;
|
||||
case iU:
|
||||
sprintf(buff+8, "%-12s%4u", name, GETARG_U(i));
|
||||
break;
|
||||
case iS:
|
||||
sprintf(buff+8, "%-12s%4d", name, GETARG_S(i));
|
||||
break;
|
||||
case iAB:
|
||||
sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
|
||||
break;
|
||||
}
|
||||
lua_pushstring(L, buff);
|
||||
return (o != OP_END);
|
||||
}
|
||||
|
||||
|
||||
static int listcode (lua_State *L) {
|
||||
int pc;
|
||||
Proto *p;
|
||||
int res;
|
||||
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||
1, "Lua function expected");
|
||||
p = clvalue(luaA_index(L, 1))->f.l;
|
||||
lua_newtable(L);
|
||||
setnameval(L, "maxstack", p->maxstacksize);
|
||||
setnameval(L, "numparams", p->numparams);
|
||||
pc = 0;
|
||||
do {
|
||||
lua_pushnumber(L, pc+1);
|
||||
res = pushop(L, p, pc++);
|
||||
lua_settable(L, -3);
|
||||
} while (res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int liststrings (lua_State *L) {
|
||||
Proto *p;
|
||||
int i;
|
||||
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||
1, "Lua function expected");
|
||||
p = clvalue(luaA_index(L, 1))->f.l;
|
||||
lua_newtable(L);
|
||||
for (i=0; i<p->nkstr; i++) {
|
||||
lua_pushnumber(L, i+1);
|
||||
lua_pushstring(L, p->kstr[i]->str);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int listlocals (lua_State *L) {
|
||||
Proto *p;
|
||||
int pc = luaL_check_int(L, 2) - 1;
|
||||
int i = 0;
|
||||
const char *name;
|
||||
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||
1, "Lua function expected");
|
||||
p = clvalue(luaA_index(L, 1))->f.l;
|
||||
while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
|
||||
lua_pushstring(L, name);
|
||||
return i-1;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
static int get_limits (lua_State *L) {
|
||||
lua_newtable(L);
|
||||
setnameval(L, "BITS_INT", BITS_INT);
|
||||
setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
|
||||
setnameval(L, "MAXARG_A", MAXARG_A);
|
||||
setnameval(L, "MAXARG_B", MAXARG_B);
|
||||
setnameval(L, "MAXARG_S", MAXARG_S);
|
||||
setnameval(L, "MAXARG_U", MAXARG_U);
|
||||
setnameval(L, "MAXLOCALS", MAXLOCALS);
|
||||
setnameval(L, "MAXPARAMS", MAXPARAMS);
|
||||
setnameval(L, "MAXSTACK", MAXSTACK);
|
||||
setnameval(L, "MAXUPVALUES", MAXUPVALUES);
|
||||
setnameval(L, "MAXVARSLH", MAXVARSLH);
|
||||
setnameval(L, "RFPF", RFIELDS_PER_FLUSH);
|
||||
setnameval(L, "SIZE_A", SIZE_A);
|
||||
setnameval(L, "SIZE_B", SIZE_B);
|
||||
setnameval(L, "SIZE_OP", SIZE_OP);
|
||||
setnameval(L, "SIZE_U", SIZE_U);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int mem_query (lua_State *L) {
|
||||
if (lua_isnull(L, 1)) {
|
||||
lua_pushnumber(L, memdebug_total);
|
||||
lua_pushnumber(L, memdebug_numblocks);
|
||||
lua_pushnumber(L, memdebug_maxmem);
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
memdebug_memlimit = luaL_check_int(L, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int hash_query (lua_State *L) {
|
||||
if (lua_isnull(L, 2)) {
|
||||
luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, "string expected");
|
||||
lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash);
|
||||
}
|
||||
else {
|
||||
Hash *t;
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
t = hvalue(luaA_index(L, 2));
|
||||
lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int table_query (lua_State *L) {
|
||||
const Hash *t;
|
||||
int i = luaL_opt_int(L, 2, -1);
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
t = hvalue(luaA_index(L, 1));
|
||||
if (i == -1) {
|
||||
lua_pushnumber(L, t->size);
|
||||
lua_pushnumber(L, t->firstfree - t->node);
|
||||
return 2;
|
||||
}
|
||||
else if (i < t->size) {
|
||||
luaA_pushobject(L, &t->node[i].key);
|
||||
luaA_pushobject(L, &t->node[i].val);
|
||||
if (t->node[i].next) {
|
||||
lua_pushnumber(L, t->node[i].next - t->node);
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int string_query (lua_State *L) {
|
||||
stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
|
||||
int s = luaL_opt_int(L, 2, 0) - 1;
|
||||
if (s==-1) {
|
||||
lua_pushnumber(L ,tb->nuse);
|
||||
lua_pushnumber(L ,tb->size);
|
||||
return 2;
|
||||
}
|
||||
else if (s < tb->size) {
|
||||
TString *ts;
|
||||
int n = 0;
|
||||
for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
|
||||
ttype(L->top) = LUA_TSTRING;
|
||||
tsvalue(L->top) = ts;
|
||||
incr_top;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int tref (lua_State *L) {
|
||||
luaL_checkany(L, 1);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getref (lua_State *L) {
|
||||
if (lua_getref(L, luaL_check_int(L, 1)))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unref (lua_State *L) {
|
||||
lua_unref(L, luaL_check_int(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int newuserdata (lua_State *L) {
|
||||
if (lua_isnumber(L, 2))
|
||||
lua_pushusertag(L, (void *)luaL_check_int(L, 1), luaL_check_int(L, 2));
|
||||
else
|
||||
lua_newuserdata(L, luaL_check_int(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int udataval (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TUSERDATA);
|
||||
lua_pushnumber(L, (int)lua_touserdata(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int newstate (lua_State *L) {
|
||||
lua_State *L1 = lua_open(luaL_check_int(L, 1));
|
||||
if (L1)
|
||||
lua_pushuserdata(L, L1);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int loadlib (lua_State *L) {
|
||||
lua_State *L1 = (lua_State *)lua_touserdata(L, 1);
|
||||
switch (*luaL_check_string(L, 2)) {
|
||||
case 'm': lua_mathlibopen(L1); break;
|
||||
case 's': lua_strlibopen(L1); break;
|
||||
case 'i': lua_iolibopen(L1); break;
|
||||
case 'd': lua_dblibopen(L1); break;
|
||||
case 'b': lua_baselibopen(L1); break;
|
||||
default: luaL_argerror(L, 2, "invalid option");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int closestate (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TUSERDATA);
|
||||
lua_close((lua_State *)lua_touserdata(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int doremote (lua_State *L) {
|
||||
lua_State *L1;
|
||||
const char *code = luaL_check_string(L, 2);
|
||||
int status;
|
||||
luaL_checktype(L, 1, LUA_TUSERDATA);
|
||||
L1 = (lua_State *)lua_touserdata(L, 1);
|
||||
status = lua_dostring(L1, code);
|
||||
if (status != 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushnumber(L, status);
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
int i = 0;
|
||||
while (!lua_isnull(L1, ++i))
|
||||
lua_pushstring(L, lua_tostring(L1, i));
|
||||
return i-1;
|
||||
}
|
||||
}
|
||||
|
||||
static int settagmethod (lua_State *L) {
|
||||
int tag = luaL_check_int(L, 1);
|
||||
const char *event = luaL_check_string(L, 2);
|
||||
luaL_checkany(L, 3);
|
||||
lua_gettagmethod(L, tag, event);
|
||||
lua_pushvalue(L, 3);
|
||||
lua_settagmethod(L, tag, event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pushbool (lua_State *L, int b) {
|
||||
if (b) lua_pushnumber(L, 1);
|
||||
else lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int equal (lua_State *L) {
|
||||
return pushbool(L, lua_equal(L, 1, 2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** function to test the API with C. It interprets a kind of "assembler"
|
||||
** language with calls to the API, so the test can be driven by Lua code
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
static const char *const delimits = " \t\n,;";
|
||||
|
||||
static void skip (const char **pc) {
|
||||
while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
|
||||
}
|
||||
|
||||
static int getnum (lua_State *L, const char **pc) {
|
||||
int res = 0;
|
||||
int sig = 1;
|
||||
skip(pc);
|
||||
if (**pc == '.') {
|
||||
res = (int)lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
(*pc)++;
|
||||
return res;
|
||||
}
|
||||
else if (**pc == '-') {
|
||||
sig = -1;
|
||||
(*pc)++;
|
||||
}
|
||||
while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
|
||||
return sig*res;
|
||||
}
|
||||
|
||||
static const char *getname (char *buff, const char **pc) {
|
||||
int i = 0;
|
||||
skip(pc);
|
||||
while (**pc != '\0' && !strchr(delimits, **pc))
|
||||
buff[i++] = *(*pc)++;
|
||||
buff[i] = '\0';
|
||||
return buff;
|
||||
}
|
||||
|
||||
|
||||
#define EQ(s1) (strcmp(s1, inst) == 0)
|
||||
|
||||
#define getnum ((getnum)(L, &pc))
|
||||
#define getname ((getname)(buff, &pc))
|
||||
|
||||
|
||||
static int testC (lua_State *L) {
|
||||
char buff[30];
|
||||
const char *pc = luaL_check_string(L, 1);
|
||||
for (;;) {
|
||||
const char *inst = getname;
|
||||
if EQ("") return 0;
|
||||
else if EQ("isnumber") {
|
||||
lua_pushnumber(L, lua_isnumber(L, getnum));
|
||||
}
|
||||
else if EQ("isstring") {
|
||||
lua_pushnumber(L, lua_isstring(L, getnum));
|
||||
}
|
||||
else if EQ("istable") {
|
||||
lua_pushnumber(L, lua_istable(L, getnum));
|
||||
}
|
||||
else if EQ("iscfunction") {
|
||||
lua_pushnumber(L, lua_iscfunction(L, getnum));
|
||||
}
|
||||
else if EQ("isfunction") {
|
||||
lua_pushnumber(L, lua_isfunction(L, getnum));
|
||||
}
|
||||
else if EQ("isuserdata") {
|
||||
lua_pushnumber(L, lua_isuserdata(L, getnum));
|
||||
}
|
||||
else if EQ("isnil") {
|
||||
lua_pushnumber(L, lua_isnil(L, getnum));
|
||||
}
|
||||
else if EQ("isnull") {
|
||||
lua_pushnumber(L, lua_isnull(L, getnum));
|
||||
}
|
||||
else if EQ("tonumber") {
|
||||
lua_pushnumber(L, lua_tonumber(L, getnum));
|
||||
}
|
||||
else if EQ("tostring") {
|
||||
lua_pushstring(L, lua_tostring(L, getnum));
|
||||
}
|
||||
else if EQ("tonumber") {
|
||||
lua_pushnumber(L, lua_tonumber(L, getnum));
|
||||
}
|
||||
else if EQ("strlen") {
|
||||
lua_pushnumber(L, lua_strlen(L, getnum));
|
||||
}
|
||||
else if EQ("tocfunction") {
|
||||
lua_pushcfunction(L, lua_tocfunction(L, getnum));
|
||||
}
|
||||
else if EQ("return") {
|
||||
return getnum;
|
||||
}
|
||||
else if EQ("gettop") {
|
||||
lua_pushnumber(L, lua_gettop(L));
|
||||
}
|
||||
else if EQ("settop") {
|
||||
lua_settop(L, getnum);
|
||||
}
|
||||
else if EQ("pop") {
|
||||
lua_pop(L, getnum);
|
||||
}
|
||||
else if EQ("pushnum") {
|
||||
lua_pushnumber(L, getnum);
|
||||
}
|
||||
else if EQ("pushvalue") {
|
||||
lua_pushvalue(L, getnum);
|
||||
}
|
||||
else if EQ("remove") {
|
||||
lua_remove(L, getnum);
|
||||
}
|
||||
else if EQ("insert") {
|
||||
lua_insert(L, getnum);
|
||||
}
|
||||
else if EQ("gettable") {
|
||||
lua_gettable(L, getnum);
|
||||
}
|
||||
else if EQ("settable") {
|
||||
lua_settable(L, getnum);
|
||||
}
|
||||
else if EQ("next") {
|
||||
lua_next(L, -2);
|
||||
}
|
||||
else if EQ("concat") {
|
||||
lua_concat(L, getnum);
|
||||
}
|
||||
else if EQ("rawcall") {
|
||||
int narg = getnum;
|
||||
int nres = getnum;
|
||||
lua_rawcall(L, narg, nres);
|
||||
}
|
||||
else if EQ("call") {
|
||||
int narg = getnum;
|
||||
int nres = getnum;
|
||||
lua_call(L, narg, nres);
|
||||
}
|
||||
else if EQ("dostring") {
|
||||
lua_dostring(L, luaL_check_string(L, getnum));
|
||||
}
|
||||
else if EQ("settagmethod") {
|
||||
int tag = getnum;
|
||||
const char *event = getname;
|
||||
lua_settagmethod(L, tag, event);
|
||||
}
|
||||
else if EQ("gettagmethod") {
|
||||
int tag = getnum;
|
||||
const char *event = getname;
|
||||
lua_gettagmethod(L, tag, event);
|
||||
}
|
||||
else if EQ("type") {
|
||||
lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
|
||||
}
|
||||
else luaL_verror(L, "unknown instruction %.30s", buff);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
static const struct luaL_reg tests_funcs[] = {
|
||||
{"hash", hash_query},
|
||||
{"limits", get_limits},
|
||||
{"listcode", listcode},
|
||||
{"liststrings", liststrings},
|
||||
{"listlocals", listlocals},
|
||||
{"loadlib", loadlib},
|
||||
{"querystr", string_query},
|
||||
{"querytab", table_query},
|
||||
{"testC", testC},
|
||||
{"ref", tref},
|
||||
{"getref", getref},
|
||||
{"unref", unref},
|
||||
{"newuserdata", newuserdata},
|
||||
{"udataval", udataval},
|
||||
{"newstate", newstate},
|
||||
{"closestate", closestate},
|
||||
{"doremote", doremote},
|
||||
{"settagmethod", settagmethod},
|
||||
{"equal", equal},
|
||||
{"totalmem", mem_query}
|
||||
};
|
||||
|
||||
|
||||
void luaB_opentests (lua_State *L) {
|
||||
lua_newtable(L);
|
||||
lua_getglobals(L);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_setglobals(L);
|
||||
luaL_openl(L, tests_funcs); /* open functions inside new table */
|
||||
lua_setglobals(L); /* restore old table of globals */
|
||||
lua_setglobal(L, "T"); /* set new table as global T */
|
||||
}
|
||||
|
||||
#endif
|
@ -1,163 +0,0 @@
|
||||
/*
|
||||
** $Id: ltm.c,v 1.1 2003/01/24 16:26:16 jason379 Exp $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "ldo.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
#include "ltm.h"
|
||||
|
||||
|
||||
const char *const luaT_eventname[] = { /* ORDER TM */
|
||||
"gettable", "settable", "index", "getglobal", "setglobal", "add", "sub",
|
||||
"mul", "div", "pow", "unm", "lt", "concat", "gc", "function",
|
||||
"le", "gt", "ge", /* deprecated options!! */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static int findevent (const char *name) {
|
||||
int i;
|
||||
for (i=0; luaT_eventname[i]; i++)
|
||||
if (strcmp(luaT_eventname[i], name) == 0)
|
||||
return i;
|
||||
return -1; /* name not found */
|
||||
}
|
||||
|
||||
|
||||
static int luaI_checkevent (lua_State *L, const char *name, int t) {
|
||||
int e = findevent(name);
|
||||
if (e >= TM_N)
|
||||
luaO_verror(L, "event `%.50s' is deprecated", name);
|
||||
if (e == TM_GC && t == LUA_TTABLE)
|
||||
luaO_verror(L, "event `gc' for tables is deprecated");
|
||||
if (e < 0)
|
||||
luaO_verror(L, "`%.50s' is not a valid event name", name);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* events in LUA_TNIL are all allowed, since this is used as a
|
||||
* 'placeholder' for "default" fallbacks
|
||||
*/
|
||||
/* ORDER LUA_T, ORDER TM */
|
||||
static const char luaT_validevents[NUM_TAGS][TM_N] = {
|
||||
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */
|
||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */
|
||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */
|
||||
{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */
|
||||
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */
|
||||
};
|
||||
|
||||
int luaT_validevent (int t, int e) { /* ORDER LUA_T */
|
||||
return (t >= NUM_TAGS) ? 1 : luaT_validevents[t][e];
|
||||
}
|
||||
|
||||
|
||||
static void init_entry (lua_State *L, int tag) {
|
||||
int i;
|
||||
for (i=0; i<TM_N; i++)
|
||||
luaT_gettm(L, tag, i) = NULL;
|
||||
L->TMtable[tag].collected = NULL;
|
||||
}
|
||||
|
||||
|
||||
void luaT_init (lua_State *L) {
|
||||
int t;
|
||||
luaM_growvector(L, L->TMtable, 0, NUM_TAGS, struct TM, "", MAX_INT);
|
||||
L->nblocks += NUM_TAGS*sizeof(struct TM);
|
||||
L->last_tag = NUM_TAGS-1;
|
||||
for (t=0; t<=L->last_tag; t++)
|
||||
init_entry(L, t);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_newtag (lua_State *L) {
|
||||
luaM_growvector(L, L->TMtable, L->last_tag, 1, struct TM,
|
||||
"tag table overflow", MAX_INT);
|
||||
L->nblocks += sizeof(struct TM);
|
||||
L->last_tag++;
|
||||
init_entry(L, L->last_tag);
|
||||
return L->last_tag;
|
||||
}
|
||||
|
||||
|
||||
static void checktag (lua_State *L, int tag) {
|
||||
if (!(0 <= tag && tag <= L->last_tag))
|
||||
luaO_verror(L, "%d is not a valid tag", tag);
|
||||
}
|
||||
|
||||
void luaT_realtag (lua_State *L, int tag) {
|
||||
if (!validtag(tag))
|
||||
luaO_verror(L, "tag %d was not created by `newtag'", tag);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
|
||||
int e;
|
||||
checktag(L, tagto);
|
||||
checktag(L, tagfrom);
|
||||
for (e=0; e<TM_N; e++) {
|
||||
if (luaT_validevent(tagto, e))
|
||||
luaT_gettm(L, tagto, e) = luaT_gettm(L, tagfrom, e);
|
||||
}
|
||||
return tagto;
|
||||
}
|
||||
|
||||
|
||||
int luaT_tag (const TObject *o) {
|
||||
int t = ttype(o);
|
||||
switch (t) {
|
||||
case LUA_TUSERDATA: return tsvalue(o)->u.d.tag;
|
||||
case LUA_TTABLE: return hvalue(o)->htag;
|
||||
default: return t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
|
||||
int e;
|
||||
e = luaI_checkevent(L, event, t);
|
||||
checktag(L, t);
|
||||
if (luaT_validevent(t, e) && luaT_gettm(L, t, e)) {
|
||||
clvalue(L->top) = luaT_gettm(L, t, e);
|
||||
ttype(L->top) = LUA_TFUNCTION;
|
||||
}
|
||||
else
|
||||
ttype(L->top) = LUA_TNIL;
|
||||
incr_top;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
|
||||
int e = luaI_checkevent(L, event, t);
|
||||
checktag(L, t);
|
||||
if (!luaT_validevent(t, e))
|
||||
luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
|
||||
luaT_eventname[e], luaO_typenames[t],
|
||||
(t == LUA_TTABLE || t == LUA_TUSERDATA) ?
|
||||
" with default tag" : "");
|
||||
switch (ttype(L->top - 1)) {
|
||||
case LUA_TNIL:
|
||||
luaT_gettm(L, t, e) = NULL;
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
luaT_gettm(L, t, e) = clvalue(L->top - 1);
|
||||
break;
|
||||
default:
|
||||
lua_error(L, "tag method must be a function (or nil)");
|
||||
}
|
||||
L->top--;
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
** $Id: ltm.h,v 1.1 2003/01/24 16:26:16 jason379 Exp $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef ltm_h
|
||||
#define ltm_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
|
||||
/*
|
||||
* WARNING: if you change the order of this enumeration,
|
||||
* grep "ORDER TM"
|
||||
*/
|
||||
typedef enum {
|
||||
TM_GETTABLE = 0,
|
||||
TM_SETTABLE,
|
||||
TM_INDEX,
|
||||
TM_GETGLOBAL,
|
||||
TM_SETGLOBAL,
|
||||
TM_ADD,
|
||||
TM_SUB,
|
||||
TM_MUL,
|
||||
TM_DIV,
|
||||
TM_POW,
|
||||
TM_UNM,
|
||||
TM_LT,
|
||||
TM_CONCAT,
|
||||
TM_GC,
|
||||
TM_FUNCTION,
|
||||
TM_N /* number of elements in the enum */
|
||||
} TMS;
|
||||
|
||||
|
||||
struct TM {
|
||||
Closure *method[TM_N];
|
||||
TString *collected; /* list of garbage-collected udata with this tag */
|
||||
};
|
||||
|
||||
|
||||
#define luaT_gettm(L,tag,event) (L->TMtable[tag].method[event])
|
||||
#define luaT_gettmbyObj(L,o,e) (luaT_gettm((L),luaT_tag(o),(e)))
|
||||
|
||||
|
||||
#define validtag(t) (NUM_TAGS <= (t) && (t) <= L->last_tag)
|
||||
|
||||
extern const char *const luaT_eventname[];
|
||||
|
||||
|
||||
void luaT_init (lua_State *L);
|
||||
void luaT_realtag (lua_State *L, int tag);
|
||||
int luaT_tag (const TObject *o);
|
||||
int luaT_validevent (int t, int e); /* used by compatibility module */
|
||||
|
||||
|
||||
#endif
|
@ -1,248 +0,0 @@
|
||||
/*
|
||||
** $Id: lua.h,v 1.1 2003/01/24 16:26:17 jason379 Exp $
|
||||
** Lua - An Extensible Extension Language
|
||||
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
||||
** e-mail: lua@tecgraf.puc-rio.br
|
||||
** www: http://www.tecgraf.puc-rio.br/lua/
|
||||
** See Copyright Notice at the end of this file
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lua_h
|
||||
#define lua_h
|
||||
|
||||
|
||||
/* definition of `size_t' */
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* mark for all API functions */
|
||||
#ifndef LUA_API
|
||||
#define LUA_API extern
|
||||
#endif
|
||||
|
||||
|
||||
#define LUA_VERSION "Lua 4.0.1"
|
||||
#define LUA_COPYRIGHT "Copyright (C) 1994-2000 TeCGraf, PUC-Rio"
|
||||
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
|
||||
|
||||
|
||||
/* name of global variable with error handler */
|
||||
#define LUA_ERRORMESSAGE "_ERRORMESSAGE"
|
||||
|
||||
|
||||
/* pre-defined references */
|
||||
#define LUA_NOREF (-2)
|
||||
#define LUA_REFNIL (-1)
|
||||
#define LUA_REFREGISTRY 0
|
||||
|
||||
/* pre-defined tags */
|
||||
#define LUA_ANYTAG (-1)
|
||||
#define LUA_NOTAG (-2)
|
||||
|
||||
|
||||
/* option for multiple returns in lua_call */
|
||||
#define LUA_MULTRET (-1)
|
||||
|
||||
|
||||
/* minimum stack available for a C function */
|
||||
#define LUA_MINSTACK 20
|
||||
|
||||
|
||||
/* error codes for lua_do* */
|
||||
#define LUA_ERRRUN 1
|
||||
#define LUA_ERRFILE 2
|
||||
#define LUA_ERRSYNTAX 3
|
||||
#define LUA_ERRMEM 4
|
||||
#define LUA_ERRERR 5
|
||||
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
typedef int (*lua_CFunction) (lua_State *L);
|
||||
|
||||
/*
|
||||
** types returned by `lua_type'
|
||||
*/
|
||||
#define LUA_TNONE (-1)
|
||||
|
||||
#define LUA_TUSERDATA 0
|
||||
#define LUA_TNIL 1
|
||||
#define LUA_TNUMBER 2
|
||||
#define LUA_TSTRING 3
|
||||
#define LUA_TTABLE 4
|
||||
#define LUA_TFUNCTION 5
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** state manipulation
|
||||
*/
|
||||
LUA_API lua_State *lua_open (int stacksize);
|
||||
LUA_API void lua_close (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** basic stack manipulation
|
||||
*/
|
||||
LUA_API int lua_gettop (lua_State *L);
|
||||
LUA_API void lua_settop (lua_State *L, int index);
|
||||
LUA_API void lua_pushvalue (lua_State *L, int index);
|
||||
LUA_API void lua_remove (lua_State *L, int index);
|
||||
LUA_API void lua_insert (lua_State *L, int index);
|
||||
LUA_API int lua_stackspace (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** access functions (stack -> C)
|
||||
*/
|
||||
|
||||
LUA_API int lua_type (lua_State *L, int index);
|
||||
LUA_API const char *lua_typename (lua_State *L, int t);
|
||||
LUA_API int lua_isnumber (lua_State *L, int index);
|
||||
LUA_API int lua_isstring (lua_State *L, int index);
|
||||
LUA_API int lua_iscfunction (lua_State *L, int index);
|
||||
LUA_API int lua_tag (lua_State *L, int index);
|
||||
|
||||
LUA_API int lua_equal (lua_State *L, int index1, int index2);
|
||||
LUA_API int lua_lessthan (lua_State *L, int index1, int index2);
|
||||
|
||||
LUA_API double lua_tonumber (lua_State *L, int index);
|
||||
LUA_API const char *lua_tostring (lua_State *L, int index);
|
||||
LUA_API size_t lua_strlen (lua_State *L, int index);
|
||||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index);
|
||||
LUA_API void *lua_touserdata (lua_State *L, int index);
|
||||
LUA_API const void *lua_topointer (lua_State *L, int index);
|
||||
|
||||
|
||||
/*
|
||||
** push functions (C -> stack)
|
||||
*/
|
||||
LUA_API void lua_pushnil (lua_State *L);
|
||||
LUA_API void lua_pushnumber (lua_State *L, double n);
|
||||
LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len);
|
||||
LUA_API void lua_pushstring (lua_State *L, const char *s);
|
||||
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
|
||||
LUA_API void lua_pushusertag (lua_State *L, void *u, int tag);
|
||||
|
||||
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
*/
|
||||
LUA_API void lua_getglobal (lua_State *L, const char *name);
|
||||
LUA_API void lua_gettable (lua_State *L, int index);
|
||||
LUA_API void lua_rawget (lua_State *L, int index);
|
||||
LUA_API void lua_rawgeti (lua_State *L, int index, int n);
|
||||
LUA_API void lua_getglobals (lua_State *L);
|
||||
LUA_API void lua_gettagmethod (lua_State *L, int tag, const char *event);
|
||||
LUA_API int lua_getref (lua_State *L, int ref);
|
||||
LUA_API void lua_newtable (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
*/
|
||||
LUA_API void lua_setglobal (lua_State *L, const char *name);
|
||||
LUA_API void lua_settable (lua_State *L, int index);
|
||||
LUA_API void lua_rawset (lua_State *L, int index);
|
||||
LUA_API void lua_rawseti (lua_State *L, int index, int n);
|
||||
LUA_API void lua_setglobals (lua_State *L);
|
||||
LUA_API void lua_settagmethod (lua_State *L, int tag, const char *event);
|
||||
LUA_API int lua_ref (lua_State *L, int lock);
|
||||
|
||||
|
||||
/*
|
||||
** "do" functions (run Lua code)
|
||||
*/
|
||||
LUA_API int lua_call (lua_State *L, int nargs, int nresults);
|
||||
LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults);
|
||||
LUA_API int lua_dofile (lua_State *L, const char *filename);
|
||||
LUA_API int lua_dostring (lua_State *L, const char *str);
|
||||
LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name);
|
||||
|
||||
/*
|
||||
** Garbage-collection functions
|
||||
*/
|
||||
LUA_API int lua_getgcthreshold (lua_State *L);
|
||||
LUA_API int lua_getgccount (lua_State *L);
|
||||
LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
|
||||
|
||||
/*
|
||||
** miscellaneous functions
|
||||
*/
|
||||
LUA_API int lua_newtag (lua_State *L);
|
||||
LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
|
||||
LUA_API void lua_settag (lua_State *L, int tag);
|
||||
|
||||
LUA_API void lua_error (lua_State *L, const char *s);
|
||||
|
||||
LUA_API void lua_unref (lua_State *L, int ref);
|
||||
|
||||
LUA_API int lua_next (lua_State *L, int index);
|
||||
LUA_API int lua_getn (lua_State *L, int index);
|
||||
|
||||
LUA_API void lua_concat (lua_State *L, int n);
|
||||
|
||||
LUA_API void *lua_newuserdata (lua_State *L, size_t size);
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define lua_pop(L,n) lua_settop(L, -(n)-1)
|
||||
|
||||
#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
|
||||
#define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0)
|
||||
#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
|
||||
#define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t))
|
||||
|
||||
#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)
|
||||
#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
|
||||
#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA)
|
||||
#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL)
|
||||
#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE)
|
||||
|
||||
#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2000 TeCGraf, PUC-Rio. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without license
|
||||
* or royalty fees, to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose, including commercial applications, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* - The above copyright notice and this permission notice shall appear in all
|
||||
* copies or substantial portions of this software.
|
||||
*
|
||||
* - The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in a
|
||||
* product, an acknowledgment in the product documentation would be greatly
|
||||
* appreciated (but it is not required).
|
||||
*
|
||||
* - Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* The authors specifically disclaim any warranties, including, but not limited
|
||||
* to, the implied warranties of merchantability and fitness for a particular
|
||||
* purpose. The software provided hereunder is on an "as is" basis, and the
|
||||
* authors have no obligation to provide maintenance, support, updates,
|
||||
* enhancements, or modifications. In no event shall TeCGraf, PUC-Rio, or the
|
||||
* authors be held liable to any party for direct, indirect, special,
|
||||
* incidental, or consequential damages arising out of the use of this software
|
||||
* and its documentation.
|
||||
*
|
||||
* The Lua language and this implementation have been entirely designed and
|
||||
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
|
||||
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
|
||||
*
|
||||
* This implementation contains no third-party code.
|
||||
******************************************************************************/
|
||||
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
** $Id: luadebug.h,v 1.1 2003/01/24 16:26:17 jason379 Exp $
|
||||
** Debugging API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef luadebug_h
|
||||
#define luadebug_h
|
||||
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
typedef struct lua_Debug lua_Debug; /* activation record */
|
||||
typedef struct lua_Localvar lua_Localvar;
|
||||
|
||||
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
||||
|
||||
|
||||
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
|
||||
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
|
||||
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||
|
||||
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
|
||||
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
|
||||
|
||||
|
||||
#define LUA_IDSIZE 60
|
||||
|
||||
struct lua_Debug {
|
||||
const char *event; /* `call', `return' */
|
||||
int currentline; /* (l) */
|
||||
const char *name; /* (n) */
|
||||
const char *namewhat; /* (n) `global', `tag method', `local', `field' */
|
||||
int nups; /* (u) number of upvalues */
|
||||
int linedefined; /* (S) */
|
||||
const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
|
||||
const char *source; /* (S) */
|
||||
char short_src[LUA_IDSIZE]; /* (S) */
|
||||
/* private part */
|
||||
struct lua_TObject *_func; /* active function */
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
** $Id: lualib.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $
|
||||
** Lua standard libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lualib_h
|
||||
#define lualib_h
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
#ifndef LUALIB_API
|
||||
#define LUALIB_API extern
|
||||
#endif
|
||||
|
||||
|
||||
#define LUA_ALERT "_ALERT"
|
||||
|
||||
LUALIB_API void lua_baselibopen (lua_State *L);
|
||||
LUALIB_API void lua_iolibopen (lua_State *L);
|
||||
LUALIB_API void lua_strlibopen (lua_State *L);
|
||||
LUALIB_API void lua_mathlibopen (lua_State *L);
|
||||
LUALIB_API void lua_dblibopen (lua_State *L);
|
||||
|
||||
|
||||
|
||||
/* Auxiliary functions (private) */
|
||||
|
||||
const char *luaI_classend (lua_State *L, const char *p);
|
||||
int luaI_singlematch (int c, const char *p, const char *ep);
|
||||
|
||||
#endif
|
@ -1,244 +0,0 @@
|
||||
/*
|
||||
** $Id: lundump.c,v 1.1 2003/01/24 16:26:18 jason379 Exp $
|
||||
** load bytecodes from files
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lfunc.h"
|
||||
#include "lmem.h"
|
||||
#include "lopcodes.h"
|
||||
#include "lstring.h"
|
||||
#include "lundump.h"
|
||||
|
||||
#define LoadByte ezgetc
|
||||
|
||||
static const char* ZNAME (ZIO* Z)
|
||||
{
|
||||
const char* s=zname(Z);
|
||||
return (*s=='@') ? s+1 : s;
|
||||
}
|
||||
|
||||
static void unexpectedEOZ (lua_State* L, ZIO* Z)
|
||||
{
|
||||
luaO_verror(L,"unexpected end of file in `%.99s'",ZNAME(Z));
|
||||
}
|
||||
|
||||
static int ezgetc (lua_State* L, ZIO* Z)
|
||||
{
|
||||
int c=zgetc(Z);
|
||||
if (c==EOZ) unexpectedEOZ(L,Z);
|
||||
return c;
|
||||
}
|
||||
|
||||
static void ezread (lua_State* L, ZIO* Z, void* b, int n)
|
||||
{
|
||||
int r=zread(Z,b,n);
|
||||
if (r!=0) unexpectedEOZ(L,Z);
|
||||
}
|
||||
|
||||
static void LoadBlock (lua_State* L, void* b, size_t size, ZIO* Z, int swap)
|
||||
{
|
||||
if (swap)
|
||||
{
|
||||
char *p=(char *) b+size-1;
|
||||
int n=size;
|
||||
while (n--) *p--=(char)ezgetc(L,Z);
|
||||
}
|
||||
else
|
||||
ezread(L,Z,b,size);
|
||||
}
|
||||
|
||||
static void LoadVector (lua_State* L, void* b, int m, size_t size, ZIO* Z, int swap)
|
||||
{
|
||||
if (swap)
|
||||
{
|
||||
char *q=(char *) b;
|
||||
while (m--)
|
||||
{
|
||||
char *p=q+size-1;
|
||||
int n=size;
|
||||
while (n--) *p--=(char)ezgetc(L,Z);
|
||||
q+=size;
|
||||
}
|
||||
}
|
||||
else
|
||||
ezread(L,Z,b,m*size);
|
||||
}
|
||||
|
||||
static int LoadInt (lua_State* L, ZIO* Z, int swap)
|
||||
{
|
||||
int x;
|
||||
LoadBlock(L,&x,sizeof(x),Z,swap);
|
||||
return x;
|
||||
}
|
||||
|
||||
static size_t LoadSize (lua_State* L, ZIO* Z, int swap)
|
||||
{
|
||||
size_t x;
|
||||
LoadBlock(L,&x,sizeof(x),Z,swap);
|
||||
return x;
|
||||
}
|
||||
|
||||
static Number LoadNumber (lua_State* L, ZIO* Z, int swap)
|
||||
{
|
||||
Number x;
|
||||
LoadBlock(L,&x,sizeof(x),Z,swap);
|
||||
return x;
|
||||
}
|
||||
|
||||
static TString* LoadString (lua_State* L, ZIO* Z, int swap)
|
||||
{
|
||||
size_t size=LoadSize(L,Z,swap);
|
||||
if (size==0)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
char* s=luaO_openspace(L,size);
|
||||
LoadBlock(L,s,size,Z,0);
|
||||
return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap)
|
||||
{
|
||||
int size=LoadInt(L,Z,swap);
|
||||
tf->code=luaM_newvector(L,size,Instruction);
|
||||
LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap);
|
||||
if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z));
|
||||
luaF_protook(L,tf,size);
|
||||
}
|
||||
|
||||
static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
|
||||
{
|
||||
int i,n;
|
||||
tf->nlocvars=n=LoadInt(L,Z,swap);
|
||||
tf->locvars=luaM_newvector(L,n,LocVar);
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
tf->locvars[i].varname=LoadString(L,Z,swap);
|
||||
tf->locvars[i].startpc=LoadInt(L,Z,swap);
|
||||
tf->locvars[i].endpc=LoadInt(L,Z,swap);
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap)
|
||||
{
|
||||
int n;
|
||||
tf->nlineinfo=n=LoadInt(L,Z,swap);
|
||||
tf->lineinfo=luaM_newvector(L,n,int);
|
||||
LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap);
|
||||
}
|
||||
|
||||
static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap);
|
||||
|
||||
static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap)
|
||||
{
|
||||
int i,n;
|
||||
tf->nkstr=n=LoadInt(L,Z,swap);
|
||||
tf->kstr=luaM_newvector(L,n,TString*);
|
||||
for (i=0; i<n; i++)
|
||||
tf->kstr[i]=LoadString(L,Z,swap);
|
||||
tf->nknum=n=LoadInt(L,Z,swap);
|
||||
tf->knum=luaM_newvector(L,n,Number);
|
||||
LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap);
|
||||
tf->nkproto=n=LoadInt(L,Z,swap);
|
||||
tf->kproto=luaM_newvector(L,n,Proto*);
|
||||
for (i=0; i<n; i++)
|
||||
tf->kproto[i]=LoadFunction(L,Z,swap);
|
||||
}
|
||||
|
||||
static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap)
|
||||
{
|
||||
Proto* tf=luaF_newproto(L);
|
||||
tf->source=LoadString(L,Z,swap);
|
||||
tf->lineDefined=LoadInt(L,Z,swap);
|
||||
tf->numparams=LoadInt(L,Z,swap);
|
||||
tf->is_vararg=LoadByte(L,Z);
|
||||
tf->maxstacksize=LoadInt(L,Z,swap);
|
||||
LoadLocals(L,tf,Z,swap);
|
||||
LoadLines(L,tf,Z,swap);
|
||||
LoadConstants(L,tf,Z,swap);
|
||||
LoadCode(L,tf,Z,swap);
|
||||
return tf;
|
||||
}
|
||||
|
||||
static void LoadSignature (lua_State* L, ZIO* Z)
|
||||
{
|
||||
const char* s=SIGNATURE;
|
||||
while (*s!=0 && ezgetc(L,Z)==*s)
|
||||
++s;
|
||||
if (*s!=0) luaO_verror(L,"bad signature in `%.99s'",ZNAME(Z));
|
||||
}
|
||||
|
||||
static void TestSize (lua_State* L, int s, const char* what, ZIO* Z)
|
||||
{
|
||||
int r=ezgetc(L,Z);
|
||||
if (r!=s)
|
||||
luaO_verror(L,"virtual machine mismatch in `%.99s':\n"
|
||||
" %.20s is %d but read %d",ZNAME(Z),what,s,r);
|
||||
}
|
||||
|
||||
#define TESTSIZE(s) TestSize(L,s,#s,Z)
|
||||
#define V(v) v/16,v%16
|
||||
|
||||
static int LoadHeader (lua_State* L, ZIO* Z)
|
||||
{
|
||||
int version,swap;
|
||||
Number f=0,tf=TEST_NUMBER;
|
||||
LoadSignature(L,Z);
|
||||
version=ezgetc(L,Z);
|
||||
if (version>VERSION)
|
||||
luaO_verror(L,"`%.99s' too new:\n"
|
||||
" read version %d.%d; expected at most %d.%d",
|
||||
ZNAME(Z),V(version),V(VERSION));
|
||||
if (version<VERSION0) /* check last major change */
|
||||
luaO_verror(L,"`%.99s' too old:\n"
|
||||
" read version %d.%d; expected at least %d.%d",
|
||||
ZNAME(Z),V(version),V(VERSION));
|
||||
swap=(luaU_endianess()!=ezgetc(L,Z)); /* need to swap bytes? */
|
||||
TESTSIZE(sizeof(int));
|
||||
TESTSIZE(sizeof(size_t));
|
||||
TESTSIZE(sizeof(Instruction));
|
||||
TESTSIZE(SIZE_INSTRUCTION);
|
||||
TESTSIZE(SIZE_OP);
|
||||
TESTSIZE(SIZE_B);
|
||||
TESTSIZE(sizeof(Number));
|
||||
f=LoadNumber(L,Z,swap);
|
||||
if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */
|
||||
luaO_verror(L,"unknown number format in `%.99s':\n"
|
||||
" read " NUMBER_FMT "; expected " NUMBER_FMT, ZNAME(Z),f,tf);
|
||||
return swap;
|
||||
}
|
||||
|
||||
static Proto* LoadChunk (lua_State* L, ZIO* Z)
|
||||
{
|
||||
return LoadFunction(L,Z,LoadHeader(L,Z));
|
||||
}
|
||||
|
||||
/*
|
||||
** load one chunk from a file or buffer
|
||||
** return main if ok and NULL at EOF
|
||||
*/
|
||||
Proto* luaU_undump (lua_State* L, ZIO* Z)
|
||||
{
|
||||
Proto* tf=NULL;
|
||||
int c=zgetc(Z);
|
||||
if (c==ID_CHUNK)
|
||||
tf=LoadChunk(L,Z);
|
||||
c=zgetc(Z);
|
||||
if (c!=EOZ)
|
||||
luaO_verror(L,"`%.99s' apparently contains more than one chunk",ZNAME(Z));
|
||||
return tf;
|
||||
}
|
||||
|
||||
/*
|
||||
** find byte order
|
||||
*/
|
||||
int luaU_endianess (void)
|
||||
{
|
||||
int x=1;
|
||||
return *(char*)&x;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
** $Id: lundump.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $
|
||||
** load pre-compiled Lua chunks
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lundump_h
|
||||
#define lundump_h
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lzio.h"
|
||||
|
||||
/* load one chunk */
|
||||
Proto* luaU_undump (lua_State* L, ZIO* Z);
|
||||
|
||||
/* find byte order */
|
||||
int luaU_endianess (void);
|
||||
|
||||
/* definitions for headers of binary files */
|
||||
#define VERSION 0x40 /* last format change was in 4.0 */
|
||||
#define VERSION0 0x40 /* last major change was in 4.0 */
|
||||
#define ID_CHUNK 27 /* binary files start with ESC... */
|
||||
#define SIGNATURE "Lua" /* ...followed by this signature */
|
||||
|
||||
/* formats for error messages */
|
||||
#define SOURCE_FMT "<%d:%.99s>"
|
||||
#define SOURCE tf->lineDefined,tf->source->str
|
||||
#define IN_FMT " in %p " SOURCE_FMT
|
||||
#define IN tf,SOURCE
|
||||
|
||||
/* a multiple of PI for testing native format */
|
||||
/* multiplying by 1E8 gives non-trivial integer values */
|
||||
#define TEST_NUMBER 3.14159265358979323846E8
|
||||
|
||||
#endif
|
@ -1,710 +0,0 @@
|
||||
/*
|
||||
** $Id: lvm.c,v 1.1 2003/01/24 16:26:18 jason379 Exp $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lapi.h"
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lgc.h"
|
||||
#include "lobject.h"
|
||||
#include "lopcodes.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
#include "lvm.h"
|
||||
|
||||
|
||||
#ifdef OLD_ANSI
|
||||
#define strcoll(a,b) strcmp(a,b)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Extra stack size to run a function:
|
||||
** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
|
||||
*/
|
||||
#define EXTRA_STACK 8
|
||||
|
||||
|
||||
|
||||
int luaV_tonumber (TObject *obj) {
|
||||
if (ttype(obj) != LUA_TSTRING)
|
||||
return 1;
|
||||
else {
|
||||
if (!luaO_str2d(svalue(obj), &nvalue(obj)))
|
||||
return 2;
|
||||
ttype(obj) = LUA_TNUMBER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
|
||||
if (ttype(obj) != LUA_TNUMBER)
|
||||
return 1;
|
||||
else {
|
||||
char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */
|
||||
lua_number2str(s, nvalue(obj)); /* convert `s' to number */
|
||||
tsvalue(obj) = luaS_new(L, s);
|
||||
ttype(obj) = LUA_TSTRING;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
|
||||
CallInfo *ci = infovalue(base-1);
|
||||
int *lineinfo = ci->func->f.l->lineinfo;
|
||||
int pc = (*ci->pc - ci->func->f.l->code) - 1;
|
||||
int newline;
|
||||
if (pc == 0) { /* may be first time? */
|
||||
ci->line = 1;
|
||||
ci->refi = 0;
|
||||
ci->lastpc = pc+1; /* make sure it will call linehook */
|
||||
}
|
||||
newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi);
|
||||
/* calls linehook when enters a new line or jumps back (loop) */
|
||||
if (newline != ci->line || pc <= ci->lastpc) {
|
||||
ci->line = newline;
|
||||
L->top = top;
|
||||
luaD_lineHook(L, base-1, newline, linehook);
|
||||
}
|
||||
ci->lastpc = pc;
|
||||
}
|
||||
|
||||
|
||||
static Closure *luaV_closure (lua_State *L, int nelems) {
|
||||
Closure *c = luaF_newclosure(L, nelems);
|
||||
L->top -= nelems;
|
||||
while (nelems--)
|
||||
c->upvalue[nelems] = *(L->top+nelems);
|
||||
clvalue(L->top) = c;
|
||||
ttype(L->top) = LUA_TFUNCTION;
|
||||
incr_top;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
|
||||
Closure *cl = luaV_closure(L, nelems);
|
||||
cl->f.c = c;
|
||||
cl->isC = 1;
|
||||
}
|
||||
|
||||
|
||||
void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
|
||||
Closure *cl = luaV_closure(L, nelems);
|
||||
cl->f.l = l;
|
||||
cl->isC = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Function to index a table.
|
||||
** Receives the table at `t' and the key at top.
|
||||
*/
|
||||
const TObject *luaV_gettable (lua_State *L, StkId t) {
|
||||
Closure *tm;
|
||||
int tg;
|
||||
if (ttype(t) == LUA_TTABLE && /* `t' is a table? */
|
||||
((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */
|
||||
luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */
|
||||
/* do a primitive get */
|
||||
const TObject *h = luaH_get(L, hvalue(t), L->top-1);
|
||||
/* result is no nil or there is no `index' tag method? */
|
||||
if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL))
|
||||
return h; /* return result */
|
||||
/* else call `index' tag method */
|
||||
}
|
||||
else { /* try a `gettable' tag method */
|
||||
tm = luaT_gettmbyObj(L, t, TM_GETTABLE);
|
||||
}
|
||||
if (tm != NULL) { /* is there a tag method? */
|
||||
luaD_checkstack(L, 2);
|
||||
*(L->top+1) = *(L->top-1); /* key */
|
||||
*L->top = *t; /* table */
|
||||
clvalue(L->top-1) = tm; /* tag method */
|
||||
ttype(L->top-1) = LUA_TFUNCTION;
|
||||
L->top += 2;
|
||||
luaD_call(L, L->top - 3, 1);
|
||||
return L->top - 1; /* call result */
|
||||
}
|
||||
else { /* no tag method */
|
||||
luaG_typeerror(L, t, "index");
|
||||
return NULL; /* to avoid warnings */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Receives table at `t', key at `key' and value at top.
|
||||
*/
|
||||
void luaV_settable (lua_State *L, StkId t, StkId key) {
|
||||
int tg;
|
||||
if (ttype(t) == LUA_TTABLE && /* `t' is a table? */
|
||||
((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */
|
||||
luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */
|
||||
*luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */
|
||||
else { /* try a `settable' tag method */
|
||||
Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE);
|
||||
if (tm != NULL) {
|
||||
luaD_checkstack(L, 3);
|
||||
*(L->top+2) = *(L->top-1);
|
||||
*(L->top+1) = *key;
|
||||
*(L->top) = *t;
|
||||
clvalue(L->top-1) = tm;
|
||||
ttype(L->top-1) = LUA_TFUNCTION;
|
||||
L->top += 3;
|
||||
luaD_call(L, L->top - 4, 0); /* call `settable' tag method */
|
||||
}
|
||||
else /* no tag method... */
|
||||
luaG_typeerror(L, t, "index");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const TObject *luaV_getglobal (lua_State *L, TString *s) {
|
||||
const TObject *value = luaH_getstr(L->gt, s);
|
||||
Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL);
|
||||
if (tm == NULL) /* is there a tag method? */
|
||||
return value; /* default behavior */
|
||||
else { /* tag method */
|
||||
luaD_checkstack(L, 3);
|
||||
clvalue(L->top) = tm;
|
||||
ttype(L->top) = LUA_TFUNCTION;
|
||||
tsvalue(L->top+1) = s; /* global name */
|
||||
ttype(L->top+1) = LUA_TSTRING;
|
||||
*(L->top+2) = *value;
|
||||
L->top += 3;
|
||||
luaD_call(L, L->top - 3, 1);
|
||||
return L->top - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaV_setglobal (lua_State *L, TString *s) {
|
||||
const TObject *oldvalue = luaH_getstr(L->gt, s);
|
||||
Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL);
|
||||
if (tm == NULL) { /* is there a tag method? */
|
||||
if (oldvalue != &luaO_nilobject) {
|
||||
/* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */
|
||||
*(TObject *)oldvalue = *(L->top - 1);
|
||||
}
|
||||
else {
|
||||
TObject key;
|
||||
ttype(&key) = LUA_TSTRING;
|
||||
tsvalue(&key) = s;
|
||||
*luaH_set(L, L->gt, &key) = *(L->top - 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
luaD_checkstack(L, 3);
|
||||
*(L->top+2) = *(L->top-1); /* new value */
|
||||
*(L->top+1) = *oldvalue;
|
||||
ttype(L->top) = LUA_TSTRING;
|
||||
tsvalue(L->top) = s;
|
||||
clvalue(L->top-1) = tm;
|
||||
ttype(L->top-1) = LUA_TFUNCTION;
|
||||
L->top += 3;
|
||||
luaD_call(L, L->top - 4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int call_binTM (lua_State *L, StkId top, TMS event) {
|
||||
/* try first operand */
|
||||
Closure *tm = luaT_gettmbyObj(L, top-2, event);
|
||||
L->top = top;
|
||||
if (tm == NULL) {
|
||||
tm = luaT_gettmbyObj(L, top-1, event); /* try second operand */
|
||||
if (tm == NULL) {
|
||||
tm = luaT_gettm(L, 0, event); /* try a `global' method */
|
||||
if (tm == NULL)
|
||||
return 0; /* error */
|
||||
}
|
||||
}
|
||||
lua_pushstring(L, luaT_eventname[event]);
|
||||
luaD_callTM(L, tm, 3, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void call_arith (lua_State *L, StkId top, TMS event) {
|
||||
if (!call_binTM(L, top, event))
|
||||
luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on");
|
||||
}
|
||||
|
||||
|
||||
static int luaV_strcomp (const TString *ls, const TString *rs) {
|
||||
const char *l = ls->str;
|
||||
size_t ll = ls->len;
|
||||
const char *r = rs->str;
|
||||
size_t lr = rs->len;
|
||||
for (;;) {
|
||||
int temp = strcoll(l, r);
|
||||
if (temp != 0) return temp;
|
||||
else { /* strings are equal up to a '\0' */
|
||||
size_t len = strlen(l); /* index of first '\0' in both strings */
|
||||
if (len == ll) /* l is finished? */
|
||||
return (len == lr) ? 0 : -1; /* l is equal or smaller than r */
|
||||
else if (len == lr) /* r is finished? */
|
||||
return 1; /* l is greater than r (because l is not finished) */
|
||||
/* both strings longer than `len'; go on comparing (after the '\0') */
|
||||
len++;
|
||||
l += len; ll -= len; r += len; lr -= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
|
||||
if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER)
|
||||
return (nvalue(l) < nvalue(r));
|
||||
else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING)
|
||||
return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0);
|
||||
else { /* call TM */
|
||||
luaD_checkstack(L, 2);
|
||||
*top++ = *l;
|
||||
*top++ = *r;
|
||||
if (!call_binTM(L, top, TM_LT))
|
||||
luaG_ordererror(L, top-2);
|
||||
L->top--;
|
||||
return (ttype(L->top) != LUA_TNIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaV_strconc (lua_State *L, int total, StkId top) {
|
||||
do {
|
||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||
if (tostring(L, top-2) || tostring(L, top-1)) {
|
||||
if (!call_binTM(L, top, TM_CONCAT))
|
||||
luaG_binerror(L, top-2, LUA_TSTRING, "concat");
|
||||
}
|
||||
else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */
|
||||
/* at least two string values; get as many as possible */
|
||||
lint32 tl = (lint32)tsvalue(top-1)->len +
|
||||
(lint32)tsvalue(top-2)->len;
|
||||
char *buffer;
|
||||
int i;
|
||||
while (n < total && !tostring(L, top-n-1)) { /* collect total length */
|
||||
tl += tsvalue(top-n-1)->len;
|
||||
n++;
|
||||
}
|
||||
if (tl > MAX_SIZET) lua_error(L, "string size overflow");
|
||||
buffer = luaO_openspace(L, tl);
|
||||
tl = 0;
|
||||
for (i=n; i>0; i--) { /* concat all strings */
|
||||
size_t l = tsvalue(top-i)->len;
|
||||
memcpy(buffer+tl, tsvalue(top-i)->str, l);
|
||||
tl += l;
|
||||
}
|
||||
tsvalue(top-n) = luaS_newlstr(L, buffer, tl);
|
||||
}
|
||||
total -= n-1; /* got `n' strings to create 1 new */
|
||||
top -= n-1;
|
||||
} while (total > 1); /* repeat until only 1 result left */
|
||||
}
|
||||
|
||||
|
||||
static void luaV_pack (lua_State *L, StkId firstelem) {
|
||||
int i;
|
||||
Hash *htab = luaH_new(L, 0);
|
||||
for (i=0; firstelem+i<L->top; i++)
|
||||
*luaH_setint(L, htab, i+1) = *(firstelem+i);
|
||||
/* store counter in field `n' */
|
||||
luaH_setstrnum(L, htab, luaS_new(L, "n"), i);
|
||||
L->top = firstelem; /* remove elements from the stack */
|
||||
ttype(L->top) = LUA_TTABLE;
|
||||
hvalue(L->top) = htab;
|
||||
incr_top;
|
||||
}
|
||||
|
||||
|
||||
static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
|
||||
int nvararg = (L->top-base) - nfixargs;
|
||||
if (nvararg < 0)
|
||||
luaD_adjusttop(L, base, nfixargs);
|
||||
luaV_pack(L, base+nfixargs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define dojump(pc, i) { int d = GETARG_S(i); pc += d; }
|
||||
|
||||
/*
|
||||
** Executes the given Lua function. Parameters are between [base,top).
|
||||
** Returns n such that the the results are between [n,top).
|
||||
*/
|
||||
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
||||
const Proto *const tf = cl->f.l;
|
||||
StkId top; /* keep top local, for performance */
|
||||
const Instruction *pc = tf->code;
|
||||
TString **const kstr = tf->kstr;
|
||||
const lua_Hook linehook = L->linehook;
|
||||
infovalue(base-1)->pc = &pc;
|
||||
luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
|
||||
if (tf->is_vararg) /* varargs? */
|
||||
adjust_varargs(L, base, tf->numparams);
|
||||
else
|
||||
luaD_adjusttop(L, base, tf->numparams);
|
||||
top = L->top;
|
||||
/* main loop of interpreter */
|
||||
for (;;) {
|
||||
const Instruction i = *pc++;
|
||||
if (linehook)
|
||||
traceexec(L, base, top, linehook);
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_END: {
|
||||
L->top = top;
|
||||
return top;
|
||||
}
|
||||
case OP_RETURN: {
|
||||
L->top = top;
|
||||
return base+GETARG_U(i);
|
||||
}
|
||||
case OP_CALL: {
|
||||
int nres = GETARG_B(i);
|
||||
if (nres == MULT_RET) nres = LUA_MULTRET;
|
||||
L->top = top;
|
||||
luaD_call(L, base+GETARG_A(i), nres);
|
||||
top = L->top;
|
||||
break;
|
||||
}
|
||||
case OP_TAILCALL: {
|
||||
L->top = top;
|
||||
luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
|
||||
return base+GETARG_B(i);
|
||||
}
|
||||
case OP_PUSHNIL: {
|
||||
int n = GETARG_U(i);
|
||||
LUA_ASSERT(n>0, "invalid argument");
|
||||
do {
|
||||
ttype(top++) = LUA_TNIL;
|
||||
} while (--n > 0);
|
||||
break;
|
||||
}
|
||||
case OP_POP: {
|
||||
top -= GETARG_U(i);
|
||||
break;
|
||||
}
|
||||
case OP_PUSHINT: {
|
||||
ttype(top) = LUA_TNUMBER;
|
||||
nvalue(top) = (Number)GETARG_S(i);
|
||||
top++;
|
||||
break;
|
||||
}
|
||||
case OP_PUSHSTRING: {
|
||||
ttype(top) = LUA_TSTRING;
|
||||
tsvalue(top) = kstr[GETARG_U(i)];
|
||||
top++;
|
||||
break;
|
||||
}
|
||||
case OP_PUSHNUM: {
|
||||
ttype(top) = LUA_TNUMBER;
|
||||
nvalue(top) = tf->knum[GETARG_U(i)];
|
||||
top++;
|
||||
break;
|
||||
}
|
||||
case OP_PUSHNEGNUM: {
|
||||
ttype(top) = LUA_TNUMBER;
|
||||
nvalue(top) = -tf->knum[GETARG_U(i)];
|
||||
top++;
|
||||
break;
|
||||
}
|
||||
case OP_PUSHUPVALUE: {
|
||||
*top++ = cl->upvalue[GETARG_U(i)];
|
||||
break;
|
||||
}
|
||||
case OP_GETLOCAL: {
|
||||
*top++ = *(base+GETARG_U(i));
|
||||
break;
|
||||
}
|
||||
case OP_GETGLOBAL: {
|
||||
L->top = top;
|
||||
*top = *luaV_getglobal(L, kstr[GETARG_U(i)]);
|
||||
top++;
|
||||
break;
|
||||
}
|
||||
case OP_GETTABLE: {
|
||||
L->top = top;
|
||||
top--;
|
||||
*(top-1) = *luaV_gettable(L, top-1);
|
||||
break;
|
||||
}
|
||||
case OP_GETDOTTED: {
|
||||
ttype(top) = LUA_TSTRING;
|
||||
tsvalue(top) = kstr[GETARG_U(i)];
|
||||
L->top = top+1;
|
||||
*(top-1) = *luaV_gettable(L, top-1);
|
||||
break;
|
||||
}
|
||||
case OP_GETINDEXED: {
|
||||
*top = *(base+GETARG_U(i));
|
||||
L->top = top+1;
|
||||
*(top-1) = *luaV_gettable(L, top-1);
|
||||
break;
|
||||
}
|
||||
case OP_PUSHSELF: {
|
||||
TObject receiver;
|
||||
receiver = *(top-1);
|
||||
ttype(top) = LUA_TSTRING;
|
||||
tsvalue(top++) = kstr[GETARG_U(i)];
|
||||
L->top = top;
|
||||
*(top-2) = *luaV_gettable(L, top-2);
|
||||
*(top-1) = receiver;
|
||||
break;
|
||||
}
|
||||
case OP_CREATETABLE: {
|
||||
L->top = top;
|
||||
luaC_checkGC(L);
|
||||
hvalue(top) = luaH_new(L, GETARG_U(i));
|
||||
ttype(top) = LUA_TTABLE;
|
||||
top++;
|
||||
break;
|
||||
}
|
||||
case OP_SETLOCAL: {
|
||||
*(base+GETARG_U(i)) = *(--top);
|
||||
break;
|
||||
}
|
||||
case OP_SETGLOBAL: {
|
||||
L->top = top;
|
||||
luaV_setglobal(L, kstr[GETARG_U(i)]);
|
||||
top--;
|
||||
break;
|
||||
}
|
||||
case OP_SETTABLE: {
|
||||
StkId t = top-GETARG_A(i);
|
||||
L->top = top;
|
||||
luaV_settable(L, t, t+1);
|
||||
top -= GETARG_B(i); /* pop values */
|
||||
break;
|
||||
}
|
||||
case OP_SETLIST: {
|
||||
int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
|
||||
int n = GETARG_B(i);
|
||||
Hash *arr = hvalue(top-n-1);
|
||||
L->top = top-n; /* final value of `top' (in case of errors) */
|
||||
for (; n; n--)
|
||||
*luaH_setint(L, arr, n+aux) = *(--top);
|
||||
break;
|
||||
}
|
||||
case OP_SETMAP: {
|
||||
int n = GETARG_U(i);
|
||||
StkId finaltop = top-2*n;
|
||||
Hash *arr = hvalue(finaltop-1);
|
||||
L->top = finaltop; /* final value of `top' (in case of errors) */
|
||||
for (; n; n--) {
|
||||
top-=2;
|
||||
*luaH_set(L, arr, top) = *(top+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_ADD: {
|
||||
if (tonumber(top-2) || tonumber(top-1))
|
||||
call_arith(L, top, TM_ADD);
|
||||
else
|
||||
nvalue(top-2) += nvalue(top-1);
|
||||
top--;
|
||||
break;
|
||||
}
|
||||
case OP_ADDI: {
|
||||
if (tonumber(top-1)) {
|
||||
ttype(top) = LUA_TNUMBER;
|
||||
nvalue(top) = (Number)GETARG_S(i);
|
||||
call_arith(L, top+1, TM_ADD);
|
||||
}
|
||||
else
|
||||
nvalue(top-1) += (Number)GETARG_S(i);
|
||||
break;
|
||||
}
|
||||
case OP_SUB: {
|
||||
if (tonumber(top-2) || tonumber(top-1))
|
||||
call_arith(L, top, TM_SUB);
|
||||
else
|
||||
nvalue(top-2) -= nvalue(top-1);
|
||||
top--;
|
||||
break;
|
||||
}
|
||||
case OP_MULT: {
|
||||
if (tonumber(top-2) || tonumber(top-1))
|
||||
call_arith(L, top, TM_MUL);
|
||||
else
|
||||
nvalue(top-2) *= nvalue(top-1);
|
||||
top--;
|
||||
break;
|
||||
}
|
||||
case OP_DIV: {
|
||||
if (tonumber(top-2) || tonumber(top-1))
|
||||
call_arith(L, top, TM_DIV);
|
||||
else
|
||||
nvalue(top-2) /= nvalue(top-1);
|
||||
top--;
|
||||
break;
|
||||
}
|
||||
case OP_POW: {
|
||||
if (!call_binTM(L, top, TM_POW))
|
||||
lua_error(L, "undefined operation");
|
||||
top--;
|
||||
break;
|
||||
}
|
||||
case OP_CONCAT: {
|
||||
int n = GETARG_U(i);
|
||||
luaV_strconc(L, n, top);
|
||||
top -= n-1;
|
||||
L->top = top;
|
||||
luaC_checkGC(L);
|
||||
break;
|
||||
}
|
||||
case OP_MINUS: {
|
||||
if (tonumber(top-1)) {
|
||||
ttype(top) = LUA_TNIL;
|
||||
call_arith(L, top+1, TM_UNM);
|
||||
}
|
||||
else
|
||||
nvalue(top-1) = -nvalue(top-1);
|
||||
break;
|
||||
}
|
||||
case OP_NOT: {
|
||||
ttype(top-1) =
|
||||
(ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL;
|
||||
nvalue(top-1) = 1;
|
||||
break;
|
||||
}
|
||||
case OP_JMPNE: {
|
||||
top -= 2;
|
||||
if (!luaO_equalObj(top, top+1)) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPEQ: {
|
||||
top -= 2;
|
||||
if (luaO_equalObj(top, top+1)) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPLT: {
|
||||
top -= 2;
|
||||
if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPLE: { /* a <= b === !(b<a) */
|
||||
top -= 2;
|
||||
if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPGT: { /* a > b === (b<a) */
|
||||
top -= 2;
|
||||
if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPGE: { /* a >= b === !(a<b) */
|
||||
top -= 2;
|
||||
if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPT: {
|
||||
if (ttype(--top) != LUA_TNIL) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPF: {
|
||||
if (ttype(--top) == LUA_TNIL) dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPONT: {
|
||||
if (ttype(top-1) == LUA_TNIL) top--;
|
||||
else dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMPONF: {
|
||||
if (ttype(top-1) != LUA_TNIL) top--;
|
||||
else dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_JMP: {
|
||||
dojump(pc, i);
|
||||
break;
|
||||
}
|
||||
case OP_PUSHNILJMP: {
|
||||
ttype(top++) = LUA_TNIL;
|
||||
pc++;
|
||||
break;
|
||||
}
|
||||
case OP_FORPREP: {
|
||||
if (tonumber(top-1))
|
||||
lua_error(L, "`for' step must be a number");
|
||||
if (tonumber(top-2))
|
||||
lua_error(L, "`for' limit must be a number");
|
||||
if (tonumber(top-3))
|
||||
lua_error(L, "`for' initial value must be a number");
|
||||
if (nvalue(top-1) > 0 ?
|
||||
nvalue(top-3) > nvalue(top-2) :
|
||||
nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
|
||||
top -= 3; /* remove control variables */
|
||||
dojump(pc, i); /* jump to loop end */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_FORLOOP: {
|
||||
LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
|
||||
LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
|
||||
if (ttype(top-3) != LUA_TNUMBER)
|
||||
lua_error(L, "`for' index must be a number");
|
||||
nvalue(top-3) += nvalue(top-1); /* increment index */
|
||||
if (nvalue(top-1) > 0 ?
|
||||
nvalue(top-3) > nvalue(top-2) :
|
||||
nvalue(top-3) < nvalue(top-2))
|
||||
top -= 3; /* end loop: remove control variables */
|
||||
else
|
||||
dojump(pc, i); /* repeat loop */
|
||||
break;
|
||||
}
|
||||
case OP_LFORPREP: {
|
||||
Node *node;
|
||||
if (ttype(top-1) != LUA_TTABLE)
|
||||
lua_error(L, "`for' table must be a table");
|
||||
node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
|
||||
if (node == NULL) { /* `empty' loop? */
|
||||
top--; /* remove table */
|
||||
dojump(pc, i); /* jump to loop end */
|
||||
}
|
||||
else {
|
||||
top += 2; /* index,value */
|
||||
*(top-2) = *key(node);
|
||||
*(top-1) = *val(node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_LFORLOOP: {
|
||||
Node *node;
|
||||
LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
|
||||
node = luaH_next(L, hvalue(top-3), top-2);
|
||||
if (node == NULL) /* end loop? */
|
||||
top -= 3; /* remove table, key, and value */
|
||||
else {
|
||||
*(top-2) = *key(node);
|
||||
*(top-1) = *val(node);
|
||||
dojump(pc, i); /* repeat loop */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_CLOSURE: {
|
||||
L->top = top;
|
||||
luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
|
||||
top = L->top;
|
||||
luaC_checkGC(L);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
** $Id: lvm.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lvm_h
|
||||
#define lvm_h
|
||||
|
||||
|
||||
#include "ldo.h"
|
||||
#include "lobject.h"
|
||||
#include "ltm.h"
|
||||
|
||||
|
||||
#define tonumber(o) ((ttype(o) != LUA_TNUMBER) && (luaV_tonumber(o) != 0))
|
||||
#define tostring(L,o) ((ttype(o) != LUA_TSTRING) && (luaV_tostring(L, o) != 0))
|
||||
|
||||
|
||||
int luaV_tonumber (TObject *obj);
|
||||
int luaV_tostring (lua_State *L, TObject *obj);
|
||||
const TObject *luaV_gettable (lua_State *L, StkId t);
|
||||
void luaV_settable (lua_State *L, StkId t, StkId key);
|
||||
const TObject *luaV_getglobal (lua_State *L, TString *s);
|
||||
void luaV_setglobal (lua_State *L, TString *s);
|
||||
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
|
||||
void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
|
||||
void luaV_Lclosure (lua_State *L, Proto *l, int nelems);
|
||||
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
|
||||
void luaV_strconc (lua_State *L, int total, StkId top);
|
||||
|
||||
#endif
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
** $Id: lzio.c,v 1.1 2003/01/24 16:26:18 jason379 Exp $
|
||||
** a generic input stream interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lzio.h"
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------- memory buffers --- */
|
||||
|
||||
static int zmfilbuf (ZIO* z) {
|
||||
(void)z; /* to avoid warnings */
|
||||
return EOZ;
|
||||
}
|
||||
|
||||
|
||||
ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name) {
|
||||
if (b==NULL) return NULL;
|
||||
z->n = size;
|
||||
z->p = (const unsigned char *)b;
|
||||
z->filbuf = zmfilbuf;
|
||||
z->u = NULL;
|
||||
z->name = name;
|
||||
return z;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ strings --- */
|
||||
|
||||
ZIO* zsopen (ZIO* z, const char* s, const char *name) {
|
||||
if (s==NULL) return NULL;
|
||||
return zmopen(z, s, strlen(s), name);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- FILEs --- */
|
||||
|
||||
static int zffilbuf (ZIO* z) {
|
||||
size_t n;
|
||||
if (feof((FILE *)z->u)) return EOZ;
|
||||
n = fread(z->buffer, 1, ZBSIZE, (FILE *)z->u);
|
||||
if (n==0) return EOZ;
|
||||
z->n = n-1;
|
||||
z->p = z->buffer;
|
||||
return *(z->p++);
|
||||
}
|
||||
|
||||
|
||||
ZIO* zFopen (ZIO* z, FILE* f, const char *name) {
|
||||
if (f==NULL) return NULL;
|
||||
z->n = 0;
|
||||
z->p = z->buffer;
|
||||
z->filbuf = zffilbuf;
|
||||
z->u = f;
|
||||
z->name = name;
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------- read --- */
|
||||
size_t zread (ZIO *z, void *b, size_t n) {
|
||||
while (n) {
|
||||
size_t m;
|
||||
if (z->n == 0) {
|
||||
if (z->filbuf(z) == EOZ)
|
||||
return n; /* return number of missing bytes */
|
||||
zungetc(z); /* put result from `filbuf' in the buffer */
|
||||
}
|
||||
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
|
||||
memcpy(b, z->p, m);
|
||||
z->n -= m;
|
||||
z->p += m;
|
||||
b = (char *)b + m;
|
||||
n -= m;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
** $Id: lzio.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $
|
||||
** Buffered streams
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lzio_h
|
||||
#define lzio_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
/* For Lua only */
|
||||
#define zFopen luaZ_Fopen
|
||||
#define zsopen luaZ_sopen
|
||||
#define zmopen luaZ_mopen
|
||||
#define zread luaZ_read
|
||||
|
||||
#define EOZ (-1) /* end of stream */
|
||||
|
||||
typedef struct zio ZIO;
|
||||
|
||||
ZIO* zFopen (ZIO* z, FILE* f, const char *name); /* open FILEs */
|
||||
ZIO* zsopen (ZIO* z, const char* s, const char *name); /* string */
|
||||
ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name); /* memory */
|
||||
|
||||
size_t zread (ZIO* z, void* b, size_t n); /* read next n bytes */
|
||||
|
||||
#define zgetc(z) (((z)->n--)>0 ? ((int)*(z)->p++): (z)->filbuf(z))
|
||||
#define zungetc(z) (++(z)->n,--(z)->p)
|
||||
#define zname(z) ((z)->name)
|
||||
|
||||
|
||||
|
||||
/* --------- Private Part ------------------ */
|
||||
|
||||
#ifndef ZBSIZE
|
||||
#define ZBSIZE 256 /* buffer size */
|
||||
#endif
|
||||
|
||||
struct zio {
|
||||
size_t n; /* bytes still unread */
|
||||
const unsigned char* p; /* current position in buffer */
|
||||
int (*filbuf)(ZIO* z);
|
||||
void* u; /* additional data */
|
||||
const char *name;
|
||||
unsigned char buffer[ZBSIZE]; /* buffer */
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,74 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - clean.c
|
||||
//
|
||||
// Remove all project and intermediate files.
|
||||
//
|
||||
// Copyright (C) 2002-2003 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: clean.c,v 1.6 2004/03/27 13:42:24 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int makeClean()
|
||||
{
|
||||
int i, j;
|
||||
const char* binaries = project->binaries;
|
||||
const char* libraries = project->libraries;
|
||||
|
||||
puts("Removing all project and intermediate files...");
|
||||
|
||||
deleteFile(project->path, project->name, ".sln"); // VS200x
|
||||
deleteFile(project->path, project->name, ".suo"); // VS200x
|
||||
deleteFile(project->path, project->name, ".ncb"); // VS6/200x
|
||||
deleteFile(project->path, project->name, ".dsw"); // VS6
|
||||
deleteFile(project->path, project->name, ".opt"); // VS6
|
||||
deleteFile(project->path, "Makefile", ""); // GNU
|
||||
deleteFile(project->path, project->name, ".cmbx"); // SharpDevelop
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
const char* name = package->name;
|
||||
const char* path = package->path;
|
||||
|
||||
for (j = 0; j < package->numConfigs; ++j)
|
||||
{
|
||||
char buffer[256];
|
||||
Config* config = package->config[j];
|
||||
const char* target = config->target;
|
||||
|
||||
strcpy(buffer, "lib"); // posix shared lib
|
||||
strcat(buffer, target);
|
||||
deleteFile(binaries, buffer, ".so");
|
||||
|
||||
deleteFile(binaries, target, ""); // posix executable
|
||||
deleteFile(binaries, target, ".exe"); // windows executable
|
||||
deleteFile(binaries, target, ".dll"); // windows or .NET shared lib
|
||||
deleteFile(binaries, target, ".pdb"); // VS symbol file
|
||||
deleteFile(binaries, target, ".ilk"); // VS incremental link
|
||||
deleteFile(libraries, target, ".pdb"); // VS symbol file
|
||||
deleteFile(libraries, target, ".exp"); // VS export lib
|
||||
deleteFile(libraries, target, ".lib"); // windows static lib
|
||||
}
|
||||
|
||||
deleteFile(path, name, ".csproj"); // VS200x
|
||||
deleteFile(path, name, ".csproj.user"); // VS200x
|
||||
deleteFile(path, name, ".csproj.webinfo"); // VS200x
|
||||
deleteFile(path, name, ".vcproj"); // VS200x
|
||||
deleteFile(path, name, ".dsp"); // VS6
|
||||
deleteFile(path, name, ".plg"); // VS6
|
||||
deleteFile(path, name, ".make"); // GNU
|
||||
deleteFile(path, name, ".prjx"); // SharpDevelop
|
||||
|
||||
deleteDirectory(path, "obj"); // intermediates directory
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
@ -1,585 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - gnu.c
|
||||
//
|
||||
// GNU tool target.
|
||||
//
|
||||
// Copyright (C) 2002-2004 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: gnu.c,v 1.26 2004/05/05 23:23:44 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
|
||||
#define MAKEFILE_EXT ".make"
|
||||
#define OBJECTS_DIR "obj"
|
||||
#define OBJECTS_EXT ".o"
|
||||
|
||||
extern const char** commandLineArgs;
|
||||
extern const char* rootProjectFile;
|
||||
extern const char* cc;
|
||||
extern const char* dotnet;
|
||||
extern int verbose;
|
||||
|
||||
static int writeRootMakefile();
|
||||
static int writeCppPackage(Package* package);
|
||||
static int writeCsPackage(Package* package);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int makeGnuScripts()
|
||||
{
|
||||
int i;
|
||||
|
||||
puts("Generating GNU makefiles:");
|
||||
|
||||
if (!writeRootMakefile())
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
int result;
|
||||
Package* package = project->package[i];
|
||||
const char* language = package->language;
|
||||
|
||||
printf("...%s\n", package->name);
|
||||
|
||||
if (strcmp(language, "c#") == 0)
|
||||
result = writeCsPackage(package);
|
||||
else if (strcmp(language, "c++") == 0 || strcmp(language, "c") == 0)
|
||||
result = writeCppPackage(package);
|
||||
else
|
||||
{
|
||||
printf("** Error: unrecognized language '%s'\n", language);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!result) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* checkDeps(const char* ref, void* data)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
if (strcmp(project->package[i]->name, ref) == 0)
|
||||
return project->package[i]->name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int writeRootMakefile()
|
||||
{
|
||||
int i;
|
||||
FILE* file;
|
||||
|
||||
file = openFile(project->path, "Makefile", "");
|
||||
if (file == NULL)
|
||||
{
|
||||
puts("Error: unable to open Makefile\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Print the header, showing the possible build configurations
|
||||
|
||||
fprintf(file, "# Makefile autogenerated by premake\n");
|
||||
fprintf(file, "# Options:\n");
|
||||
fprintf(file, "# CONFIG=[");
|
||||
for (i = 0; i < project->package[0]->numConfigs; ++i)
|
||||
{
|
||||
if (i > 0) fprintf(file, "|");
|
||||
fprintf(file, project->package[0]->config[i]->name);
|
||||
}
|
||||
|
||||
fprintf(file, "]\n\n");
|
||||
|
||||
// Set a default build config if none specified
|
||||
|
||||
fprintf(file, "ifndef CONFIG\n");
|
||||
fprintf(file, " CONFIG=%s\n", project->package[0]->config[0]->name);
|
||||
fprintf(file, "endif\n\n");
|
||||
fprintf(file, "export CONFIG\n\n");
|
||||
|
||||
// List all of the available make targets
|
||||
|
||||
fprintf(file, ".PHONY: all clean");
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
fprintf(file, " %s", project->package[i]->name);
|
||||
fprintf(file, "\n\n");
|
||||
|
||||
// Make rules
|
||||
|
||||
fprintf(file, "all:");
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
fprintf(file, " %s", project->package[i]->name);
|
||||
fprintf(file, "\n\n");
|
||||
|
||||
// Target to regenerate the makefiles when the premake scripts change
|
||||
|
||||
fprintf(file, "Makefile: %s%s", reversePath(project->path, ".", UNIX), rootProjectFile);
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
if (project->package[i]->script != NULL)
|
||||
fprintf(file, " %s%s", reversePath(project->path, ".", UNIX), project->package[i]->script);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "\t@echo ==== Regenerating Makefiles ====\n");
|
||||
fprintf(file, "\t@premake");
|
||||
for (i = 1; args[i] != NULL; ++i)
|
||||
fprintf(file, " %s", args[i]);
|
||||
fprintf(file, "\n\n");
|
||||
|
||||
// Individual package targets
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
|
||||
fprintf(file, "%s:", package->name);
|
||||
writeList(file, package->config[0]->links, " ", "", "", checkDeps, NULL);
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, "\t@echo ==== Building %s ====\n", package->name);
|
||||
fprintf(file, "\t@$(MAKE) ");
|
||||
fprintf(file, "--no-print-directory -C %s ", reversePath(project->path, package->path, UNIX));
|
||||
fprintf(file, "-f %s%s\n", package->name, MAKEFILE_EXT);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
fprintf(file, "clean:\n");
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
|
||||
fprintf(file, "\t@$(MAKE) ");
|
||||
fprintf(file, "--no-print-directory -C %s ", reversePath(project->path, package->path, UNIX));
|
||||
fprintf(file, "-f %s%s clean\n", package->name, MAKEFILE_EXT);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
char buffer[4096];
|
||||
static const char* checkCppSources(const char* file, void* data)
|
||||
{
|
||||
if (isCppFile(file))
|
||||
{
|
||||
strcpy(buffer, getFilename(file, 0));
|
||||
strcat(buffer, ".o");
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* checkCppFlags(const char* flag, void* data)
|
||||
{
|
||||
char* cc = (char*)data;
|
||||
|
||||
if (strcmp(flag, "with-symbols") == 0)
|
||||
return "-g";
|
||||
else if (strcmp(flag, "optimize-size") == 0)
|
||||
return "-Os";
|
||||
else if (strcmp(flag, "optimize-speed") == 0)
|
||||
return "-O3";
|
||||
else if (strcmp(flag, "no-rtti") == 0 && strcmp(cc, "C++") == 0)
|
||||
return "--no-rtti";
|
||||
else if (strcmp(flag, "no-exceptions") == 0 && strcmp(cc, "C++") == 0)
|
||||
return "--no-exceptions";
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void writeSourcePaths(FILE* file, const char* path, const char* prefix, int stage)
|
||||
{
|
||||
if (stage == WST_OPENGROUP && strlen(path) > 0)
|
||||
fprintf(file, " %s", path);
|
||||
}
|
||||
|
||||
static const char* checkLink(const char* path, void* data)
|
||||
{
|
||||
Package* package = getPackage(path);
|
||||
if (package == NULL) return path;
|
||||
|
||||
if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0)
|
||||
return package->config[*((int*)data)]->target;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int writeCppPackage(Package* package)
|
||||
{
|
||||
const char* prefix = (verbose) ? "" : "@";
|
||||
|
||||
char buffer[4096];
|
||||
const char* cflags;
|
||||
const char* ldflags;
|
||||
FILE* file;
|
||||
int i;
|
||||
|
||||
const char* name = package->name;
|
||||
const char* path = package->path;
|
||||
const char* kind = package->kind;
|
||||
|
||||
const char* location;
|
||||
|
||||
// Set up the flags specific to the type of binary being built
|
||||
|
||||
cflags = "";
|
||||
ldflags = "";
|
||||
location = "$(BINDIR)";
|
||||
|
||||
if (strcmp(kind, "exe") == 0 || strcmp(kind, "winexe") == 0)
|
||||
{
|
||||
/* defaults are fine */
|
||||
}
|
||||
else if (strcmp(kind, "dll") == 0)
|
||||
{
|
||||
if (strcmp(osIdent, "windows") != 0)
|
||||
cflags = " -fPIC";
|
||||
if (cc == NULL || strcmp(cc, "gcc") == 0)
|
||||
ldflags = " -shared";
|
||||
}
|
||||
else if (strcmp(kind, "lib") == 0)
|
||||
{
|
||||
location = "$(LIBDIR)";
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown package type '%s'\n", kind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Open package makefile and write the header
|
||||
|
||||
file = openFile(path, name, MAKEFILE_EXT);
|
||||
if (file == NULL) return 0;
|
||||
|
||||
fprintf(file, "# Sub-makefile autogenerated by premake\n\n");
|
||||
|
||||
// Build bin and lib paths, trim off trailing slash
|
||||
strcpy(buffer, reversePath(path, project->binaries, UNIX));
|
||||
buffer[strlen(buffer)-1] = '\0';
|
||||
fprintf(file, "BINDIR = %s\n", buffer);
|
||||
|
||||
strcpy(buffer, reversePath(path, project->libraries, UNIX));
|
||||
buffer[strlen(buffer)-1] = '\0';
|
||||
fprintf(file, "LIBDIR = %s\n\n", buffer);
|
||||
|
||||
fprintf(file, "CFLAGS =%s\n", cflags);
|
||||
fprintf(file, "LDFLAGS = -L$(BINDIR) -L$(LIBDIR)%s\n", ldflags);
|
||||
fprintf(file, "TARGET =\n");
|
||||
if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0)
|
||||
fprintf(file, "MACAPP = \n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
// Process the build configurations
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
Config* config = package->config[i];
|
||||
fprintf(file, "ifeq ($(CONFIG),%s)\n", config->name);
|
||||
|
||||
fprintf(file, " CFLAGS +=");
|
||||
writeList(file, config->buildOptions, " ", "", "", NULL, "C");
|
||||
writeList(file, config->buildFlags, " ", "", "", checkCppFlags, "C");
|
||||
|
||||
if (strcmp(osIdent, "windows") == 0)
|
||||
fprintf(file, " -D_WIN32");
|
||||
writeList(file, config->defines, " -D \"", "\"", "", NULL, NULL);
|
||||
writeList(file, config->includePaths, " -I ", "", "", NULL, NULL);
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, " CXXFLAGS = $(CFLAGS)");
|
||||
writeList(file, config->buildOptions, " ", "", "", NULL, "C++");
|
||||
writeList(file, config->buildFlags, " ", "", "", checkCppFlags, "C++");
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, " LDFLAGS +=");
|
||||
writeList(file, config->linkOptions, " ", "", "", NULL, NULL);
|
||||
writeList(file, config->linkFlags, " ", "", "", NULL, NULL);
|
||||
writeList(file, config->libPaths, " -L ", "", "", NULL, NULL);
|
||||
writeList(file, config->links, " -l", "", "", checkLink, &i);
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, " TARGET = ");
|
||||
if (strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0)
|
||||
{
|
||||
if (strcmp(kind, "winexe") == 0 && strcmp(osIdent, "macosx") == 0)
|
||||
{
|
||||
fprintf(file, "%s.app/Contents/MacOS/%s\n", config->target, config->target);
|
||||
fprintf(file, " MACAPP = %s\n", config->target);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "%s\n", config->target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "%s/", getDirectory(config->target));
|
||||
if (strcmp(kind, "lib") == 0)
|
||||
{
|
||||
fprintf(file, "lib%s.a\n", getFilename(config->target, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(osIdent, "windows") == 0)
|
||||
fprintf(file, "%s.dll\n", getFilename(config->target, 0));
|
||||
else
|
||||
fprintf(file, "lib%s.so\n", getFilename(config->target, 0));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "endif\n");
|
||||
}
|
||||
|
||||
fprintf(file, "\n");
|
||||
|
||||
// These rules auto-create dependency lists (see "Advanced Auto-Dependency
|
||||
// Generation at http://www.paulandlesley.org/gmake/autodep.html) and place
|
||||
// the *.P and *.o files in $(OBJ_DIR)
|
||||
|
||||
// Note all of these targets do the same thing. Is there a way to reuse the
|
||||
// command block? Didn't see anything in the make manual, though it would
|
||||
// seem this is something people would want to do.
|
||||
|
||||
for (i = 0; CPP_EXT[i]; ++i)
|
||||
{
|
||||
fprintf(file, "%s/%%%s.o : %%%s\n", OBJECTS_DIR, CPP_EXT[i], CPP_EXT[i]);
|
||||
fprintf(file, "\t-%sif [ ! -d %s ]; then mkdir %s; fi\n", prefix, OBJECTS_DIR, OBJECTS_DIR);
|
||||
if (!verbose)
|
||||
fprintf(file, "\t@echo $(notdir $<)\n");
|
||||
|
||||
if (cc != NULL && strcmp(cc, "dmc") == 0)
|
||||
{
|
||||
if (strcmp(CPP_EXT[i], ".c") == 0)
|
||||
fprintf(file, "\t%sdmc $(CFLAGS) -o $@ -c $<\n", prefix);
|
||||
else if (strcmp(CPP_EXT[i], ".asm") != 0)
|
||||
fprintf(file, "\t%sdmc -cpp -Ae -Ar -mn -D_WINDOWS $(CXXFLAGS) -o $@ -c $<\n", prefix);
|
||||
|
||||
fprintf(file, "\t-%sif [ -f $(<F).d ]; then mv $(<F).d %s/$(<F).d; fi\n", prefix, OBJECTS_DIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(CPP_EXT[i], ".c") == 0)
|
||||
fprintf(file, "\t%s$(CC) $(CFLAGS) -MD -MF obj/$(<F).d -o $@ -c $<\n", prefix);
|
||||
else if (strcmp(CPP_EXT[i], ".asm") == 0)
|
||||
{
|
||||
/* nasm -f elf -o $@ $<
|
||||
nasm -M -o $@ $< >OBJ_DIR/$*.P */
|
||||
const char *extraOpts="";
|
||||
if (strcmp(osIdent, "windows"))
|
||||
extraOpts="-dDONT_USE_UNDERLINE=1";
|
||||
fprintf(file, "\t%snasm %s -f elf -o $@ $<\n", prefix, extraOpts);
|
||||
fprintf(file, "\t%snasm %s -M -o $@ $< >obj/$(<F).d\n", prefix, extraOpts);
|
||||
}
|
||||
else
|
||||
fprintf(file, "\t%s$(CXX) $(CXXFLAGS) -MD -MF obj/$(<F).d -o $@ -c $<\n", prefix);
|
||||
}
|
||||
|
||||
fprintf(file, "\t%ssed -e 's@.*:@%s/$(<F).o:@' < %s/$(<F).d > %s/$(<F).P; \\\n", prefix, OBJECTS_DIR, OBJECTS_DIR, OBJECTS_DIR);
|
||||
fprintf(file, "\t sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\\\$$//' \\\n");
|
||||
fprintf(file, "\t -e '/^$$/ d' -e 's/$$/ :/' < %s/$(<F).d >> %s/$(<F).P; \\\n", OBJECTS_DIR, OBJECTS_DIR);
|
||||
fprintf(file, "\trm -f %s/$(<F).d\n\n", OBJECTS_DIR);
|
||||
}
|
||||
|
||||
// Write out the list of object file targets for all C/C++ sources
|
||||
|
||||
fprintf(file, "OBJECTS = \\\n");
|
||||
writeList(file, package->files, "\tobj/", " \\\n", "", checkCppSources, NULL);
|
||||
fprintf(file, "\n");
|
||||
|
||||
// Write out the list of source directories
|
||||
|
||||
fprintf(file, "VPATH =");
|
||||
walkSourceList(file, package, "", writeSourcePaths);
|
||||
fprintf(file, "\n\n");
|
||||
|
||||
fprintf(file, ".PHONY: clean\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0)
|
||||
{
|
||||
fprintf(file, "all: $(BINDIR)/$(MACAPP).app/Contents/PkgInfo $(BINDIR)/$(MACAPP).app/Contents/Info.plist $(BINDIR)/$(TARGET)\n\n");
|
||||
}
|
||||
|
||||
fprintf(file, "%s/$(TARGET): $(OBJECTS)\n", location);
|
||||
fprintf(file, "\t@echo Linking %s\n", package->name);
|
||||
fprintf(file, "\t-%sif [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi\n", prefix);
|
||||
fprintf(file, "\t-%sif [ ! -d $(LIBDIR) ]; then mkdir -p $(LIBDIR); fi\n", prefix);
|
||||
if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0)
|
||||
fprintf(file, "\t-%sif [ ! -d $(BINDIR)/$(MACAPP).app/Contents/MacOS ]; then mkdir -p $(BINDIR)/$(MACAPP).app/Contents/MacOS; fi\n", prefix);
|
||||
|
||||
if (strcmp(kind, "lib") == 0)
|
||||
{
|
||||
fprintf(file, "\t%sar -cr $@ $^\n", prefix);
|
||||
fprintf(file, "\t%sranlib $@\n", prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "\t%s$(CXX) -o $@ $(filter-out %%.so, $^) $(LDFLAGS)\n", prefix);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
|
||||
if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0)
|
||||
{
|
||||
fprintf(file, "$(BINDIR)/$(MACAPP).app/Contents/PkgInfo:\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, "$(BINDIR)/$(MACAPP).app/Contents/Info.plist:\n");
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
fprintf(file, "clean:\n");
|
||||
fprintf(file, "\t@echo Cleaning %s\n", package->name);
|
||||
if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0)
|
||||
{
|
||||
fprintf(file, "\t-%srm -rf %s/$(MACAPP).app %s/*\n", prefix, location, OBJECTS_DIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "\t-%srm -rf %s/$(TARGET) %s/*\n", prefix, location, OBJECTS_DIR);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, "-include $(OBJECTS:%%.o=%%.P)\n\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* checkReferences(const char* file, void* data)
|
||||
{
|
||||
Package* package = getPackage(file);
|
||||
if (package == NULL) return file;
|
||||
if (strcmp(package->language, "c#") != 0) return NULL;
|
||||
return package->config[*((int*)data)]->target;
|
||||
}
|
||||
|
||||
static const char* checkCsSources(const char* file, void* data)
|
||||
{
|
||||
if (strcmp(getExtension(file), ".cs") == 0)
|
||||
return file;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int writeCsPackage(Package* package)
|
||||
{
|
||||
const char* extension;
|
||||
const char* csc;
|
||||
FILE* file;
|
||||
int i;
|
||||
|
||||
// Figure out what I'm building
|
||||
|
||||
const char* name = package->name;
|
||||
const char* path = package->path;
|
||||
const char* kind = package->kind;
|
||||
|
||||
if (strcmp(kind, "dll") == 0 || strcmp(kind, "aspnet") == 0)
|
||||
{
|
||||
extension = ".dll";
|
||||
kind = "library";
|
||||
}
|
||||
else if (strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0)
|
||||
{
|
||||
extension = ".exe";
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown package type '%s'\n", kind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Figure out what I'm building it with
|
||||
|
||||
if (dotnet == NULL)
|
||||
{
|
||||
if (strcmp(osIdent, "windows") == 0)
|
||||
csc = "csc /nologo";
|
||||
else
|
||||
csc = "mcs";
|
||||
}
|
||||
else if (strcmp(dotnet, "ms") == 0)
|
||||
csc = "csc";
|
||||
else if (strcmp(dotnet, "pnet") == 0)
|
||||
csc = "cscc";
|
||||
else if (strcmp(dotnet, "mono") == 0)
|
||||
csc = "mcs";
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown .NET runtime '%s'\n", dotnet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Open the package Makefile and write the header
|
||||
|
||||
file = openFile(path, name, MAKEFILE_EXT);
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
fprintf(file, "# Sub-makefile autogenerated by premake\n\n");
|
||||
|
||||
fprintf(file, "BINDIR = %s\n\n", reversePath(path, project->binaries, UNIX));
|
||||
|
||||
fprintf(file, "FLAGS =\n");
|
||||
fprintf(file, "TARGET =\n\n");
|
||||
|
||||
// Process the build configurations
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
Config* config = package->config[i];
|
||||
int symbols = !inArray(config->buildFlags,"no-symbols");
|
||||
int optimize = inArray(config->buildFlags,"optimize")||inArray(config->buildFlags,"optimize-size")||inArray(config->buildFlags,"optimize-speed");
|
||||
int unsafe = inArray(config->buildFlags,"unsafe");
|
||||
|
||||
fprintf(file, "ifeq ($(CONFIG),%s)\n", config->name);
|
||||
|
||||
fprintf(file, " FLAGS +=");
|
||||
if (symbols) fprintf(file, " /debug");
|
||||
if (unsafe) fprintf(file, " /unsafe");
|
||||
writeList(file, config->defines, " /d:", "", "", NULL, NULL);
|
||||
writeList(file, config->libPaths, " /lib:", "", "", NULL, NULL);
|
||||
writeList(file, config->links, " /r:", ".dll", "", checkReferences, &i);
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, " TARGET = %s%s\n", config->target, extension);
|
||||
fprintf(file, "endif\n");
|
||||
}
|
||||
|
||||
// Create the list of files
|
||||
|
||||
fprintf(file, "\nSOURCES = \\\n");
|
||||
writeList(file, package->files, "\t", " \\\n", "", checkCsSources, NULL);
|
||||
fprintf(file, "\n");
|
||||
|
||||
// Build targets
|
||||
|
||||
fprintf(file, "\n.PHONY: clean\n\n");
|
||||
|
||||
fprintf(file, "$(BINDIR)/$(TARGET): $(SOURCES)\n");
|
||||
fprintf(file, "\t-@if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi\n");
|
||||
fprintf(file, "\t@%s /out:$@ /t:%s -lib:$(BINDIR) $(FLAGS) $^\n\n", csc, kind);
|
||||
|
||||
fprintf(file, "clean:\n");
|
||||
fprintf(file, "\t@echo Cleaning %s\n", name);
|
||||
fprintf(file, "\t-@rm -f $(BINDIR)/$(TARGET)\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - posix.c
|
||||
//
|
||||
// POSIX file and directory manipulation functions.
|
||||
//
|
||||
// Written by Jason Perkins (jason@379.com)
|
||||
// Copyright (C) 2002 by 379, Inc.
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: posix.c,v 1.10 2004/04/16 22:18:38 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <glob.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
char nativePathSep = '/';
|
||||
|
||||
#if defined(__linux__)
|
||||
const char* osIdent = "linux";
|
||||
#elif defined(__FreeBSD__)
|
||||
const char* osIdent = "freebsd";
|
||||
#elif defined(__NetBSD__)
|
||||
const char* osIdent = "netbsd";
|
||||
#elif defined(__OpenBSD__)
|
||||
const char* osIdent = "openbsd";
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
const char* osIdent = "macosx";
|
||||
#else
|
||||
#error Unknown OS type.
|
||||
#endif
|
||||
|
||||
static glob_t globbuf;
|
||||
static int iGlob;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_chdir(const char* path)
|
||||
{
|
||||
return !chdir(path);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_copyFile(const char* src, const char* dest)
|
||||
{
|
||||
char buffer[4096];
|
||||
sprintf(buffer, "cp %s %s", src, dest);
|
||||
return (system(buffer) == 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void plat_deleteDir(const char* path)
|
||||
{
|
||||
char buffer[1024];
|
||||
strcpy(buffer, "rm -rf ");
|
||||
strcat(buffer, path);
|
||||
system(buffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void plat_deleteFile(const char* path)
|
||||
{
|
||||
unlink(path);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int findLib(const char* lib, const char* path)
|
||||
{
|
||||
char buffer[2048];
|
||||
struct stat sb;
|
||||
|
||||
sprintf(buffer, "%s/lib%s.so", path, lib);
|
||||
if (stat(buffer, &sb) == 0 && !S_ISDIR(sb.st_mode)) return 1;
|
||||
|
||||
sprintf(buffer, "%s/%s.so", path, lib);
|
||||
if (stat(buffer, &sb) == 0 && !S_ISDIR(sb.st_mode)) return 1;
|
||||
|
||||
sprintf(buffer, "%s/%s", path, lib);
|
||||
if (stat(buffer, &sb) == 0 && !S_ISDIR(sb.st_mode)) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plat_findLib(const char* lib, char* buffer, int size)
|
||||
{
|
||||
FILE* file;
|
||||
|
||||
if (findLib(lib, "/usr/lib"))
|
||||
{
|
||||
strcpy(buffer, "/usr/lib");
|
||||
return 1;
|
||||
}
|
||||
|
||||
file = fopen("/etc/ld.so.conf", "rt");
|
||||
if (file == NULL) return 0;
|
||||
|
||||
while (!feof(file))
|
||||
{
|
||||
// Read a line and trim off any trailing whitespace
|
||||
char linebuffer[2048];
|
||||
char* ptr;
|
||||
|
||||
fgets(buffer, 2048, file);
|
||||
ptr = &buffer[strlen(buffer) - 1];
|
||||
while (isspace(*ptr))
|
||||
*(ptr--) = '\0';
|
||||
|
||||
if (findLib(lib, buffer))
|
||||
{
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_generateUUID(char* uuid)
|
||||
{
|
||||
FILE* rnd = fopen("/dev/random", "rb");
|
||||
fread(uuid, 16, 1, rnd);
|
||||
fclose(rnd);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void plat_getcwd(char* buffer, int size)
|
||||
{
|
||||
getcwd(buffer, size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_isAbsPath(const char* buffer)
|
||||
{
|
||||
return (buffer[0] == '/');
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_dirOpen(const char* mask)
|
||||
{
|
||||
globbuf.gl_offs = 0;
|
||||
globbuf.gl_pathc = 0;
|
||||
globbuf.gl_pathv = NULL;
|
||||
glob(mask, GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf);
|
||||
iGlob = -1;
|
||||
}
|
||||
|
||||
void plat_dirClose()
|
||||
{
|
||||
globfree(&globbuf);
|
||||
}
|
||||
|
||||
int plat_dirGetNext()
|
||||
{
|
||||
return (++iGlob < globbuf.gl_pathc);
|
||||
}
|
||||
|
||||
const char* plat_dirGetName()
|
||||
{
|
||||
char* ptr = strrchr(globbuf.gl_pathv[iGlob], '/');
|
||||
ptr = (ptr == NULL) ? globbuf.gl_pathv[iGlob] : ptr + 1;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int plat_dirIsFile()
|
||||
{
|
||||
return 1;
|
||||
}
|
@ -1,218 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - premake.c
|
||||
//
|
||||
// Program entry point and project/package file parsing.
|
||||
//
|
||||
// Copyright (C) 2002-2004 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: premake.c,v 1.46 2004/05/05 23:23:44 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
#include "Lua/lua.h"
|
||||
|
||||
#define VERSION "1.9"
|
||||
#define COPYRIGHT "Copyright (C) 2002-2004 Jason Perkins"
|
||||
|
||||
extern int makeGnuScripts();
|
||||
extern int makeSharpDevScripts();
|
||||
extern int makeVs6Scripts();
|
||||
extern int makeVsXmlScripts(int version);
|
||||
extern int makeClean();
|
||||
|
||||
static void showCompilers();
|
||||
static void showOptions();
|
||||
static void showTargets();
|
||||
static void showUsage();
|
||||
static void showCredits();
|
||||
|
||||
const char** commandLineArgs;
|
||||
const char* rootProjectFile = NULL;
|
||||
const char* cc = NULL;
|
||||
const char* dotnet = NULL;
|
||||
int verbose = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
char* filename = "premake.lua";
|
||||
args = argv;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
puts("Type 'premake --help' for help");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Look for a '--file' command to override the default
|
||||
for (i = 0; argv[i] != NULL; ++i)
|
||||
{
|
||||
if (strcmp(argv[i], "--file") == 0)
|
||||
{
|
||||
if (argv[i + 1] == NULL || strncmp(argv[i + 1], "--", 2) == 0)
|
||||
{
|
||||
fprintf(stderr, "Usage: --file filename");
|
||||
return 0;
|
||||
}
|
||||
|
||||
filename = argv[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// chdir() to the directory containing the project, so that relative
|
||||
// paths to the packages will work
|
||||
setCwd(getDirectory(filename));
|
||||
|
||||
// Remember the root project filename. This is used by the gmake generator
|
||||
// to rebuild the makefiles when the premake files change
|
||||
rootProjectFile = filename;
|
||||
|
||||
createProject(argv);
|
||||
if (!loadProject(filename))
|
||||
return 1;
|
||||
|
||||
// Project must have at least one package
|
||||
if (project->numPackages == 0)
|
||||
{
|
||||
puts("** Error: project must have at least one package.");
|
||||
closeProject();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Process the command-line options
|
||||
for (i = 0; argv[i] != NULL; ++i)
|
||||
{
|
||||
if (strncmp(argv[i], "--", 2) == 0)
|
||||
{
|
||||
if (strcmp(argv[i], "--file") == 0)
|
||||
{
|
||||
/* Already handled above */ ;
|
||||
}
|
||||
else if (strcmp(argv[i], "--help") == 0)
|
||||
{
|
||||
showUsage();
|
||||
}
|
||||
else if (strcmp(argv[i], "--version") == 0)
|
||||
{
|
||||
printf("premake (Premake Build Script Generator) %s\n", VERSION);
|
||||
}
|
||||
else if (strcmp(argv[i], "--show-options") == 0 ||
|
||||
strcmp(argv[i], "--show-compilers") == 0 ||
|
||||
strcmp(argv[i], "--show-targets") == 0)
|
||||
{
|
||||
/* deprecated commands */
|
||||
printf("The option '%s' has been deprecated.\n", argv[i]);
|
||||
printf("Type 'premake --help' for help.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
handleCommand(argv, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closeProject();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void defaultCommand(int argc, const char* argv[])
|
||||
{
|
||||
int result, i;
|
||||
|
||||
if (strcmp(argv[0], "target") == 0)
|
||||
{
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
if (strcmp(argv[i], "gnu") == 0)
|
||||
result = makeGnuScripts();
|
||||
else if (strcmp(argv[i], "sd") == 0)
|
||||
result = makeSharpDevScripts();
|
||||
else if (strcmp(argv[i], "vs6") == 0)
|
||||
result = makeVs6Scripts();
|
||||
else if (strcmp(argv[i], "vs7") == 0 || strcmp(argv[i], "vs2002") == 0)
|
||||
result = makeVsXmlScripts(7);
|
||||
else if (strcmp(argv[i], "vs2003") == 0)
|
||||
result = makeVsXmlScripts(2003);
|
||||
else
|
||||
{
|
||||
printf("** Unrecognized target '%s'\n", argv[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result) break;
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[0], "clean") == 0)
|
||||
{
|
||||
makeClean();
|
||||
}
|
||||
else if (strcmp(argv[0], "cc") == 0)
|
||||
{
|
||||
cc = argv[1];
|
||||
}
|
||||
else if (strcmp(argv[0], "dotnet") == 0)
|
||||
{
|
||||
dotnet = argv[1];
|
||||
}
|
||||
else if (strcmp(argv[0], "verbose") == 0)
|
||||
{
|
||||
verbose = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void showUsage()
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Premake %s, a build script generator\n", VERSION);
|
||||
puts(COPYRIGHT);
|
||||
printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT);
|
||||
puts("");
|
||||
puts(" --file name Process the specified premake script file");
|
||||
puts("");
|
||||
puts(" --clean Remove all binaries and build scripts");
|
||||
puts(" --verbose Generate verbose makefiles (where applicable)");
|
||||
puts("");
|
||||
puts(" --cc name Choose a C/C++ compiler, if supported by target; one of:");
|
||||
puts(" gcc GNU gcc compiler");
|
||||
puts(" dmc Digital Mars C/C+ compiler");
|
||||
puts("");
|
||||
puts(" --dotnet name Choose a .NET compiler set, if supported by target; one of:");
|
||||
puts(" ms Microsoft (csc)");
|
||||
puts(" mono Mono (msc)");
|
||||
puts(" pnet Portable.NET (cscc)");
|
||||
puts("");
|
||||
puts(" --target name Generate input files for the specified toolset; one of:");
|
||||
puts(" gnu GNU Makefile for POSIX, MinGW, and Cygwin");
|
||||
puts(" sd ICSharpCode SharpDevelop");
|
||||
puts(" vs6 Microsoft Visual Studio 6");
|
||||
puts(" vs7 Microsoft Visual Studio 7");
|
||||
puts(" vs2003 Microsoft Visual Studio 2003");
|
||||
puts("");
|
||||
puts(" --help Display this information");
|
||||
puts(" --version Display version information");
|
||||
puts("");
|
||||
|
||||
if (project != NULL && project->numOptions > 0)
|
||||
{
|
||||
puts("This premake configuration also supports the following custom options:");
|
||||
puts("");
|
||||
|
||||
for (i = 0; i < project->numOptions; ++i)
|
||||
printf(" --%-14s %s\n", project->option[i]->flag, project->option[i]->description);
|
||||
}
|
||||
|
||||
puts("");
|
||||
}
|
@ -1,943 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - project.c
|
||||
//
|
||||
// Functions to load and access the project data, along with all of the helper
|
||||
// functions used by the project scripts.
|
||||
//
|
||||
// Copyright (C) 2002-2004 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: project.c,v 1.18 2004/04/14 00:15:26 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "Lua/lua.h"
|
||||
#include "Lua/lualib.h"
|
||||
#include "Lua/lauxlib.h"
|
||||
#include "Lua/ldebug.h"
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
|
||||
extern void defaultCommand(int argc, const char** argv);
|
||||
|
||||
Project* project = NULL;
|
||||
|
||||
static lua_State* L;
|
||||
static const char* currentScript = NULL;
|
||||
|
||||
static int finishProject();
|
||||
|
||||
static int getArray(int ref, const char* name);
|
||||
static int getArraySize(int ref);
|
||||
static int getDeepArraySize(int ref);
|
||||
static int getObjectFromArray(int ref, int i);
|
||||
static const char* getStringFromArray(int ref, int index);
|
||||
static double getNumber(int ref, char* name);
|
||||
|
||||
static int addoption(lua_State* L);
|
||||
static int copyfile(lua_State* L);
|
||||
static int docommand(lua_State* L);
|
||||
static int dopackage(lua_State* L);
|
||||
static int ERRORMESSAGE(lua_State* L);
|
||||
static int getglobal(lua_State* L);
|
||||
static int findlib(lua_State* L);
|
||||
static int matchfiles(lua_State* L);
|
||||
static int newpackage(lua_State* L);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void createProject(char* argv[])
|
||||
{
|
||||
int argIndex, i;
|
||||
|
||||
// Create a script environment and install the standard libraries
|
||||
|
||||
L = lua_open(0);
|
||||
|
||||
lua_baselibopen(L);
|
||||
lua_iolibopen(L);
|
||||
lua_strlibopen(L);
|
||||
lua_mathlibopen(L);
|
||||
|
||||
// Install the helper functions for the scripts
|
||||
|
||||
lua_pushcfunction(L, addoption);
|
||||
lua_setglobal(L, "option");
|
||||
|
||||
lua_pushcfunction(L, addoption);
|
||||
lua_setglobal(L, "addoption");
|
||||
|
||||
lua_pushcfunction(L, copyfile);
|
||||
lua_setglobal(L, "copyfile");
|
||||
|
||||
lua_pushcfunction(L, docommand);
|
||||
lua_setglobal(L, "docommand");
|
||||
|
||||
lua_pushcfunction(L, dopackage);
|
||||
lua_setglobal(L, "dopackage");
|
||||
|
||||
lua_pushcfunction(L, ERRORMESSAGE);
|
||||
lua_setglobal(L, "_ERRORMESSAGE");
|
||||
|
||||
lua_pushcfunction(L, getglobal);
|
||||
lua_settagmethod(L, LUA_TNIL, "getglobal");
|
||||
|
||||
lua_pushcfunction(L, dopackage);
|
||||
lua_setglobal(L, "include");
|
||||
|
||||
lua_pushcfunction(L, findlib);
|
||||
lua_setglobal(L, "findlib");
|
||||
|
||||
lua_pushcfunction(L, matchfiles);
|
||||
lua_setglobal(L, "matchfiles");
|
||||
|
||||
lua_pushcfunction(L, newpackage);
|
||||
lua_setglobal(L, "newpackage");
|
||||
|
||||
// Set up the registry
|
||||
|
||||
lua_getregistry(L);
|
||||
|
||||
lua_pushstring(L, "packages");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "options");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Set the OS variable
|
||||
|
||||
lua_pushstring(L, osIdent);
|
||||
lua_setglobal(L, "OS");
|
||||
|
||||
// Create and populate the options table
|
||||
|
||||
lua_newtable(L);
|
||||
argIndex = 0;
|
||||
for (i = 1; argv[i] != NULL; ++i)
|
||||
{
|
||||
if (strncmp(argv[i], "--", 2) == 0)
|
||||
{
|
||||
if (argIndex > 0) lua_settable(L, -3);
|
||||
lua_pushstring(L, argv[i] + 2);
|
||||
lua_newtable(L);
|
||||
argIndex = 1;
|
||||
}
|
||||
else if (argIndex > 0)
|
||||
{
|
||||
lua_pushnumber(L, argIndex++);
|
||||
lua_pushstring(L, argv[i]);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
}
|
||||
if (argIndex > 0) lua_settable(L, -3);
|
||||
lua_setglobal(L, "options");
|
||||
|
||||
// Create an empty project object
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L, "name");
|
||||
lua_pushstring(L, "MyProject");
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "path");
|
||||
lua_pushstring(L, getDirectory(currentScript));
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "bindir");
|
||||
lua_pushstring(L, ".");
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "libdir");
|
||||
lua_pushstring(L, ".");
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "configs");
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "Debug");
|
||||
lua_rawseti(L, -2, 1);
|
||||
lua_pushstring(L, "Release");
|
||||
lua_rawseti(L, -2, 2);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_setglobal(L, "project");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int loadProject(char* project)
|
||||
{
|
||||
int result;
|
||||
result = lua_dofile(L, project);
|
||||
if (result == LUA_ERRFILE)
|
||||
{
|
||||
/* Try "${project}.lua" */
|
||||
char buffer[4096];
|
||||
strcpy(buffer, project);
|
||||
strcat(buffer, ".lua");
|
||||
result = lua_dofile(L, buffer);
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
result = finishProject();
|
||||
|
||||
if (result != 0)
|
||||
lua_close(L);
|
||||
|
||||
return (result == 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void handleCommand(char* args[], int i)
|
||||
{
|
||||
int j;
|
||||
|
||||
// Try to find a command processor
|
||||
lua_getglobal(L, "docommand");
|
||||
if (!lua_isfunction(L, -1))
|
||||
return;
|
||||
|
||||
// Push the command and it's arguments onto the stack
|
||||
lua_pushstring(L, args[i] + 2);
|
||||
for (j = i + 1; args[j] != NULL && strncmp(args[j], "--", 2) != 0; ++j)
|
||||
lua_pushstring(L, args[j]);
|
||||
|
||||
// Call the command processor
|
||||
lua_call(L, j - i, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int getProject()
|
||||
{
|
||||
lua_getglobal(L, "project");
|
||||
return lua_ref(L, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Package* getPackage(const char* name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
if (strcmp(project->package[i]->name, name) == 0)
|
||||
return project->package[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void configureProject()
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
lua_getglobal(L, "project");
|
||||
lua_pushstring(L, "configure");
|
||||
lua_gettable(L, -2);
|
||||
if (!lua_isnil(L, -1))
|
||||
lua_call(L, 0, 0);
|
||||
lua_settop(L, top);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void getConfigList(int package, int config, const char* list, const char*** array, int* length)
|
||||
{
|
||||
const char** buffer;
|
||||
int size, i;
|
||||
|
||||
int pkgRef = getArray(package, list);
|
||||
int pkgLen = getDeepArraySize(pkgRef);
|
||||
int cfgRef = getArray(config, list);
|
||||
int cfgLen = getDeepArraySize(cfgRef);
|
||||
|
||||
size = pkgLen + cfgLen;
|
||||
buffer = (const char**)malloc(sizeof(char**) * (size + 1));
|
||||
buffer[size] = NULL;
|
||||
|
||||
for (i = 0; i < pkgLen; ++i)
|
||||
buffer[i] = getStringFromArray(pkgRef, i);
|
||||
for (i = 0; i < cfgLen; ++i)
|
||||
buffer[i + pkgLen] = getStringFromArray(cfgRef, i);
|
||||
|
||||
*array = buffer;
|
||||
*length = size;
|
||||
}
|
||||
|
||||
static int finishProject()
|
||||
{
|
||||
int i, optlist, packages;
|
||||
|
||||
project = (Project*)malloc(sizeof(Project));
|
||||
|
||||
project->name = getString(getProject(), "name");
|
||||
if (strchr(project->name, ' ') != NULL)
|
||||
puts("** Warning: not all generators allow spaces in the project name.");
|
||||
|
||||
project->path = getString(getProject(), "path");
|
||||
project->binaries = getString(getProject(), "bindir");
|
||||
project->libraries = getString(getProject(), "libdir");
|
||||
project->debugfiles = getString(getProject(), "debugdir");
|
||||
|
||||
optlist = getArray(-1, "options");
|
||||
project->numOptions = getArraySize(optlist);
|
||||
project->option = (Option**)malloc(sizeof(Option*) * (project->numOptions + 1));
|
||||
project->option[project->numOptions] = NULL;
|
||||
for (i = 0; i < project->numOptions; ++i)
|
||||
{
|
||||
int opt = getObjectFromArray(optlist, i);
|
||||
Option* option = (Option*)malloc(sizeof(Option));
|
||||
project->option[i] = option;
|
||||
option->flag = (char*)getStringFromArray(opt, 0);
|
||||
option->description = (char*)getStringFromArray(opt, 1);
|
||||
}
|
||||
|
||||
packages = getArray(-1, "packages");
|
||||
project->numPackages = getArraySize(packages);
|
||||
project->package = (Package**)malloc(sizeof(Package**) * (project->numPackages + 1));
|
||||
project->package[project->numPackages] = NULL;
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
int pkg, files, configs, j;
|
||||
|
||||
Package* package = (Package*)malloc(sizeof(Package));
|
||||
project->package[i] = package;
|
||||
|
||||
pkg = getObjectFromArray(packages, i);
|
||||
|
||||
files = getArray(pkg, "files");
|
||||
package->numFiles = getDeepArraySize(files);
|
||||
package->files = (const char**)malloc(sizeof(char**) * (package->numFiles + 1));
|
||||
package->files[package->numFiles] = NULL;
|
||||
for (j = 0; j < package->numFiles; ++j)
|
||||
package->files[j] = getStringFromArray(files, j);
|
||||
|
||||
package->filesprefix = getString(pkg, "filesprefix");
|
||||
|
||||
package->name = getString(pkg, "name");
|
||||
package->script = getString(pkg, "script");
|
||||
package->path = getString(pkg, "path");
|
||||
package->language = getString(pkg, "language");
|
||||
package->kind = getString(pkg, "kind");
|
||||
package->url = getString(pkg, "url");
|
||||
package->data = NULL;
|
||||
|
||||
configs = getArray(pkg, "config");
|
||||
package->numConfigs = getArraySize(configs);
|
||||
package->config = (Config**)malloc(sizeof(Config*) * (package->numConfigs + 1));
|
||||
package->config[package->numConfigs] = NULL;
|
||||
|
||||
for (j = 0; j < package->numConfigs; ++j)
|
||||
{
|
||||
int cfg;
|
||||
const char* objdir;
|
||||
|
||||
Config* config = (Config*)malloc(sizeof(Config));
|
||||
package->config[j] = config;
|
||||
|
||||
cfg = getObjectFromArray(configs, j);
|
||||
|
||||
config->name = getString(cfg, "name");
|
||||
|
||||
config->target = getString(cfg, "target");
|
||||
if (config->target == NULL) config->target = getString(pkg, "target");
|
||||
if (config->target == NULL) config->target = package->name;
|
||||
|
||||
objdir = getString(cfg, "objdir");
|
||||
if (objdir == NULL)
|
||||
{
|
||||
config->objdir = (char*)malloc(4+strlen(config->name)+1);
|
||||
sprintf(config->objdir, "obj\\%s", config->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
config->objdir = strdup(translatePath(objdir, NATIVE));
|
||||
}
|
||||
|
||||
config->pchHeader = getString(cfg, "pchHeader");
|
||||
if (!config->pchHeader)
|
||||
config->pchHeader = getString(pkg, "pchHeader");
|
||||
|
||||
config->pchSource = getString(cfg, "pchSource");
|
||||
if (!config->pchSource)
|
||||
config->pchSource = getString(pkg, "pchSource");
|
||||
|
||||
config->nasmPath = getString(cfg, "nasmpath");
|
||||
if (!config->nasmPath)
|
||||
config->nasmPath = getString(pkg, "nasmpath");
|
||||
if (!config->nasmPath)
|
||||
config->nasmPath = getString(getProject(), "nasmpath");
|
||||
if (!config->nasmPath)
|
||||
config->nasmPath = "nasm";
|
||||
|
||||
if (getString(cfg, "build"))
|
||||
config->build = (getNumber(cfg, "build") != 0.0);
|
||||
else if (getString(pkg, "build"))
|
||||
config->build = (getNumber(pkg, "build") != 0.0);
|
||||
else
|
||||
config->build = 1;
|
||||
|
||||
getConfigList(pkg, cfg, "buildflags", &config->buildFlags, &config->numBuildFlags);
|
||||
getConfigList(pkg, cfg, "buildoptions", &config->buildOptions, &config->numBuildOptions);
|
||||
getConfigList(pkg, cfg, "defines", &config->defines, &config->numDefines);
|
||||
getConfigList(pkg, cfg, "includepaths", &config->includePaths, &config->numIncludePaths);
|
||||
getConfigList(pkg, cfg, "libpaths", &config->libPaths, &config->numLibPaths);
|
||||
getConfigList(pkg, cfg, "linkflags", &config->linkFlags, &config->numLinkFlags);
|
||||
getConfigList(pkg, cfg, "linkoptions", &config->linkOptions, &config->numLinkOptions);
|
||||
getConfigList(pkg, cfg, "links", &config->links, &config->numLinks);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void closeProject()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
|
||||
for (j = 0; j < package->numConfigs; ++j)
|
||||
{
|
||||
Config* config = package->config[j];
|
||||
free((char**)config->buildFlags);
|
||||
free((char**)config->buildOptions);
|
||||
free((char**)config->defines);
|
||||
free((char**)config->includePaths);
|
||||
free((char**)config->libPaths);
|
||||
free((char**)config->linkFlags);
|
||||
free((char**)config->linkOptions);
|
||||
free((char**)config->links);
|
||||
free((char*)config->objdir);
|
||||
free(package->config[j]);
|
||||
}
|
||||
free(package->config);
|
||||
if (package->data) free(package->data);
|
||||
free(package);
|
||||
}
|
||||
|
||||
free(project->package);
|
||||
free(project);
|
||||
project = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int getArray(int ref, const char* name)
|
||||
{
|
||||
if (ref == -1)
|
||||
ref = LUA_REFREGISTRY;
|
||||
|
||||
lua_getref(L, ref);
|
||||
lua_pushstring(L, name);
|
||||
lua_gettable(L, -2);
|
||||
ref = lua_ref(L, -1);
|
||||
|
||||
lua_pop(L, 1);
|
||||
return ref;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int getArraySize(int ref)
|
||||
{
|
||||
if (ref > 0)
|
||||
{
|
||||
int size;
|
||||
lua_getref(L, ref);
|
||||
size = lua_getn(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getDeepArraySize(int ref)
|
||||
{
|
||||
int i, size = 0;
|
||||
if (ref == 0) return 0;
|
||||
|
||||
lua_getref(L, ref);
|
||||
for (i = 1; i <= lua_getn(L,-1); ++i)
|
||||
{
|
||||
lua_rawgeti(L, -1, i);
|
||||
if (lua_istable(L, -1))
|
||||
{
|
||||
size += getDeepArraySize(lua_ref(L,0));
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
++size;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
return size;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int getObjectFromArray(int ref, int i)
|
||||
{
|
||||
lua_getref(L, ref);
|
||||
lua_rawgeti(L, -1, i + 1);
|
||||
ref = lua_ref(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return ref;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* getString(int ref, char* name)
|
||||
{
|
||||
const char* str;
|
||||
lua_getref(L, ref);
|
||||
lua_pushstring(L, name);
|
||||
lua_gettable(L, -2);
|
||||
str = lua_tostring(L, -1);
|
||||
lua_pop(L, 2);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static double getNumber(int ref, char* name)
|
||||
{
|
||||
double num;
|
||||
lua_getref(L, ref);
|
||||
lua_pushstring(L, name);
|
||||
lua_gettable(L, -2);
|
||||
num = lua_tonumber(L, -1);
|
||||
lua_pop(L, 2);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* goDeep(int ref, int* index)
|
||||
{
|
||||
int i;
|
||||
const char* str = NULL;
|
||||
|
||||
lua_getref(L, ref);
|
||||
for (i = 1; i <= lua_getn(L,-1) && *index >= 0; ++i)
|
||||
{
|
||||
lua_rawgeti(L, -1, i);
|
||||
if (lua_istable(L, -1))
|
||||
{
|
||||
str = goDeep(lua_ref(L,0), index);
|
||||
if (str != NULL)
|
||||
return str;
|
||||
}
|
||||
else if (*index == 0)
|
||||
{
|
||||
str = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
--(*index);
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
static const char* getStringFromArray(int ref, int index)
|
||||
{
|
||||
return goDeep(ref, &index);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void setProjectOption(char* option)
|
||||
{
|
||||
lua_getglobal(L, "options");
|
||||
lua_pushstring(L, option);
|
||||
lua_pushnumber(L, 1);
|
||||
lua_settable(L, -3);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void createEmptyConfig(lua_State* L, const char* name)
|
||||
{
|
||||
lua_newtable(L);
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
lua_pushstring(L, "name");
|
||||
lua_pushstring(L, name);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
lua_pushstring(L, "buildflags");
|
||||
lua_newtable(L);
|
||||
if (name != NULL && strcmp(name, "Release") == 0) {
|
||||
lua_pushstring(L, "no-symbols");
|
||||
lua_rawseti(L, -2, 1);
|
||||
lua_pushstring(L, "optimize");
|
||||
lua_rawseti(L, -2, 2);
|
||||
}
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "buildoptions");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "defines");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "includepaths");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "libpaths");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "linkflags");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "linkoptions");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "links");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* The registry stores the list of projects and packages. This function will
|
||||
* add the table at the top of the stack to one of these lists. */
|
||||
|
||||
static void registerTable(lua_State* L, char* listname)
|
||||
{
|
||||
int n;
|
||||
|
||||
lua_getregistry(L);
|
||||
|
||||
lua_pushstring(L, listname);
|
||||
lua_gettable(L, -2);
|
||||
lua_pushvalue(L, -3);
|
||||
|
||||
n = lua_getn(L, -2);
|
||||
lua_rawseti(L, -2, n + 1);
|
||||
|
||||
lua_pop(L, 2); // remove list and registry
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int addoption(lua_State* L)
|
||||
{
|
||||
lua_getregistry(L);
|
||||
lua_pushstring(L, "options");
|
||||
lua_gettable(L, -2);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_rawseti(L, -2, lua_getn(L,-2) + 1);
|
||||
|
||||
lua_pushvalue(L, 2);
|
||||
lua_rawseti(L, -2, lua_getn(L,-2) + 1);
|
||||
|
||||
lua_rawseti(L, -2, lua_getn(L,-2) + 1);
|
||||
|
||||
lua_pop(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int copyfile(lua_State* L)
|
||||
{
|
||||
const char* src = luaL_check_string(L, 1);
|
||||
const char* dest = luaL_check_string(L, 2);
|
||||
if (copyFile(src, dest))
|
||||
lua_pushnumber(L, 1);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int docommand(lua_State* L)
|
||||
{
|
||||
int argc, i;
|
||||
const char** argv;
|
||||
|
||||
/* If this function is overriden in Lua, the second parameter will be a
|
||||
* table. Otherwise there will be zero or more string parameters. */
|
||||
if (lua_gettop(L) > 1 && !lua_isnil(L,2))
|
||||
{
|
||||
if (lua_istable(L, 2))
|
||||
{
|
||||
argc = lua_getn(L, 2) + 1;
|
||||
argv = (const char**)malloc(sizeof(char*) * argc);
|
||||
argv[0] = luaL_check_string(L, 1);
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
lua_rawgeti(L, 2, i);
|
||||
argv[i] = luaL_check_string(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argc = lua_gettop(L);
|
||||
argv = (const char**)malloc(sizeof(char*) * argc);
|
||||
for (i = 0; i < lua_gettop(L); ++i)
|
||||
argv[i] = luaL_check_string(L, i + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argc = 1;
|
||||
argv = (const char**)malloc(sizeof(char*));
|
||||
argv[0] = luaL_check_string(L, 1);
|
||||
}
|
||||
|
||||
defaultCommand(argc, argv);
|
||||
|
||||
free((char*)argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int dopackage(lua_State* L)
|
||||
{
|
||||
int result;
|
||||
currentScript = luaL_check_string(L, 1);
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, "package");
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushstring(L, "/premake.lua");
|
||||
lua_concat(L, 2);
|
||||
currentScript = lua_tostring(L, -1);
|
||||
result = lua_dofile(L, currentScript);
|
||||
if (result == LUA_ERRFILE)
|
||||
{
|
||||
currentScript = lua_tostring(L, 1);
|
||||
result = lua_dofile(L, currentScript);
|
||||
}
|
||||
|
||||
currentScript = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int ERRORMESSAGE(lua_State* L)
|
||||
{
|
||||
lua_Debug ar;
|
||||
int stack;
|
||||
|
||||
const char* msg = lua_tostring(L, 1);
|
||||
printf("\n** Error: %s\n", msg);
|
||||
|
||||
for (stack = 0; lua_getstack(L, stack, &ar); ++stack)
|
||||
{
|
||||
lua_getinfo(L, "S1", &ar);
|
||||
if (ar.source && ar.currentline > 0)
|
||||
{
|
||||
printf("<%.70s: line %d>\n\n", ar.short_src, ar.currentline);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int findlib(lua_State* L)
|
||||
{
|
||||
const char* libname = luaL_check_string(L, 1);
|
||||
const char* result = findSharedLib(libname);
|
||||
if (result)
|
||||
lua_pushstring(L, result);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int getglobal(lua_State* L)
|
||||
{
|
||||
const char* name = lua_tostring(L, 1);
|
||||
if (strcmp(name, "package") == 0)
|
||||
{
|
||||
|
||||
newpackage(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "package");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int matchfiles(lua_State* L)
|
||||
{
|
||||
const char* path;
|
||||
int i, numArgs;
|
||||
|
||||
/* How many masks were passed in? */
|
||||
numArgs = lua_gettop(L);
|
||||
|
||||
/* Get the current package path */
|
||||
lua_getglobal(L, "package");
|
||||
lua_pushstring(L, "path");
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isstring(L, -1))
|
||||
{
|
||||
path = lua_tostring(L, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentScript != NULL)
|
||||
path = currentScript;
|
||||
else
|
||||
path = ".";
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
|
||||
lua_newtable(L);
|
||||
for (i = 1; i <= numArgs; ++i)
|
||||
{
|
||||
const char* mask = luaL_check_string(L, i);
|
||||
int usePrefix = strcmp(getDirectory(mask), ".") != 0;
|
||||
|
||||
dirOpen(path, mask);
|
||||
while (dirGetNext())
|
||||
{
|
||||
if (dirIsFile())
|
||||
{
|
||||
if (usePrefix)
|
||||
{
|
||||
const char* result;
|
||||
lua_pushstring(L, getDirectory(mask));
|
||||
lua_pushstring(L, dirGetName());
|
||||
lua_concat(L, 2);
|
||||
result = lua_tostring(L, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, dirGetName());
|
||||
}
|
||||
|
||||
lua_rawseti(L, -2, lua_getn(L,-2) + 1);
|
||||
}
|
||||
}
|
||||
dirClose();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int newpackage(lua_State* L)
|
||||
{
|
||||
int configs;
|
||||
int n;
|
||||
|
||||
createEmptyConfig(L, NULL);
|
||||
|
||||
// Add the package to the master list in the registry
|
||||
|
||||
lua_getregistry(L);
|
||||
lua_pushstring(L, "packages");
|
||||
lua_gettable(L, -2);
|
||||
n = lua_getn(L, -1);
|
||||
|
||||
lua_pushvalue(L, -3);
|
||||
lua_rawseti(L, -2, n + 1);
|
||||
lua_pop(L, 2);
|
||||
|
||||
// Set default values
|
||||
|
||||
lua_pushstring(L, "name");
|
||||
if (n == 0)
|
||||
lua_pushstring(L, getString(getProject(), "name"));
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, "Package");
|
||||
lua_pushnumber(L, n + 1);
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "script");
|
||||
lua_pushstring(L, currentScript);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "path");
|
||||
lua_pushstring(L, getDirectory(currentScript));
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "language");
|
||||
lua_pushstring(L, "c++");
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "kind");
|
||||
lua_pushstring(L, "winexe");
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "files");
|
||||
lua_newtable(L);
|
||||
lua_settable(L, -3);
|
||||
|
||||
/* Build list of configurations that can be indexed by name or number */
|
||||
lua_pushstring(L, "config");
|
||||
lua_newtable(L);
|
||||
|
||||
configs = getArray(getProject(), "configs");
|
||||
for (n = 0; n < getArraySize(configs); ++n)
|
||||
{
|
||||
const char* name = getStringFromArray(configs, n);
|
||||
lua_pushstring(L, name);
|
||||
createEmptyConfig(L, name);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, name);
|
||||
lua_gettable(L, -2);
|
||||
lua_rawseti(L, -2, n + 1);
|
||||
}
|
||||
|
||||
lua_settable(L, -3);
|
||||
|
||||
return 1;
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - project.h
|
||||
//
|
||||
// An interface to the project settings.
|
||||
//
|
||||
// Copyright (C) 2002-2004 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: project.h,v 1.10 2004/03/27 13:42:24 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef struct _Config
|
||||
{
|
||||
const char* name;
|
||||
const char* target;
|
||||
const char** buildFlags;
|
||||
const char** buildOptions;
|
||||
const char** defines;
|
||||
const char** includePaths;
|
||||
const char** libPaths;
|
||||
const char** linkFlags;
|
||||
const char** linkOptions;
|
||||
const char** links;
|
||||
const char* pchHeader;
|
||||
const char* pchSource;
|
||||
const char* nasmPath;
|
||||
char* objdir;
|
||||
int build; // 0 or 1, to indicate whether to include it in the default build
|
||||
int numBuildFlags;
|
||||
int numBuildOptions;
|
||||
int numDefines;
|
||||
int numIncludePaths;
|
||||
int numLibPaths;
|
||||
int numLinkFlags;
|
||||
int numLinkOptions;
|
||||
int numLinks;
|
||||
} Config;
|
||||
|
||||
typedef struct _Package
|
||||
{
|
||||
const char* name;
|
||||
const char* script;
|
||||
const char* path;
|
||||
const char* language;
|
||||
const char* kind;
|
||||
const char* url;
|
||||
const char** files;
|
||||
int numFiles;
|
||||
const char* filesprefix;
|
||||
Config** config;
|
||||
int numConfigs;
|
||||
void* data;
|
||||
} Package;
|
||||
|
||||
typedef struct _Option
|
||||
{
|
||||
char* flag;
|
||||
char* description;
|
||||
struct _Option* next;
|
||||
} Option;
|
||||
|
||||
typedef struct _Project
|
||||
{
|
||||
const char* name;
|
||||
const char* binaries;
|
||||
const char* libraries;
|
||||
const char* debugfiles;
|
||||
const char* path;
|
||||
Package** package;
|
||||
Option** option;
|
||||
int numPackages;
|
||||
int numOptions;
|
||||
} Project;
|
||||
|
||||
|
||||
extern Project* project;
|
||||
|
||||
extern void createProject(char* argv[]);
|
||||
extern int loadProject(char* project);
|
||||
extern void closeProject();
|
||||
extern void handleCommand(char* args[], int i);
|
||||
|
||||
// Deprecated?
|
||||
extern Package* getPackage(const char* name);
|
||||
extern void configureProject();
|
||||
extern void setProjectOption(char* option);
|
||||
|
||||
// Access to the lua objects
|
||||
extern int getProject();
|
||||
extern const char* getString(int ref, char* name);
|
@ -1,356 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - sharpdev.c
|
||||
//
|
||||
// ICSharpCode SharpDevelop tool target.
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// Written by Chris McGuirk (leedgitar@latenitegames.com)
|
||||
// Modified by Jason Perkins
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
|
||||
static char buffer[4096];
|
||||
|
||||
static int writeCombine();
|
||||
static int writeCsProject(Package* package);
|
||||
|
||||
extern const char* dotnet;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int makeSharpDevScripts()
|
||||
{
|
||||
int i;
|
||||
|
||||
puts("Generating SharpDevelop combine and project files:");
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
|
||||
printf("...%s\n", package->name);
|
||||
|
||||
if (strcmp(package->language, "c#") == 0)
|
||||
{
|
||||
if (!writeCsProject(package))
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0)
|
||||
{
|
||||
printf("** Error: SharpDevelop does not support C/C++ development.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
printf("** Error: unrecognized language '%s'\n", package->language);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!writeCombine())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int writeCombine()
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
FILE* file;
|
||||
file = openFile(project->path, project->name, ".cmbx");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
fprintf(file, "<Combine fileversion=\"1.0\" name=\"%s\" description=\"\">\n", project->name);
|
||||
|
||||
// TODO: select the first executable project
|
||||
// pick the first project as the startup by default in the meantime
|
||||
if(project->numPackages != 0)
|
||||
{
|
||||
fprintf(file, " <StartMode startupentry=\"%s\" single=\"True\">\n", project->package[0]->name);
|
||||
}
|
||||
|
||||
// first write out the startup entries
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
const char* name = package->name;
|
||||
fprintf(file, " <Execute entry=\"%s\" type=\"None\" />\n", name);
|
||||
}
|
||||
|
||||
fprintf(file, " </StartMode>\n");
|
||||
fprintf(file, " <Entries>\n");
|
||||
|
||||
// now write out the project entries
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
const char* name = package->name;
|
||||
const char* path = reversePath(project->path, package->path, NATIVE);
|
||||
fprintf(file, " <Entry filename=\"%s%s.%s\" />\n", path, name, "prjx");
|
||||
}
|
||||
|
||||
fprintf(file, " </Entries>\n");
|
||||
fprintf(file, " <Configurations active=\"Debug\">\n");
|
||||
|
||||
// write out the entries for each build configuration
|
||||
for (i = 0; i < project->package[0]->numConfigs; ++i)
|
||||
{
|
||||
const char* configName = project->package[0]->config[i]->name;
|
||||
|
||||
fprintf(file, " <Configuration name=\"%s\">\n", configName);
|
||||
|
||||
// loop through each package. if has a configuration matching the curent one, write an entry
|
||||
for(j = 0; j < project->numPackages; j++)
|
||||
{
|
||||
Package* package = project->package[j];
|
||||
const char* name = package->name;
|
||||
|
||||
int isIncluded = 0;
|
||||
|
||||
// look at each of this projects configs
|
||||
for(k = 0; k < package->numConfigs; k++)
|
||||
{
|
||||
if(strcmp(configName, package->config[k]->name) != 0)
|
||||
{
|
||||
isIncluded = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write the entry for the current project in this build configuration
|
||||
fprintf(file, " <Entry name=\"%s\" configurationname=\"%s\" build=\"%s\" />\n", package->name, configName, isIncluded ? "True" : "False");
|
||||
}
|
||||
|
||||
fprintf(file, " </Configuration>\n");
|
||||
}
|
||||
|
||||
fprintf(file, " </Configurations>\n");
|
||||
fprintf(file, "</Combine>");
|
||||
|
||||
// Finish
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* checkDir(const char* path, void* data)
|
||||
{
|
||||
return translatePath(path, WIN32);
|
||||
}
|
||||
|
||||
static const char* checkLibs(const char* file, void* data)
|
||||
{
|
||||
Package* package = getPackage(file);
|
||||
if (package == NULL) return file;
|
||||
if (strcmp(package->language, "c#") != 0) return NULL;
|
||||
return package->config[*((int*)data)]->target;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* checkRefs(const char* ref, void* data)
|
||||
{
|
||||
int i;
|
||||
int isSibling = 0;
|
||||
const char* fileName = getFilename(ref, 0);
|
||||
|
||||
strcpy(buffer," type=\"");
|
||||
|
||||
// Is this a sibling project?
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
if (strcmp(project->package[i]->name, ref) == 0)
|
||||
{
|
||||
isSibling = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isSibling)
|
||||
{
|
||||
strcat(buffer, "Project\"");
|
||||
strcat(buffer, " refto=\"");
|
||||
strcat(buffer, fileName);
|
||||
strcat(buffer, "\" localcopy=\"True\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* ext = strchr(ref,',') ? "" : ".dll";
|
||||
|
||||
// See if this assembly exists on one of the link paths
|
||||
Package* package = (Package*)data;
|
||||
if (fileExists(project->binaries, ref, ext))
|
||||
{
|
||||
strcat(buffer, "Assembly\" refto=\"");
|
||||
strcat(buffer, reversePath(package->path, project->binaries, NATIVE));
|
||||
strcat(buffer, "/");
|
||||
strcat(buffer, ref);
|
||||
strcat(buffer, ".dll\" localcopy=\"False\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(buffer, "Gac\" refto=\"");
|
||||
strcat(buffer, ref);
|
||||
strcat(buffer, ext);
|
||||
strcat(buffer, "\" localcopy=\"False\"");
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char* checkRefPaths(const char* ref, void* data)
|
||||
{
|
||||
const char* projPath = (const char*)data;
|
||||
return makeAbsolute(projPath, ref);
|
||||
}
|
||||
|
||||
static const char* checkSrcFileType(const char* file, void* data)
|
||||
{
|
||||
const char* ext;
|
||||
|
||||
strcpy(buffer, translatePath(file, WIN32));
|
||||
strcat(buffer, "\" subtype=\"Code\" ");
|
||||
|
||||
ext = getExtension(file);
|
||||
if (strcmp(ext, ".cs") == 0)
|
||||
{
|
||||
strcat(buffer, "BuildAction=\"Compile\"");
|
||||
}
|
||||
else if (strcmp(ext, ".resx") == 0)
|
||||
{
|
||||
strcat(buffer, "BuildAction=\"EmbedAsResource\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(buffer, "BuildAction=\"Nothing\"");
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int writeCsProject(Package* package)
|
||||
{
|
||||
FILE* file;
|
||||
const char* runtime;
|
||||
const char* csc;
|
||||
int i;
|
||||
|
||||
const char* name = package->name;
|
||||
const char* path = package->path;
|
||||
const char* kind = package->kind;
|
||||
|
||||
if (strcmp(kind, "winexe") == 0)
|
||||
kind = "WinExe";
|
||||
else if (strcmp(kind, "exe") == 0)
|
||||
kind = "Exe";
|
||||
else if (strcmp(kind, "dll") == 0 || strcmp(kind, "aspnet") == 0)
|
||||
kind = "Library";
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown package kind '%s'\n", kind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Figure out what .net environment I'm using
|
||||
if (dotnet == NULL)
|
||||
dotnet = (strcmp(osIdent, "windows") == 0) ? "ms" : "mono";
|
||||
|
||||
if (strcmp(dotnet, "ms") == 0)
|
||||
{
|
||||
runtime = "MsNet";
|
||||
csc = "Csc";
|
||||
}
|
||||
else if (strcmp(dotnet, "mono") == 0)
|
||||
{
|
||||
runtime = "Mono";
|
||||
csc = "Mcs";
|
||||
}
|
||||
else if (strcmp(dotnet, "pnet") == 0)
|
||||
{
|
||||
printf("** Error: SharpDevelop does not yet support Portable.NET\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown .NET runtime '%s'\n", dotnet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Open the project file and write the header
|
||||
file = openFile(path, name, ".prjx");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
// Project Header
|
||||
fprintf(file, "<Project name=\"%s\" description=\"\" newfilesearch=\"None\" enableviewstate=\"True\" version=\"1.1\" projecttype=\"C#\">\n", name);
|
||||
|
||||
// File List
|
||||
fprintf(file, " <Contents>\n");
|
||||
writeList(file, package->files, " <File name=\".\\", " dependson=\"\" data=\"\" />\n", "", checkSrcFileType, NULL);
|
||||
fprintf(file, " </Contents>\n");
|
||||
|
||||
// References
|
||||
fprintf(file, " <References>\n");
|
||||
writeList(file, package->config[0]->links, " <Reference", " />\n", "", checkRefs, package);
|
||||
fprintf(file, " </References>\n");
|
||||
|
||||
// Configurations
|
||||
fprintf(file, " <Configurations active=\"%s\">\n", package->config[0]->name);
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
Config* config = package->config[i];
|
||||
|
||||
int symbols = !inArray(config->buildFlags, "no-symbols");
|
||||
int optimize = inArray(config->buildFlags, "optimize") || inArray(config->buildFlags, "optimize-size") || inArray(config->buildFlags, "optimize-speed");
|
||||
int unsafe = inArray(config->buildFlags, "unsafe");
|
||||
|
||||
fprintf(file, " <Configuration runwithwarnings=\"True\" name=\"%s\">\n", config->name);
|
||||
fprintf(file, " <CodeGeneration runtime=\"%s\" compiler=\"%s\"", runtime, csc);
|
||||
fprintf(file, " warninglevel=\"0\" ");
|
||||
fprintf(file, "includedebuginformation=\"%s\" ", symbols ? "True" : "False");
|
||||
fprintf(file, "optimize=\"%s\" ", optimize ? "True" : "False");
|
||||
fprintf(file, "unsafecodeallowed=\"%s\" ", unsafe ? "True" : "False");
|
||||
fprintf(file, "generateoverflowchecks=\"True\" ");
|
||||
fprintf(file, "mainclass=\"\" ");
|
||||
fprintf(file, "target=\"%s\" ", kind);
|
||||
fprintf(file, "definesymbols=\"");
|
||||
writeList(file, config->defines, "", "", ";", NULL, NULL);
|
||||
fprintf(file, "\" ");
|
||||
fprintf(file, "generatexmldocumentation=\"False\" ");
|
||||
fprintf(file, "/>\n");
|
||||
|
||||
fprintf(file, " <Output ");
|
||||
fprintf(file, "directory=\"");
|
||||
fprintf(file, reversePath(path, project->binaries, NATIVE));
|
||||
insertPath(file, getDirectory(config->target), NATIVE);
|
||||
fprintf(file, "\" ");
|
||||
fprintf(file, "assembly=\"%s\" ", getFilename(config->target,0));
|
||||
fprintf(file, "executeScript=\"\" ");
|
||||
fprintf(file, "executeBeforeBuild=\"\" ");
|
||||
fprintf(file, "executeAfterBuild=\"\" ");
|
||||
fprintf(file, "/>\n");
|
||||
|
||||
fprintf(file, " </Configuration>\n", config->name);
|
||||
}
|
||||
|
||||
fprintf(file, " </Configurations>\n");
|
||||
fprintf(file, "</Project>\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
@ -1,566 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - util.c
|
||||
//
|
||||
// Premake utility functions
|
||||
//
|
||||
// Copyright (C) 2002-2003 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: util.c,v 1.19 2004/03/27 13:42:24 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
|
||||
char** args;
|
||||
|
||||
static char buffer[4096];
|
||||
static char buffer2[4096];
|
||||
|
||||
static char pathseps[] = { '/', '\\' };
|
||||
|
||||
extern int plat_chdir(const char* path);
|
||||
extern int plat_copyFile(const char* src, const char* dest);
|
||||
extern void plat_deleteDir(const char* path);
|
||||
extern void plat_deleteFile(const char* path);
|
||||
extern int plat_findLib(const char* lib, char* buffer, int size);
|
||||
extern void plat_generateUUID(const char* uuid);
|
||||
extern void plat_getcwd(char* buffer, int size);
|
||||
extern int plat_isAbsPath(const char* path);
|
||||
|
||||
extern int plat_dirOpen(const char* mask);
|
||||
extern void plat_dirClose();
|
||||
extern int plat_dirGetNext();
|
||||
extern const char* plat_dirGetName();
|
||||
extern int plat_dirIsFile();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int copyFile(const char* src, const char* dest)
|
||||
{
|
||||
translatePath(src, NATIVE); // copies into buffer2
|
||||
strcpy(buffer, buffer2);
|
||||
translatePath(dest, NATIVE);
|
||||
return plat_copyFile(buffer, buffer2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void deleteDirectory(const char* directory, const char* name)
|
||||
{
|
||||
strcpy(buffer, directory);
|
||||
if (strlen(directory) > 0) strcat(buffer, "/");
|
||||
strcat(buffer, name);
|
||||
plat_deleteDir(translatePath(buffer, NATIVE));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void deleteFile(const char* directory, const char* name, const char* extension)
|
||||
{
|
||||
strcpy(buffer, directory);
|
||||
if (strlen(buffer) > 0) strcat(buffer, "/");
|
||||
strcat(buffer, name);
|
||||
strcat(buffer, extension);
|
||||
plat_deleteFile(buffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int endsWith(const char* haystack, const char* needle)
|
||||
{
|
||||
if (strlen(haystack) < strlen(needle))
|
||||
return 0;
|
||||
|
||||
haystack = haystack + strlen(haystack) - strlen(needle);
|
||||
return (strcmp(haystack, needle) == 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int fileExists(const char* path, const char* name, const char* extension)
|
||||
{
|
||||
FILE* file;
|
||||
char buffer[512];
|
||||
|
||||
strcpy(buffer, path);
|
||||
if (path && strlen(path) > 0)
|
||||
strcat(buffer, "/");
|
||||
strcat(buffer, name);
|
||||
strcat(buffer, extension);
|
||||
|
||||
file = fopen(buffer, "r");
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* findSharedLib(const char* lib)
|
||||
{
|
||||
if (plat_findLib(lib, buffer, 4096))
|
||||
return buffer;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void stringify(unsigned char* src, char* dst, int count)
|
||||
{
|
||||
char buffer[4];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
sprintf(buffer, "%X", (int)src[i]);
|
||||
|
||||
if (src[i] >= 0x10)
|
||||
{
|
||||
*(dst++) = buffer[0];
|
||||
*(dst++) = buffer[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
*(dst++) = '0';
|
||||
*(dst++) = buffer[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void generateUUID(char* uuid)
|
||||
{
|
||||
plat_generateUUID(buffer);
|
||||
|
||||
stringify(buffer, uuid, 4);
|
||||
uuid[8] = '-';
|
||||
stringify(buffer + 4, uuid + 9, 2);
|
||||
uuid[13] = '-';
|
||||
stringify(buffer + 6, uuid + 14, 2);
|
||||
uuid[18] = '-';
|
||||
stringify(buffer + 8, uuid + 19, 2);
|
||||
uuid[23] = '-';
|
||||
stringify(buffer + 10, uuid + 24, 6);
|
||||
uuid[36] = '\0';
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* getDirectory(const char* path)
|
||||
{
|
||||
char* ptr;
|
||||
if (path != NULL)
|
||||
{
|
||||
strcpy(buffer, path);
|
||||
for (ptr = buffer; *ptr; ptr++)
|
||||
{
|
||||
if (*ptr == '\\')
|
||||
*ptr = '/';
|
||||
}
|
||||
|
||||
ptr = strrchr(buffer, '/');
|
||||
if (ptr != NULL)
|
||||
{
|
||||
*(++ptr) = '\0';
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return ".";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* getExtension(const char* path)
|
||||
{
|
||||
if (path != NULL)
|
||||
{
|
||||
const char* ptr = strrchr(path, '.');
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* getFilename(const char* path, int trim)
|
||||
{
|
||||
if (path != NULL)
|
||||
{
|
||||
char* ptr = strrchr(path, '/');
|
||||
ptr = (ptr != NULL) ? ++ptr : (char*)path;
|
||||
strcpy(buffer, ptr);
|
||||
|
||||
if (trim)
|
||||
{
|
||||
ptr = strrchr(buffer, '.');
|
||||
if (ptr != NULL) *ptr = '\0';
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int hasOption(char* option)
|
||||
{
|
||||
char** arg;
|
||||
for (arg = args; *arg != NULL; ++arg)
|
||||
{
|
||||
if (strlen(*arg) == strlen(option) + 2 && strcmp((*arg) + 2, option) == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int inArray(const char** list, const char* value)
|
||||
{
|
||||
while (*list)
|
||||
{
|
||||
if (strcmp(*list, value) == 0)
|
||||
return 1;
|
||||
++list;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void insertPath(FILE* file, const char* path, int type)
|
||||
{
|
||||
if (strcmp(path, ".") != 0)
|
||||
fprintf(file, translatePath(path, type));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int isCppFile(const char* file)
|
||||
{
|
||||
int i;
|
||||
const char* ext = getExtension(file);
|
||||
for (i = 0; CPP_EXT[i] != NULL; ++i)
|
||||
{
|
||||
if (strcmp(ext, CPP_EXT[i]) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function does some gyrations to handle the case where the requested
|
||||
// directory doesn't actually exist. It tries to still give a reasonable path.
|
||||
|
||||
const char* makeAbsolute(const char* base, const char* path)
|
||||
{
|
||||
const char* ptr;
|
||||
|
||||
// If the directory is already absolute I don't have to do anything
|
||||
if (plat_isAbsPath(path))
|
||||
return translatePath(path, NATIVE);
|
||||
|
||||
// chdir() to the package directory
|
||||
plat_getcwd(buffer, 4096);
|
||||
if (!plat_chdir(translatePath(base, NATIVE)))
|
||||
{
|
||||
plat_chdir(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Back my way up the tree
|
||||
ptr = path;
|
||||
while (*ptr == '.' || *ptr == '/')
|
||||
{
|
||||
if (strncmp(ptr, "..", 2) == 0)
|
||||
{
|
||||
plat_chdir("..");
|
||||
ptr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* OBSOLETE
|
||||
while (*ptr == '.')
|
||||
{
|
||||
if (strncmp(ptr, "../", 3) == 0)
|
||||
{
|
||||
plat_chdir("..");
|
||||
ptr += 3;
|
||||
}
|
||||
else if (strncmp(ptr, "./", 2) == 0)
|
||||
{
|
||||
ptr += 2;
|
||||
}
|
||||
else if (*(ptr + 1) == '\0')
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Tack the remained of the path onto my current location
|
||||
plat_getcwd(buffer2, 4096);
|
||||
strcat(buffer2, "/");
|
||||
strcat(buffer2, ptr);
|
||||
|
||||
for (ptr = buffer2; *ptr; ++ptr)
|
||||
{
|
||||
if (*ptr == '/')
|
||||
*((char*)ptr) = nativePathSep;
|
||||
}
|
||||
|
||||
plat_chdir(buffer);
|
||||
return buffer2;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FILE* openFile(const char* path, const char* name, const char* extension)
|
||||
{
|
||||
FILE* file;
|
||||
char buffer[512];
|
||||
|
||||
strcpy(buffer, path);
|
||||
if (path && strlen(path) > 0)
|
||||
strcat(buffer, "/");
|
||||
strcat(buffer, name);
|
||||
strcat(buffer, extension);
|
||||
|
||||
file = fopen(buffer, "wt");
|
||||
if (file == NULL)
|
||||
printf("** Error: unable to open file '%s'\n", buffer);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* replaceChars(const char* str, const char* replace)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)strlen(str); ++i)
|
||||
buffer[i] = (strchr(replace, str[i]) == NULL) ? str[i] : '_';
|
||||
buffer[strlen(str)] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* replaceExtension(const char* path, const char* extension)
|
||||
{
|
||||
char* ptr = strrchr(path, '.');
|
||||
if (ptr != NULL)
|
||||
{
|
||||
strncpy(buffer, path, ptr - path);
|
||||
buffer[ptr - path] = '\0';
|
||||
}
|
||||
else
|
||||
strcpy(buffer, path);
|
||||
strcat(buffer, extension);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* reversePath(const char* path, const char* subdir, int type)
|
||||
{
|
||||
char origin[2048];
|
||||
char destination[2048];
|
||||
int start, i;
|
||||
|
||||
// Get the full path to both locations
|
||||
strcpy(origin, makeAbsolute(".", path));
|
||||
strcpy(destination, makeAbsolute(".", subdir));
|
||||
|
||||
// Trim off common directories
|
||||
start = 0;
|
||||
i = 0;
|
||||
while (origin[i] && destination[i] && origin[i] == destination[i])
|
||||
{
|
||||
if (origin[i] == nativePathSep)
|
||||
start = i + 1;
|
||||
++i;
|
||||
}
|
||||
|
||||
// Build the return path
|
||||
if (strlen(origin) - start > 0)
|
||||
{
|
||||
int i = start;
|
||||
strcpy(buffer, "..");
|
||||
for ( ; origin[i]; ++i)
|
||||
{
|
||||
if (origin[i] == nativePathSep && origin[i+1] != '\0')
|
||||
strcat(buffer, "/..");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(buffer, ".");
|
||||
}
|
||||
|
||||
if (strlen(destination) - start > 0)
|
||||
{
|
||||
strcat(buffer, "/");
|
||||
strcat(buffer, destination + start);
|
||||
}
|
||||
|
||||
// It must end with a separator
|
||||
if (buffer[strlen(buffer)-1] != '/' && buffer[strlen(buffer)-1] != '\\') strcat(buffer, "/");
|
||||
|
||||
return translatePath(buffer, type);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* translatePath(const char* path, int type)
|
||||
{
|
||||
char* ptr;
|
||||
char sep = (type == NATIVE) ? type = nativePathSep : pathseps[type];
|
||||
|
||||
strcpy(buffer2, path);
|
||||
for (ptr = buffer2; *ptr != '\0'; ++ptr)
|
||||
{
|
||||
if (*ptr == '/' || *ptr == '\\')
|
||||
*ptr = sep;
|
||||
}
|
||||
|
||||
return buffer2;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void walkSourceList(FILE* file, Package* package, const char* path, void (*cb)(FILE*, const char*, const char*, int))
|
||||
{
|
||||
const char** i;
|
||||
|
||||
// Open the group
|
||||
strcpy(buffer, path);
|
||||
if (buffer[strlen(buffer)-1] == '/') buffer[strlen(buffer)-1] = '\0';
|
||||
cb(file, buffer, package->filesprefix, WST_OPENGROUP);
|
||||
|
||||
for (i = package->files; *i; ++i)
|
||||
{
|
||||
const char* source = (*i);
|
||||
|
||||
// For each file in the target directory...
|
||||
if (strlen(source) > strlen(path) && strncmp(source, path, strlen(path)) == 0)
|
||||
{
|
||||
// Look for a subdirectory...
|
||||
const char* ptr = strchr(source + strlen(path), '/');
|
||||
if (ptr != NULL)
|
||||
{
|
||||
// Have I processed this subdirectory already?
|
||||
const char** j;
|
||||
strncpy(buffer, source, ptr - source + 1);
|
||||
buffer[ptr - source + 1] = '\0';
|
||||
for (j = package->files; *j; ++j)
|
||||
{
|
||||
if (strncmp(buffer, *j, strlen(buffer)) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == j)
|
||||
{
|
||||
char* newpath = (char*)malloc(strlen(buffer) + 1);
|
||||
strcpy(newpath, buffer);
|
||||
walkSourceList(file, package, newpath, cb);
|
||||
free(newpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send the source files
|
||||
for (i = package->files; *i; ++i)
|
||||
{
|
||||
const char* source = (*i);
|
||||
const char* ptr = strrchr(source, '/');
|
||||
if (strncmp(path, source, strlen(path)) == 0 && ptr <= source + strlen(path))
|
||||
cb(file, source, package->filesprefix, WST_SOURCEFILE);
|
||||
}
|
||||
|
||||
// Close the group
|
||||
strcpy(buffer, path);
|
||||
if (buffer[strlen(buffer)-1] == '/') buffer[strlen(buffer)-1] = '\0';
|
||||
cb(file, buffer, package->filesprefix, WST_CLOSEGROUP);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void writeList(FILE* file, const char** list, const char* prefix, const char* postfix, const char* infix, const char* (*check)(const char*,void*), void* data)
|
||||
{
|
||||
int i = 0;
|
||||
while (*list)
|
||||
{
|
||||
const char* value = (check != NULL) ? check(*list, data) : *list;
|
||||
if (value != NULL)
|
||||
{
|
||||
if (i++ > 0) fprintf(file, infix);
|
||||
fprintf(file, "%s%s%s", prefix, value, postfix);
|
||||
}
|
||||
++list;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* getCwd()
|
||||
{
|
||||
plat_getcwd(buffer, 4096);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int setCwd(const char* path)
|
||||
{
|
||||
return plat_chdir(path);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int dirOpen(const char* base, const char* mask)
|
||||
{
|
||||
strcpy(buffer, base);
|
||||
strcat(buffer, "/");
|
||||
strcat(buffer, mask);
|
||||
return plat_dirOpen(translatePath(buffer, NATIVE));
|
||||
}
|
||||
|
||||
void dirClose()
|
||||
{
|
||||
plat_dirClose();
|
||||
}
|
||||
|
||||
int dirGetNext()
|
||||
{
|
||||
return plat_dirGetNext();
|
||||
}
|
||||
|
||||
const char* dirGetName()
|
||||
{
|
||||
return plat_dirGetName();
|
||||
}
|
||||
|
||||
int dirIsFile()
|
||||
{
|
||||
return plat_dirIsFile();
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - util.h
|
||||
//
|
||||
// Premake utility functions
|
||||
//
|
||||
// Copyright (C) 2002-2003 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: util.h,v 1.13 2004/03/27 13:42:24 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static char* CPP_EXT[] = { ".cc", ".cpp", ".cxx", ".c", ".asm", NULL };
|
||||
|
||||
enum { UNIX, WIN32, NATIVE };
|
||||
extern char nativePathSep;
|
||||
extern const char* osIdent;
|
||||
|
||||
enum { WST_OPENGROUP, WST_CLOSEGROUP, WST_SOURCEFILE };
|
||||
|
||||
extern char** args;
|
||||
|
||||
extern int copyFile(const char* src, const char* dest);
|
||||
extern void deleteDirectory(const char* path, const char* name);
|
||||
extern void deleteFile(const char* path, const char* name, const char* extension);
|
||||
extern int endsWith(const char* haystack, const char* needle);
|
||||
extern int fileExists(const char* path, const char* name, const char* extension);
|
||||
extern const char* findSharedLib(const char* lib);
|
||||
extern void generateUUID(char* uuid);
|
||||
extern const char* getDirectory(const char* path);
|
||||
extern const char* getExtension(const char* path);
|
||||
extern const char* getFilename(const char* path, int trim);
|
||||
extern int hasOption(char* option);
|
||||
extern int inArray(const char** list, const char* value);
|
||||
extern void insertPath(FILE* file, const char* path, int type);
|
||||
extern int isCppFile(const char* file);
|
||||
extern const char* makeAbsolute(const char* base, const char* path);
|
||||
extern FILE* openFile(const char* path, const char* name, const char* extension);
|
||||
extern const char* replaceChars(const char* str, const char* replace);
|
||||
extern const char* replaceExtension(const char* path, const char* extension);
|
||||
extern const char* reversePath(const char* path, const char* subdir, int type);
|
||||
extern const char* translatePath(const char* buffer, int type);
|
||||
extern void walkSourceList(FILE* file, Package* package, const char* path, void (*cb)(FILE*, const char*, const char*, int));
|
||||
extern void writeList(FILE* file, const char** list, const char* prefix, const char* postfix, const char* infix, const char* (*check)(const char*,void*), void* data);
|
||||
extern const char* getCwd();
|
||||
extern int setCwd(const char* path);
|
||||
|
||||
extern int dirOpen(const char* base, const char* mask);
|
||||
extern void dirClose();
|
||||
extern int dirGetNext();
|
||||
extern const char* dirGetName();
|
||||
extern int dirIsFile();
|
@ -1,614 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - vs6.c
|
||||
//
|
||||
// MS Visual Studio 6 tool target.
|
||||
//
|
||||
// Copyright (C) 2002-2004 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: vs6.c,v 1.20 2004/05/07 00:12:29 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
|
||||
extern const char* dotnet;
|
||||
|
||||
static int writeWorkspace();
|
||||
static int writeCsProject(Package* package);
|
||||
static int writeVcProject(Package* package);
|
||||
static int writeProjectHeader(FILE* file, Package* package);
|
||||
|
||||
#if VS6_DOTNET
|
||||
static char* csc;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int makeVs6Scripts()
|
||||
{
|
||||
int i, csharp = 0;
|
||||
|
||||
puts("Generating Visual Studio 6 workspace and project files:");
|
||||
|
||||
#if VS6_DOTNET
|
||||
if (dotnet == NULL)
|
||||
csc = "csc.exe";
|
||||
else if (strcmp(dotnet, "mono") == 0)
|
||||
csc = "mcs.exe";
|
||||
else if (strcmp(dotnet, "pnet") == 0)
|
||||
csc = "cscc.exe";
|
||||
else
|
||||
csc = "csc.exe";
|
||||
#endif
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
const char* language = package->language;
|
||||
printf("...%s\n", package->name);
|
||||
|
||||
if (strcmp(language, "c++") == 0 || strcmp(language, "c") == 0)
|
||||
{
|
||||
writeVcProject(package);
|
||||
}
|
||||
else if (strcmp(language, "c#") == 0)
|
||||
{
|
||||
#if VS6_DOTNET
|
||||
csharp = 1;
|
||||
writeCsProject(package);
|
||||
#else
|
||||
printf("** Error: C# projects are not supported by Visual Studio 6\n");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unrecognized language '%s'\n", language);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if VS6_DOTNET
|
||||
if (csharp && getenv("DOTNET_PATH") == NULL)
|
||||
{
|
||||
printf("\nBEFORE USING THESE PROJECT FILES you must set the environment variable\n");
|
||||
printf("DOTNET_PATH to the directory containing %s.\n\n", csc);
|
||||
|
||||
if (strcmp(csc, "csc.exe") == 0)
|
||||
printf("This will be something like C:\\WinNT\\Microsoft.NET\\Framework\\v1.0.3705.\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return writeWorkspace();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int writeWorkspace()
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
FILE* file = openFile(project->path, project->name, ".dsw");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
fprintf(file, "Microsoft Developer Studio Workspace File, Format Version 6.00\n");
|
||||
fprintf(file, "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
|
||||
fprintf(file, "###############################################################################\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "Project: \"%s\"=%s%s.dsp\n", replaceChars(package->name,"-"), reversePath(project->path,package->path,WIN32), package->name);
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "Package=<5>\n");
|
||||
fprintf(file, "{{{\n");
|
||||
fprintf(file, "}}}\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "Package=<4>\n");
|
||||
fprintf(file, "{{{\n");
|
||||
|
||||
// List package dependencies on sibling projects
|
||||
for (j = 0; j < package->config[0]->numLinks; ++j)
|
||||
{
|
||||
const char* link = package->config[0]->links[j];
|
||||
for (k = 0; k < project->numPackages; k++)
|
||||
{
|
||||
if (strcmp(project->package[k]->name, link) == 0)
|
||||
{
|
||||
fprintf(file, " Begin Project Dependency\n");
|
||||
fprintf(file, " Project_Dep_Name %s\n", replaceChars(link, "-"));
|
||||
fprintf(file, " End Project Dependency\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "}}}\n");
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
fprintf(file, "###############################################################################\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "Global:\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "Package=<5>\n");
|
||||
fprintf(file, "{{{\n");
|
||||
fprintf(file, "}}}\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "Package=<3>\n");
|
||||
fprintf(file, "{{{\n");
|
||||
fprintf(file, "}}}\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "###############################################################################\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void vcFiles(FILE* file, const char* path, const char* prefix, int stage)
|
||||
{
|
||||
const char* ptr = strrchr(path, '/');
|
||||
int i,j;
|
||||
ptr = (ptr == NULL) ? path : ptr + 1;
|
||||
|
||||
switch (stage)
|
||||
{
|
||||
case WST_OPENGROUP:
|
||||
if (strlen(path) > 0 && strcmp(ptr, "..") != 0) {
|
||||
fprintf(file, "# Begin Group \"%s\"\n\n", ptr);
|
||||
fprintf(file, "# PROP Default_Filter \"\"\n");
|
||||
}
|
||||
break;
|
||||
case WST_CLOSEGROUP:
|
||||
if (strlen(path) > 0 && strcmp(ptr, "..") != 0)
|
||||
fprintf(file, "# End Group\n");
|
||||
break;
|
||||
case WST_SOURCEFILE:
|
||||
fprintf(file, "# Begin Source File\n\n");
|
||||
fprintf(file, "SOURCE=.\\%s\n", translatePath(path,WIN32));
|
||||
for (i=0;i<project->numPackages;i++)
|
||||
{
|
||||
Package *package=project->package[i];
|
||||
for (j=0;j<package->numConfigs;j++)
|
||||
{
|
||||
Config *config=package->config[j];
|
||||
|
||||
fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"\n", (i == 0 ? "IF" : "ELSEIF"), replaceChars(package->name,"-"), config->name);
|
||||
fprintf(file, "\n");
|
||||
|
||||
if (config->pchSource && strcmp(ptr, config->pchSource)==0)
|
||||
{
|
||||
fprintf(file, "# ADD CPP /Yc\"%s\"\n", config->pchHeader);
|
||||
}
|
||||
}
|
||||
fprintf(file, "!ENDIF\n");
|
||||
}
|
||||
fprintf(file, "# End Source File\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* checkLink(const char* path, void* data)
|
||||
{
|
||||
Package* package = getPackage(path);
|
||||
if (package == NULL) return path;
|
||||
|
||||
if (strcmp(package->language, "c++") == 0)
|
||||
return package->config[*((int*)data)]->target;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int writeVcProject(Package* package)
|
||||
{
|
||||
const char* ldflags;
|
||||
const char* extension;
|
||||
const char* outdir;
|
||||
FILE* file;
|
||||
int i;
|
||||
|
||||
// Some target type specific info...
|
||||
if (strcmp(package->kind, "winexe") == 0)
|
||||
{
|
||||
ldflags = "/subsystem:windows";
|
||||
extension = "exe";
|
||||
outdir = project->binaries;
|
||||
}
|
||||
else if (strcmp(package->kind, "exe") == 0)
|
||||
{
|
||||
ldflags = "/subsystem:console";
|
||||
extension = "exe";
|
||||
outdir = project->binaries;
|
||||
}
|
||||
else if (strcmp(package->kind, "dll") == 0)
|
||||
{
|
||||
ldflags = "/dll";
|
||||
extension = "dll";
|
||||
outdir = project->binaries;
|
||||
}
|
||||
else if (strcmp(package->kind, "lib") == 0)
|
||||
{
|
||||
ldflags =
|
||||
extension = "lib";
|
||||
outdir = project->libraries;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown package type '%s'\n", package->kind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Open the file and write the header
|
||||
file = openFile(package->path, package->name, ".dsp");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
writeProjectHeader(file, package);
|
||||
|
||||
fprintf(file, "CPP=cl.exe\n");
|
||||
fprintf(file, "MTL=midl.exe\n");
|
||||
fprintf(file, "RSC=rc.exe\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
char* runtime;
|
||||
|
||||
Config* config = package->config[i];
|
||||
|
||||
int size = inArray(config->buildFlags, "optimize-size");
|
||||
int speed = inArray(config->buildFlags, "optimize-speed") || inArray(config->buildFlags, "optimize");
|
||||
int debug = !size && !speed;
|
||||
int importlib = !inArray(config->buildFlags, "no-import-lib");
|
||||
int noMain = inArray(config->buildFlags, "no-main");
|
||||
int exceptions = !inArray(config->buildFlags, "no-exceptions");
|
||||
|
||||
int rtti = !inArray(config->buildFlags, "no-rtti");
|
||||
|
||||
if (inArray(config->linkFlags, "static-runtime") || inArray(config->buildFlags, "static-runtime"))
|
||||
runtime = (debug) ? "/MTd" : "/MT";
|
||||
else
|
||||
runtime = (debug) ? "/MDd" : "/MD";
|
||||
|
||||
fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"\n", (i == 0 ? "IF" : "ELSEIF"), replaceChars(package->name,"-"), config->name);
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# PROP BASE Use_MFC 0\n");
|
||||
fprintf(file, "# PROP BASE Use_Debug_Libraries %d\n", debug ? 1 : 0);
|
||||
fprintf(file, "# PROP BASE Output_Dir \"%s\\\"\n", debug ? "Debug" : "Release");
|
||||
fprintf(file, "# PROP BASE Intermediate_Dir \"%s\\\"\n", debug ? "Debug" : "Release");
|
||||
fprintf(file, "# PROP BASE Target_Dir \"\"\n");
|
||||
fprintf(file, "# PROP Use_MFC 0\n");
|
||||
fprintf(file, "# PROP Use_Debug_Libraries %d\n", debug ? 1 : 0);
|
||||
fprintf(file, "# PROP Output_Dir \"");
|
||||
fprintf(file, reversePath(package->path, outdir, WIN32));
|
||||
insertPath(file, getDirectory(config->target), WIN32);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, "# PROP Intermediate_Dir \"%s\\\"\n", config->objdir);
|
||||
if (strcmp(package->kind, "lib") != 0)
|
||||
fprintf(file, "# PROP Ignore_Export_Lib %d\n", importlib ? 0 : 1);
|
||||
fprintf(file, "# PROP Target_Dir \"\"\n");
|
||||
|
||||
fprintf(file, "# ADD BASE CPP /nologo /W3");
|
||||
if (debug)
|
||||
fprintf(file, " /Gm /GX /ZI /Od /D \"_DEBUG\" /YX /FD /GZ /c\n");
|
||||
else
|
||||
fprintf(file, " /GX /O2 /D \"NDEBUG\" /YX /FD /c\n");
|
||||
|
||||
fprintf(file, "# ADD CPP /nologo %s /W3", runtime);
|
||||
if (debug) fprintf(file, " /Gm /ZI /Od");
|
||||
|
||||
if (exceptions) fprintf(file, " /GX");
|
||||
|
||||
if (rtti) fprintf(file, " /GR");
|
||||
|
||||
if (size) fprintf(file, " /O1");
|
||||
if (speed) fprintf(file, " /O2");
|
||||
writeList(file, config->defines, " /D \"", "\"", "", NULL, NULL);
|
||||
writeList(file, config->includePaths, " /I \"", "\"", "", NULL, NULL);
|
||||
writeList(file, config->buildOptions, "", "", " ", NULL, NULL);
|
||||
|
||||
if (config->pchHeader)
|
||||
fprintf(file, " /Yu\"%s\"", config->pchHeader);
|
||||
else
|
||||
fprintf(file, " /YX");
|
||||
|
||||
if (debug)
|
||||
fprintf(file, " /FD /GZ /c\n");
|
||||
else
|
||||
fprintf(file, " /FD /c\n");
|
||||
|
||||
if (strcmp(package->kind, "lib") != 0)
|
||||
{
|
||||
fprintf(file, "# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\n");
|
||||
fprintf(file, "# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\n");
|
||||
}
|
||||
|
||||
fprintf(file, "# ADD BASE RSC /l 0x409 /d \"NDEBUG\"\n");
|
||||
fprintf(file, "# ADD RSC /l 0x409 /d \"NDEBUG\"\n");
|
||||
fprintf(file, "BSC32=bscmake.exe\n");
|
||||
fprintf(file, "# ADD BASE BSC32 /nologo\n");
|
||||
fprintf(file, "# ADD BSC32 /nologo\n");
|
||||
|
||||
if (strcmp(package->kind, "lib") != 0)
|
||||
{
|
||||
fprintf(file, "LINK32=link.exe\n");
|
||||
fprintf(file, "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo %s /machine:I386 %s\n",
|
||||
ldflags, debug ? "/debug /pdbtype:sept" : "");
|
||||
|
||||
fprintf(file, "# ADD LINK32");
|
||||
writeList(file, config->links, " ", ".lib", "", checkLink, &i);
|
||||
fprintf(file, " /nologo %s", ldflags);
|
||||
if (strcmp(package->kind, "winexe") == 0 && !noMain)
|
||||
fprintf(file, " /entry:\"mainCRTStartup\"");
|
||||
fprintf(file, " /out:\"%s", reversePath(package->path, project->binaries, WIN32));
|
||||
fprintf(file, "%s.%s\"", translatePath(config->target,WIN32), extension);
|
||||
fprintf(file, " /machine:I386");
|
||||
if (strcmp(package->kind, "dll") == 0)
|
||||
{
|
||||
fprintf(file, " /implib:\"");
|
||||
if (importlib)
|
||||
fprintf(file, reversePath(package->path, project->libraries, WIN32));
|
||||
else
|
||||
fprintf(file, "$(IntDir)\\");
|
||||
fprintf(file, "%s.lib\"", translatePath(config->target, WIN32));
|
||||
}
|
||||
fprintf(file, " /pdbtype:sept /libpath:\"%s\"", reversePath(package->path, project->libraries, WIN32));
|
||||
if (debug) {
|
||||
fprintf(file, " /pdb:\"%s", reversePath(package->path,project->binaries,WIN32));
|
||||
fprintf(file, "%s.pdb\" /debug", translatePath(config->target,WIN32));
|
||||
}
|
||||
writeList(file, config->linkOptions, " ", "", "", NULL, NULL);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "LIB32=link.exe -lib\n");
|
||||
fprintf(file, "# ADD BASE LIB32 /nologo\n");
|
||||
fprintf(file, "# ADD LIB32 /nologo /out:\"%s", reversePath(package->path, project->libraries, WIN32));
|
||||
fprintf(file, "%s.%s\"\n", translatePath(config->target,WIN32), extension);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "!ENDIF \n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# Begin Target\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
fprintf(file, "# Name \"%s - Win32 %s\"\n", replaceChars(package->name,"-"), package->config[i]->name);
|
||||
walkSourceList(file, package, "", vcFiles);
|
||||
|
||||
fprintf(file, "# End Target\n");
|
||||
fprintf(file, "# End Project\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if VS6_DOTNET
|
||||
|
||||
static const char* checkRef(const char* path, void* data)
|
||||
{
|
||||
Package* package = getPackage(path);
|
||||
if (package == NULL) return path;
|
||||
|
||||
if (strcmp(package->language, "c#") == 0)
|
||||
return package->config[*((int*)data)]->target;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int writeCsProject(Package* package)
|
||||
{
|
||||
const char* extension;
|
||||
FILE* file;
|
||||
int i, j;
|
||||
|
||||
const char* kind = package->kind;
|
||||
|
||||
// .NET requires all configurations use the same assembly filespec
|
||||
const char* target = package->config[0]->target;
|
||||
|
||||
// Figure out the object type
|
||||
if (strcmp(kind, "winexe") == 0)
|
||||
{
|
||||
extension = "exe";
|
||||
}
|
||||
else if (strcmp(kind, "exe") == 0)
|
||||
{
|
||||
extension = "exe";
|
||||
}
|
||||
else if (strcmp(kind, "dll") == 0)
|
||||
{
|
||||
extension = "dll";
|
||||
kind = "library";
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown package type '%s'\n", kind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Open the project file and write the header
|
||||
|
||||
file = openFile(package->path, package->name, ".dsp");
|
||||
if (file == NULL) return 0;
|
||||
if (!writeProjectHeader(file, package)) return 0;
|
||||
|
||||
fprintf(file, "MTL=midl.exe\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
Config* config = package->config[i];
|
||||
|
||||
int symbols = !inArray(config->buildFlags, "no-symbols");
|
||||
int optimize = inArray(config->buildFlags,"optimize") || inArray(config->buildFlags,"optimize-size") && inArray(config->buildFlags,"optimize-speed");
|
||||
int unsafe = inArray(config->buildFlags, "unsafe");
|
||||
|
||||
fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"\n", i == 0 ? "IF" : "ELSEIF", replaceChars(package->name,"-"), config->name);
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# PROP BASE Use_MFC 0\n");
|
||||
fprintf(file, "# PROP BASE Use_Debug_Libraries 1\n");
|
||||
fprintf(file, "# PROP BASE Output_Dir \"Release\"\n");
|
||||
fprintf(file, "# PROP BASE Intermediate_Dir \"Release\"\n");
|
||||
fprintf(file, "# PROP BASE Target_Dir \"\"\n");
|
||||
fprintf(file, "# PROP Use_MFC 0\n");
|
||||
fprintf(file, "# PROP Use_Debug_Libraries 0\n");
|
||||
fprintf(file, "# PROP Output_Dir \"");
|
||||
fprintf(file, reversePath(package->path, project->binaries, WIN32));
|
||||
insertPath(file, getDirectory(config->target), WIN32);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, "# PROP Intermediate_Dir \"%s\"\n", config->objdir);
|
||||
fprintf(file, "# PROP Target_Dir \"\"\n");
|
||||
fprintf(file, "# Begin Special Build Tool\n");
|
||||
fprintf(file, "SOURCE=\"$(InputPath)\"\n");
|
||||
|
||||
fprintf(file, "PostBuild_Cmds=$(DOTNET_PATH)\\%s /nologo", csc);
|
||||
fprintf(file, " /out:\"%s", reversePath(package->path,project->binaries,WIN32));
|
||||
fprintf(file, "\\%s.%s\"", translatePath(config->target,WIN32), extension);
|
||||
fprintf(file, " /target:%s", kind);
|
||||
if (symbols) fprintf(file, " /debug");
|
||||
if (optimize) fprintf(file, " /optimize");
|
||||
if (unsafe) fprintf(file, " /unsafe");
|
||||
fprintf(file, " /lib:\"%s\"", reversePath(package->path, project->binaries, WIN32));
|
||||
writeList(file, config->links, " /r:", ".dll", "", checkRef, &i);
|
||||
fprintf(file, " %s\\*.cs\n", config->objdir);
|
||||
|
||||
fprintf(file, "# End Special Build Tool\n");
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
fprintf(file, "!ENDIF\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# Begin Target\n");
|
||||
fprintf(file, "\n");
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
fprintf(file, "# Name \"%s - Win32 %s\"\n", replaceChars(package->name,"-"), package->config[i]->name);
|
||||
for (i = 0; i < package->numFiles; ++i)
|
||||
{
|
||||
const char* source = package->files[i];
|
||||
|
||||
fprintf(file, "# Begin Source File\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "SOURCE=.\\%s\n", translatePath(source, WIN32));
|
||||
fprintf(file, "\n");
|
||||
|
||||
for (j = 0; j < package->numConfigs; ++j)
|
||||
{
|
||||
Config* config = package->config[j];
|
||||
|
||||
fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"", (i == 0 ? "IF" : "ELSEIF"), replaceChars(package->name,"-"), config->name);
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# Begin Custom Build - %s\n", source);
|
||||
fprintf(file, "IntDir=.\\%s\n", config->objdir);
|
||||
fprintf(file, "InputPath=.\\%s\n", translatePath(source, WIN32));
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "\"$(INTDIR)\\%s\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n", translatePath(source, WIN32));
|
||||
fprintf(file, "\tcopy $(InputPath) $(IntDir)\\%s > out\n", translatePath(source, WIN32));
|
||||
fprintf(file, "\terase out\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# End Custom Build\n");
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
fprintf(file, "!ENDIF \n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# End Source File\n");
|
||||
}
|
||||
|
||||
fprintf(file, "# End Target\n");
|
||||
fprintf(file, "# End Project\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int writeProjectHeader(FILE* file, Package* package)
|
||||
{
|
||||
int i;
|
||||
const char* tag;
|
||||
const char* num;
|
||||
|
||||
const char* name = replaceChars(package->name, "-");
|
||||
|
||||
if (strcmp(package->language, "c#") == 0)
|
||||
{
|
||||
tag = "Win32 (x86) Generic Project";
|
||||
num = "0x010a";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(package->kind, "winexe") == 0)
|
||||
{
|
||||
tag = "Win32 (x86) Application";
|
||||
num = "0x0101";
|
||||
}
|
||||
else if (strcmp(package->kind, "exe") == 0)
|
||||
{
|
||||
tag = "Win32 (x86) Console Application";
|
||||
num = "0x0103";
|
||||
}
|
||||
else if (strcmp(package->kind, "dll") == 0)
|
||||
{
|
||||
tag = "Win32 (x86) Dynamic-Link Library";
|
||||
num = "0x0102";
|
||||
}
|
||||
else if (strcmp(package->kind, "lib") == 0)
|
||||
{
|
||||
tag = "Win32 (x86) Static Library";
|
||||
num = "0x0104";
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("** Error: unrecognized package type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "# Microsoft Developer Studio Project File - Name=\"%s\" - Package Owner=<4>\n", name);
|
||||
fprintf(file, "# Microsoft Developer Studio Generated Build File, Format Version 6.00\n");
|
||||
fprintf(file, "# ** DO NOT EDIT **\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# TARGTYPE \"%s\" %s\n", tag, num);
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "CFG=%s - Win32 Debug\n", name);
|
||||
fprintf(file, "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n");
|
||||
fprintf(file, "!MESSAGE use the Export Makefile command and run\n");
|
||||
fprintf(file, "!MESSAGE \n");
|
||||
fprintf(file, "!MESSAGE NMAKE /f \"%s.mak\".\n", package->name);
|
||||
fprintf(file, "!MESSAGE \n");
|
||||
fprintf(file, "!MESSAGE You can specify a configuration when running NMAKE\n");
|
||||
fprintf(file, "!MESSAGE by defining the macro CFG on the command line. For example:\n");
|
||||
fprintf(file, "!MESSAGE \n");
|
||||
fprintf(file, "!MESSAGE NMAKE /f \"%s.mak\" CFG=\"%s - Win32 Debug\"\n", package->name, name);
|
||||
fprintf(file, "!MESSAGE \n");
|
||||
fprintf(file, "!MESSAGE Possible choices for configuration are:\n");
|
||||
fprintf(file, "!MESSAGE \n");
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
fprintf(file, "!MESSAGE \"%s - Win32 %s\" (based on \"%s\")\n", name, package->config[i]->name, tag);
|
||||
fprintf(file, "!MESSAGE \n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "# Begin Project\n");
|
||||
fprintf(file, "# PROP AllowPerConfigDependencies 0\n");
|
||||
fprintf(file, "# PROP Scc_ProjName \"\"\n");
|
||||
fprintf(file, "# PROP Scc_LocalPath \"\"\n");
|
||||
|
||||
return 1;
|
||||
}
|
@ -1,927 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - vs_xml.c
|
||||
//
|
||||
// MS Visual Studio XML projects files (v7.0-2003)
|
||||
//
|
||||
// Copyright (C) 2002-2004 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: vs7.c,v 1.34 2004/05/11 00:38:58 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "project.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef struct _PkgData
|
||||
{
|
||||
char projGuid[38];
|
||||
char toolGuid[38];
|
||||
char projExt[8];
|
||||
char projType[8];
|
||||
} PkgData;
|
||||
|
||||
static char buffer[4096];
|
||||
|
||||
static int writeSolution(int version);
|
||||
static int writeVcProject(int version, Package* package);
|
||||
static int writeCsProject(int version, Package* package);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int makeVsXmlScripts(int version)
|
||||
{
|
||||
int i;
|
||||
printf("Generating Visual Studio %d solution and project files:\n", version);
|
||||
|
||||
// Assign UUIDs to all packages
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
PkgData* data = (PkgData*)malloc(sizeof(PkgData));
|
||||
package->data = data;
|
||||
generateUUID(data->projGuid);
|
||||
if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0)
|
||||
{
|
||||
strcpy(data->toolGuid, "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942");
|
||||
}
|
||||
else if (strcmp(package->language, "c#") == 0)
|
||||
{
|
||||
strcpy(data->toolGuid, "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unrecognized language '%s'\n", package->language);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the project files
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
PkgData* data = (PkgData*)package->data;
|
||||
|
||||
printf("...%s\n", package->name);
|
||||
|
||||
if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0)
|
||||
{
|
||||
strcpy(data->projExt, "vcproj");
|
||||
strcpy(data->projType, "Win32");
|
||||
if (!writeVcProject(version, package))
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (strcmp(package->language, "c#") == 0)
|
||||
{
|
||||
strcpy(data->projExt, "csproj");
|
||||
strcpy(data->projType, ".NET");
|
||||
if (!writeCsProject(version, package))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!writeSolution(version))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int numDeps = 0; /* Use by the project dependency writer */
|
||||
|
||||
/* Look for a package with the same name as 'name' and if found, return a
|
||||
* dependency description to be included in the solution file */
|
||||
static const char* checkProjectDependencies(const char* name, void* data)
|
||||
{
|
||||
int i;
|
||||
int version = (int)data;
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
if (strcmp(project->package[i]->name, name) == 0)
|
||||
{
|
||||
PkgData* data = (PkgData*)project->package[i]->data;
|
||||
if (version == 7)
|
||||
{
|
||||
sprintf(buffer, "%d = {%s}", numDeps++, data->projGuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "{%s} = {%s}", data->projGuid, data->projGuid);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int writeSolution(int version)
|
||||
{
|
||||
int i, j;
|
||||
FILE* file;
|
||||
|
||||
file = openFile(project->path, project->name, ".sln");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
/* Line 1: Format identification string */
|
||||
fprintf(file, "Microsoft Visual Studio Solution File, Format Version ");
|
||||
switch (version)
|
||||
{
|
||||
case 7:
|
||||
fprintf(file, "7.00\n");
|
||||
break;
|
||||
case 2003:
|
||||
fprintf(file, "8.00\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* List of projects that make up the solution */
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
PkgData* data = package->data;
|
||||
const char* name = package->name;
|
||||
const char* path = reversePath(project->path, package->path, WIN32);
|
||||
|
||||
/* VS.NET doesn't write out the leading '.\' on solution-relative
|
||||
* paths. Not really necessary, but I'm trying to match the original */
|
||||
if (strncmp(path, ".\\", 2) == 0)
|
||||
path = path + 2;
|
||||
|
||||
fprintf(file, "Project(\"{%s}\") = \"%s\", \"%s%s.%s\", \"{%s}\"\n", data->toolGuid, name, path, name, data->projExt, data->projGuid);
|
||||
if (version == 2003)
|
||||
{
|
||||
fprintf(file, "\tProjectSection(ProjectDependencies) = postProject\n");
|
||||
writeList(file, package->config[0]->links, "\t\t", "\n", "", checkProjectDependencies, (void*)version);
|
||||
fprintf(file, "\tEndProjectSection\n");
|
||||
}
|
||||
fprintf(file, "EndProject\n");
|
||||
}
|
||||
|
||||
fprintf(file, "Global\n");
|
||||
fprintf(file, "\tGlobalSection(SolutionConfiguration) = preSolution\n");
|
||||
for (i = 0; i < project->package[0]->numConfigs; ++i)
|
||||
{
|
||||
if (version == 7)
|
||||
{
|
||||
fprintf(file, "\t\tConfigName.%d = %s\n", i, project->package[0]->config[i]->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "\t\t%s = %s\n", project->package[0]->config[i]->name, project->package[0]->config[i]->name);
|
||||
}
|
||||
}
|
||||
fprintf(file, "\tEndGlobalSection\n");
|
||||
|
||||
/* Find package dependencies for VS7 */
|
||||
if (version == 7)
|
||||
{
|
||||
fprintf(file, "\tGlobalSection(ProjectDependencies) = postSolution\n");
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
char prefix[128];
|
||||
Package* package = project->package[i];
|
||||
PkgData* data = (PkgData*)package->data;
|
||||
Config* config = package->config[0];
|
||||
|
||||
numDeps = 0;
|
||||
sprintf(prefix, "\t\t{%s}.", data->projGuid);
|
||||
writeList(file, config->links, prefix, "\n", "", checkProjectDependencies, (void*)version);
|
||||
}
|
||||
fprintf(file, "\tEndGlobalSection\n");
|
||||
}
|
||||
|
||||
// Write configuration for each project
|
||||
fprintf(file, "\tGlobalSection(ProjectConfiguration) = postSolution\n");
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
Package* package = project->package[i];
|
||||
for (j = 0; j < package->numConfigs; ++j)
|
||||
{
|
||||
Config* config = package->config[j];
|
||||
PkgData* data = (PkgData*)package->data;
|
||||
fprintf(file, "\t\t{%s}.%s.ActiveCfg = %s|%s\n", data->projGuid, config->name, config->name, data->projType);
|
||||
if (config->build)
|
||||
fprintf(file, "\t\t{%s}.%s.Build.0 = %s|%s\n", data->projGuid, config->name, config->name, data->projType);
|
||||
}
|
||||
}
|
||||
fprintf(file, "\tEndGlobalSection\n");
|
||||
|
||||
// Finish
|
||||
|
||||
fprintf(file, "\tGlobalSection(ExtensibilityGlobals) = postSolution\n");
|
||||
fprintf(file, "\tEndGlobalSection\n");
|
||||
fprintf(file, "\tGlobalSection(ExtensibilityAddIns) = postSolution\n");
|
||||
fprintf(file, "\tEndGlobalSection\n");
|
||||
fprintf(file, "EndGlobal\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* checkDir(const char* path, void* data)
|
||||
{
|
||||
return translatePath(path, WIN32);
|
||||
}
|
||||
|
||||
static const char* checkLibs(const char* file, void* data)
|
||||
{
|
||||
Package* package = getPackage(file);
|
||||
if (package == NULL) return file;
|
||||
if (strcmp(package->language, "c++") != 0) return NULL;
|
||||
return package->config[*((int*)data)]->target;
|
||||
}
|
||||
|
||||
static void vcFiles(FILE* file, const char* path, const char* prefix, int stage)
|
||||
{
|
||||
static char fullpath[4096];
|
||||
char indent[128];
|
||||
char* ptr;
|
||||
int i=0, j=0;
|
||||
|
||||
strcpy(indent, " ");
|
||||
if (strlen(path) > 0) strcat(indent, " ");
|
||||
ptr = strchr(path, '/');
|
||||
while (ptr != NULL) {
|
||||
strcat(indent, " ");
|
||||
ptr = strchr(ptr + 1, '/');
|
||||
}
|
||||
|
||||
ptr = strrchr(path, '/');
|
||||
ptr = (ptr == NULL) ? (char*)path : ptr + 1;
|
||||
|
||||
switch (stage)
|
||||
{
|
||||
case WST_OPENGROUP:
|
||||
if (strlen(path) > 0 && strcmp(ptr, "..") != 0)
|
||||
{
|
||||
fprintf(file, "%s<Filter\n", indent);
|
||||
fprintf(file, "%s Name=\"%s\"\n", indent, ptr);
|
||||
fprintf(file, "%s Filter=\"\">\n", indent);
|
||||
}
|
||||
break;
|
||||
|
||||
case WST_CLOSEGROUP:
|
||||
if (strlen(path) > 0 && strcmp(ptr, "..") != 0)
|
||||
fprintf(file, "%s</Filter>\n", indent);
|
||||
break;
|
||||
|
||||
case WST_SOURCEFILE:
|
||||
fprintf(file, "%s<File\n", indent);
|
||||
strcpy(fullpath, prefix?translatePath(prefix, WIN32):"");
|
||||
strcat(fullpath, translatePath(path, WIN32));
|
||||
fprintf(file, "%s RelativePath=\"%s\">\n", indent, fullpath);
|
||||
for (i=0;i<project->numPackages;i++)
|
||||
{
|
||||
Package *package=project->package[i];
|
||||
for (j=0;j<package->numConfigs;j++)
|
||||
{
|
||||
Config *config=package->config[j];
|
||||
const char *nasmPath = translatePath(config->nasmPath, WIN32);
|
||||
|
||||
// JW 2005-09-29: fixed CommandLine to work with paths
|
||||
// containing spaces.
|
||||
if (endsWith(path, ".asm"))
|
||||
{
|
||||
fprintf(file, "%s <FileConfiguration Name=\"%s|Win32\">\n", indent, config->name);
|
||||
fprintf(file, "%s <Tool Name=\"VCCustomBuildTool\" "
|
||||
"Description=\"Assembling $(InputPath)\" "
|
||||
"CommandLine=\"%s -f win32 -o "$(IntDir)\\$(InputName).asm.obj" "$(InputPath)"\" "
|
||||
"Outputs=\"$(IntDir)\\$(InputName).asm.obj\" />", indent, nasmPath);
|
||||
fprintf(file, "%s </FileConfiguration>", indent);
|
||||
}
|
||||
// Skip PCH for assembler files
|
||||
else if (config->pchSource && strcmp(ptr, config->pchSource)==0)
|
||||
{
|
||||
fprintf(file, "%s <FileConfiguration Name=\"%s|Win32\">\n", indent, config->name);
|
||||
fprintf(file, "%s <Tool Name=\"VCCLCompilerTool\" UsePrecompiledHeader=\"1\" />\n", indent);
|
||||
fprintf(file, "%s </FileConfiguration>", indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(file, "%s</File>\n", indent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int writeVcProject(int version, Package* package)
|
||||
{
|
||||
int configType, subsystem, managed, i;
|
||||
const char* extension;
|
||||
FILE* file;
|
||||
|
||||
const char* name = package->name;
|
||||
const char* path = package->path;
|
||||
const char* kind = package->kind;
|
||||
PkgData* data = (PkgData*)package->data;
|
||||
|
||||
// Set up target type information
|
||||
|
||||
if (strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0)
|
||||
{
|
||||
configType = 1;
|
||||
extension = "exe";
|
||||
}
|
||||
else if (strcmp(kind, "dll") == 0)
|
||||
{
|
||||
configType = 2;
|
||||
extension = "dll";
|
||||
}
|
||||
else if (strcmp(kind, "lib") == 0)
|
||||
{
|
||||
configType = 4;
|
||||
extension = "lib";
|
||||
}
|
||||
else if (strcmp(kind, "aspnet") == 0)
|
||||
{
|
||||
puts("** Error: C++ ASP.NET projects are not supported");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown package kind '%s'\n", kind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check the build subsystem...must be the same for all configs
|
||||
|
||||
subsystem = (strcmp(kind, "exe") == 0) ? 1 : 2;
|
||||
managed = inArray(package->config[0]->buildFlags, "managed");
|
||||
|
||||
// Open the file and write the header
|
||||
|
||||
file = openFile(path, name, ".vcproj");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
fprintf(file, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n");
|
||||
fprintf(file, "<VisualStudioProject\n");
|
||||
fprintf(file, " ProjectType=\"Visual C++\"\n");
|
||||
fprintf(file, " Version=\"");
|
||||
switch (version)
|
||||
{
|
||||
case 7:
|
||||
fprintf(file, "7.00");
|
||||
break;
|
||||
case 2003:
|
||||
fprintf(file, "7.10");
|
||||
break;
|
||||
}
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " Name=\"%s\"\n", name);
|
||||
fprintf(file, " ProjectGUID=\"{%s}\"\n", data->projGuid);
|
||||
fprintf(file, " Keyword=\"%s\">\n", managed ? "ManagedCProj" : "Win32Proj");
|
||||
fprintf(file, " <Platforms>\n");
|
||||
fprintf(file, " <Platform\n");
|
||||
fprintf(file, " Name=\"Win32\"/>\n");
|
||||
fprintf(file, " </Platforms>\n");
|
||||
|
||||
// Write configurations
|
||||
|
||||
fprintf(file, " <Configurations>\n");
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
int optLevel, debug, symbols, runtime, noMain;
|
||||
Config* config = package->config[i];
|
||||
|
||||
int optimize = inArray(config->buildFlags, "optimize");
|
||||
int size = inArray(config->buildFlags, "optimize-size");
|
||||
int speed = inArray(config->buildFlags, "optimize-speed");
|
||||
|
||||
int check64bit = !inArray(config->buildFlags, "no-64bit-checks");
|
||||
int importlib = !inArray(config->buildFlags, "no-import-lib");
|
||||
int exceptions = !inArray(config->buildFlags, "no-exceptions");
|
||||
int rtti = !inArray(config->buildFlags, "no-rtti");
|
||||
int rtc = !inArray(config->buildFlags, "no-runtime-checks");
|
||||
|
||||
if (speed)
|
||||
optLevel = 2;
|
||||
else if (size)
|
||||
optLevel = 1;
|
||||
else if (optimize)
|
||||
optLevel = 3;
|
||||
else
|
||||
optLevel = 0;
|
||||
debug = (optLevel == 0);
|
||||
|
||||
if (!inArray(config->buildFlags, "no-symbols"))
|
||||
symbols = (managed || inArray(config->buildFlags, "no-edit-and-continue")) ? 3 : 4;
|
||||
else
|
||||
symbols = 0;
|
||||
|
||||
if (inArray(config->linkFlags, "static-runtime") || inArray(config->buildFlags, "static-runtime"))
|
||||
runtime = (debug) ? 1 : 0;
|
||||
else
|
||||
runtime = (debug) ? 3 : 2;
|
||||
|
||||
noMain = inArray(config->buildFlags, "no-main");
|
||||
|
||||
fprintf(file, " <Configuration\n");
|
||||
fprintf(file, " Name=\"%s|Win32\"\n", config->name);
|
||||
fprintf(file, " OutputDirectory=\"");
|
||||
fprintf(file, reversePath(path, (configType != 4 ? project->binaries : project->libraries), WIN32));
|
||||
insertPath(file, getDirectory(config->target), WIN32);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " IntermediateDirectory=\"%s\\\"\n", config->objdir);
|
||||
fprintf(file, " ConfigurationType=\"%d\"\n", configType);
|
||||
fprintf(file, " CharacterSet=\"2\"");
|
||||
if (managed) fprintf(file, "\n ManagedExtensions=\"TRUE\"");
|
||||
fprintf(file, ">\n");
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCCLCompilerTool\"\n");
|
||||
fprintf(file, " Optimization=\"%d\"\n", optLevel);
|
||||
if (!debug) fprintf(file, " InlineFunctionExpansion=\"1\"\n");
|
||||
if (!debug) fprintf(file, " OmitFramePointers=\"TRUE\"\n");
|
||||
fprintf(file, " AdditionalOptions=\"");
|
||||
writeList(file, config->buildOptions, "", "", " ", NULL, NULL);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " AdditionalIncludeDirectories=\"");
|
||||
writeList(file, config->includePaths, "", "", ",", checkDir, NULL);
|
||||
fprintf(file, "\"\n");
|
||||
if (managed)
|
||||
{
|
||||
fprintf(file, " AdditionalUsingDirectories=\"");
|
||||
fprintf(file, reversePath(path, project->binaries, WIN32));
|
||||
fprintf(file, "\"\n");
|
||||
}
|
||||
fprintf(file, " PreprocessorDefinitions=\"");
|
||||
writeList(file, config->defines, "", "", ";", NULL, NULL);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " MinimalRebuild=\"%s\"\n", (debug && !managed) ? "TRUE" : "FALSE");
|
||||
if (!exceptions) fprintf(file, " ExceptionHandling=\"FALSE\"\n");
|
||||
fprintf(file, " BasicRuntimeChecks=\"%d\"\n", (debug && !managed && rtc) ? 3 : 0);
|
||||
if (!debug) fprintf(file, " StringPooling=\"TRUE\"\n");
|
||||
if (!debug) fprintf(file, " EnableFunctionLevelLinking=\"TRUE\"\n");
|
||||
fprintf(file, " RuntimeLibrary=\"%d\"\n", runtime);
|
||||
if (rtti)
|
||||
fprintf(file, " RuntimeTypeInfo=\"TRUE\"\n");
|
||||
|
||||
if (config->pchHeader)
|
||||
{
|
||||
fprintf(file, " UsePrecompiledHeader=\"3\"\n");
|
||||
fprintf(file, " PrecompiledHeaderThrough=\"%s\"\n", config->pchHeader);
|
||||
}
|
||||
else
|
||||
fprintf(file, " UsePrecompiledHeader=\"0\"\n");
|
||||
|
||||
fprintf(file, " WarningLevel=\"4\"\n");
|
||||
if (!managed) fprintf(file, " Detect64BitPortabilityProblems=\"%s\"\n", check64bit ? "TRUE" : "FALSE");
|
||||
fprintf(file, " DebugInformationFormat=\"%d\"/>\n", symbols);
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCCustomBuildTool\"/>\n");
|
||||
|
||||
if (configType != 4)
|
||||
{
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCLinkerTool\"\n");
|
||||
fprintf(file, " IgnoreImportLibrary=\"%s\"\n", importlib ? "TRUE" : "FALSE");
|
||||
fprintf(file, " AdditionalOptions=\"");
|
||||
writeList(file, config->linkOptions, " ", "", "", NULL, NULL);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " AdditionalDependencies=\"");
|
||||
writeList(file, config->links, "", ".lib", " ", checkLibs, &i);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " OutputFile=\"$(OutDir)\\%s.%s\"\n", getFilename(config->target, 0), extension);
|
||||
fprintf(file, " LinkIncremental=\"%d\"\n", debug ? 2 : 1);
|
||||
fprintf(file, " AdditionalLibraryDirectories=\"");
|
||||
fprintf(file, reversePath(path, project->libraries, WIN32));
|
||||
writeList(file, config->libPaths, ";", "", "", checkDir, NULL);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " GenerateDebugInformation=\"%s\"\n", symbols ? "TRUE" : "FALSE");
|
||||
|
||||
if (symbols)
|
||||
{
|
||||
if (project->debugfiles)
|
||||
{
|
||||
fprintf(file, " ProgramDatabaseFile=\"");
|
||||
fprintf(file, reversePath(path, project->debugfiles, WIN32));
|
||||
fprintf(file, "%s.pdb\"\n", getFilename(config->target, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, " ProgramDatabaseFile=\"%s\\%s.pdb\"\n", config->objdir, getFilename(config->target, 0));
|
||||
}
|
||||
}
|
||||
fprintf(file, " SubSystem=\"%d\"\n", subsystem);
|
||||
if (!debug) fprintf(file, " OptimizeReferences=\"2\"\n");
|
||||
if (!debug) fprintf(file, " EnableCOMDATFolding=\"2\"\n");
|
||||
if ((strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0) && !noMain)
|
||||
fprintf(file, " EntryPointSymbol=\"mainCRTStartup\"\n");
|
||||
else if (strcmp(kind, "dll") == 0) {
|
||||
fprintf(file, " ImportLibrary=\"");
|
||||
if (importlib)
|
||||
fprintf(file, reversePath(path, project->libraries, WIN32));
|
||||
else
|
||||
fprintf(file, "$(IntDir)");
|
||||
fprintf(file, "%s.lib\"\n", getFilename(config->target, 1));
|
||||
}
|
||||
fprintf(file, " TargetMachine=\"1\"/>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCLibrarianTool\"\n");
|
||||
fprintf(file, " OutputFile=\"$(OutDir)\\%s.lib\"/>\n", config->target);
|
||||
}
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCMIDLTool\"/>\n");
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCPostBuildEventTool\"/>\n");
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCPreBuildEventTool\"/>\n");
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCPreLinkEventTool\"/>\n");
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCResourceCompilerTool\"/>\n");
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCWebServiceProxyGeneratorTool\"/>\n");
|
||||
|
||||
fprintf(file, " <Tool\n");
|
||||
fprintf(file, " Name=\"VCWebDeploymentTool\"/>\n");
|
||||
fprintf(file, " </Configuration>\n");
|
||||
}
|
||||
|
||||
fprintf(file, " </Configurations>\n");
|
||||
|
||||
fprintf(file, " <Files>\n");
|
||||
walkSourceList(file, package, "", vcFiles);
|
||||
fprintf(file, " </Files>\n");
|
||||
|
||||
fprintf(file, " <Globals>\n");
|
||||
fprintf(file, " </Globals>\n");
|
||||
fprintf(file, "</VisualStudioProject>\n");
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* checkRefs(const char* ref, void* data)
|
||||
{
|
||||
int i;
|
||||
char* comma;
|
||||
char tmp[1024];
|
||||
|
||||
// Pull the name out of the full reference
|
||||
strcpy(tmp, ref);
|
||||
comma = strchr(tmp, ',');
|
||||
if (comma != NULL)
|
||||
*comma = '\0';
|
||||
|
||||
// Write the reference name
|
||||
strcpy(buffer, " Name = \"");
|
||||
strcat(buffer, tmp);
|
||||
strcat(buffer, "\"\n");
|
||||
|
||||
// Is this a sibling project?
|
||||
for (i = 0; i < project->numPackages; ++i)
|
||||
{
|
||||
if (strcmp(project->package[i]->name, ref) == 0)
|
||||
{
|
||||
PkgData* data = (PkgData*)project->package[i]->data;
|
||||
strcat(buffer, " Project = \"{");
|
||||
strcat(buffer, data->projGuid);
|
||||
strcat(buffer, "}\"\n");
|
||||
strcat(buffer, " Package = \"{");
|
||||
strcat(buffer, data->toolGuid);
|
||||
strcat(buffer, "}\"\n");
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
strcat(buffer, " AssemblyName = \"");
|
||||
strcat(buffer, getFilename(tmp, 0));
|
||||
strcat(buffer, "\"\n");
|
||||
if (strlen(tmp) != strlen(getFilename(tmp, 0))) {
|
||||
strcat(buffer, " HintPath = \"");
|
||||
strcat(buffer, tmp);
|
||||
strcat(buffer, ".dll\"\n");
|
||||
}
|
||||
|
||||
// Tack on any extra information about the assembly
|
||||
while (comma != NULL)
|
||||
{
|
||||
char* start;
|
||||
for (start = comma + 1; *start == ' '; ++start);
|
||||
comma = strchr(start, '=');
|
||||
*comma = '\0';
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, start);
|
||||
strcat(buffer, " = \"");
|
||||
|
||||
start = comma + 1;
|
||||
comma = strchr(start, ',');
|
||||
if (comma != NULL) *comma = '\0';
|
||||
strcat(buffer, start);
|
||||
strcat(buffer, "\"\n");
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char* checkRefPaths(const char* ref, void* data)
|
||||
{
|
||||
const char* projPath = (const char*)data;
|
||||
return makeAbsolute(projPath, ref);
|
||||
}
|
||||
|
||||
static const char* checkSrcFileType(const char* file, void* data)
|
||||
{
|
||||
Package* package = (Package*)data;
|
||||
|
||||
strcpy(buffer, translatePath(file, WIN32));
|
||||
strcat(buffer, "\"\n");
|
||||
|
||||
if (endsWith(file, ".aspx.cs") || endsWith(file, ".asax.cs"))
|
||||
{
|
||||
/* The path to the parent .aspx file is relative to the .cs file.
|
||||
* I assume that they are in the same directory and strip off all
|
||||
* path information, then cut off the '.cs' */
|
||||
char* ptr = strrchr(file, '/');
|
||||
if (ptr == NULL)
|
||||
ptr = (char*)file;
|
||||
else
|
||||
ptr++;
|
||||
|
||||
strcat(buffer, "\t\t\t\t\tDependentUpon = \"");
|
||||
strncat(buffer, ptr, strlen(ptr) - 3);
|
||||
strcat(buffer, "\"\n");
|
||||
strcat(buffer, "\t\t\t\t\tSubType = \"ASPXCodeBehind\"\n");
|
||||
strcat(buffer, "\t\t\t\t\tBuildAction = \"Compile\"\n");
|
||||
}
|
||||
/* obsolete, handled by ".resx" block below
|
||||
else if (endsWith(file, ".aspx.resx") || endsWith(file, ".asax.resx"))
|
||||
{
|
||||
strcat(buffer, "\t\t\t\t\tDependentUpon = \"");
|
||||
strncat(buffer, file, strlen(file) - 5);
|
||||
strcat(buffer, ".cs\"\n");
|
||||
strcat(buffer, "\t\t\t\t\tBuildAction = \"EmbeddedResource\"\n");
|
||||
}
|
||||
*/
|
||||
else if (endsWith(file, ".cs"))
|
||||
{
|
||||
strcat(buffer, "\t\t\t\t\tSubType = \"Code\"\n");
|
||||
strcat(buffer, "\t\t\t\t\tBuildAction = \"Compile\"\n");
|
||||
}
|
||||
else if (endsWith(file, ".aspx"))
|
||||
{
|
||||
strcat(buffer, "\t\t\t\t\tSubType = \"Form\"\n");
|
||||
strcat(buffer, "\t\t\t\t\tBuildAction = \"Content\"\n");
|
||||
}
|
||||
else if (endsWith(file, ".asax"))
|
||||
{
|
||||
strcat(buffer, "\t\t\t\t\tSubType = \"Component\"\n");
|
||||
strcat(buffer, "\t\t\t\t\tBuildAction = \"Content\"\n");
|
||||
}
|
||||
else if (endsWith(file, ".resx"))
|
||||
{
|
||||
/* If a matching .cs file exists, link it */
|
||||
char depname[2048];
|
||||
strcpy(depname, file);
|
||||
strcpy(depname + strlen(file) - 5, ".cs");
|
||||
if (inArray(package->files, depname))
|
||||
{
|
||||
/* Path is relative to .resx file, I assume both are in same
|
||||
* directory and cut off path information */
|
||||
char* ptr = strrchr(depname, '/');
|
||||
ptr = (ptr != NULL) ? ptr+1 : depname;
|
||||
strcat(buffer, "\t\t\t\t\tDependentUpon = \"");
|
||||
strcat(buffer, ptr);
|
||||
strcat(buffer, "\"\n");
|
||||
}
|
||||
strcat(buffer, "\t\t\t\t\tBuildAction = \"EmbeddedResource\"\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(buffer, "\t\t\t\t\tBuildAction = \"");
|
||||
strcat(buffer, strcmp(package->kind, "aspnet") == 0 ? "Content" : "None");
|
||||
strcat(buffer, "\"\n");
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int writeCsProject(int version, Package* package)
|
||||
{
|
||||
FILE* file;
|
||||
const char* target;
|
||||
const char* outputType;
|
||||
int i;
|
||||
|
||||
const char* name = package->name;
|
||||
const char* path = package->path;
|
||||
const char* kind = package->kind;
|
||||
PkgData* data = (PkgData*)package->data;
|
||||
|
||||
if (strcmp(kind, "winexe") == 0)
|
||||
outputType = "WinExe";
|
||||
else if (strcmp(kind, "exe") == 0)
|
||||
outputType = "Exe";
|
||||
else if (strcmp(kind, "dll") == 0 || strcmp(kind, "aspnet") == 0)
|
||||
outputType = "Library";
|
||||
else
|
||||
{
|
||||
printf("** Error: unknown package kind '%s'\n", kind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Open the project file and write the header
|
||||
file = openFile(path, name, ".csproj");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
fprintf(file, "<VisualStudioProject>\n");
|
||||
fprintf(file, " <CSHARP\n");
|
||||
fprintf(file, " ProjectType = \"");
|
||||
fprintf(file, strcmp(kind, "aspnet") == 0 ? "Web" : "Local");
|
||||
fprintf(file, "\"\n");
|
||||
switch (version)
|
||||
{
|
||||
case 7:
|
||||
fprintf(file, " ProductVersion = \"7.0.9254\"\n");
|
||||
fprintf(file, " SchemaVersion = \"1.0\"\n");
|
||||
break;
|
||||
case 2003:
|
||||
fprintf(file, " ProductVersion = \"7.10.3077\"\n");
|
||||
fprintf(file, " SchemaVersion = \"2.0\"\n");
|
||||
break;
|
||||
}
|
||||
fprintf(file, " ProjectGuid = \"{%s}\"\n", data->projGuid);
|
||||
fprintf(file, " >\n");
|
||||
fprintf(file, " <Build>\n");
|
||||
fprintf(file, " <Settings\n");
|
||||
fprintf(file, " ApplicationIcon = \"\"\n");
|
||||
fprintf(file, " AssemblyKeyContainerName = \"\"\n");
|
||||
fprintf(file, " AssemblyName = \"%s\"\n", getFilename(package->config[0]->target, 0));
|
||||
fprintf(file, " AssemblyOriginatorKeyFile = \"\"\n");
|
||||
fprintf(file, " DefaultClientScript = \"JScript\"\n");
|
||||
fprintf(file, " DefaultHTMLPageLayout = \"Grid\"\n");
|
||||
fprintf(file, " DefaultTargetSchema = \"IE50\"\n");
|
||||
fprintf(file, " DelaySign = \"false\"\n");
|
||||
if (version == 7)
|
||||
{
|
||||
fprintf(file, " NoStandardLibraries = \"false\"\n");
|
||||
}
|
||||
fprintf(file, " OutputType = \"%s\"\n", outputType);
|
||||
if (version == 2003)
|
||||
{
|
||||
fprintf(file, " PreBuildEvent = \"\"\n");
|
||||
fprintf(file, " PostBuildEvent = \"\"\n");
|
||||
}
|
||||
fprintf(file, " RootNamespace = \"%s\"\n", getFilename(package->config[0]->target, 0));
|
||||
if (version == 2003)
|
||||
{
|
||||
fprintf(file, " RunPostBuildEvent = \"OnBuildSuccess\"\n");
|
||||
}
|
||||
|
||||
fprintf(file, " StartupObject = \"\"\n");
|
||||
fprintf(file, " >\n");
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
Config* config = package->config[i];
|
||||
|
||||
int symbols = !inArray(config->buildFlags, "no-symbols");
|
||||
int optimize = inArray(config->buildFlags, "optimize") || inArray(config->buildFlags, "optimize-size") || inArray(config->buildFlags, "optimize-speed");
|
||||
int unsafe = inArray(config->buildFlags, "unsafe");
|
||||
|
||||
fprintf(file, " <Config\n");
|
||||
fprintf(file, " Name = \"%s\"\n", config->name);
|
||||
fprintf(file, " AllowUnsafeBlocks = \"%s\"\n", unsafe ? "true" : "false");
|
||||
fprintf(file, " BaseAddress = \"285212672\"\n");
|
||||
fprintf(file, " CheckForOverflowUnderflow = \"false\"\n");
|
||||
fprintf(file, " ConfigurationOverrideFile = \"\"\n");
|
||||
fprintf(file, " DefineConstants = \"");
|
||||
writeList(file, config->defines, "", "", ";", NULL, NULL);
|
||||
fprintf(file, "\"\n");
|
||||
fprintf(file, " DocumentationFile = \"\"\n");
|
||||
fprintf(file, " DebugSymbols = \"%s\"\n", symbols ? "true" : "false");
|
||||
fprintf(file, " FileAlignment = \"4096\"\n");
|
||||
fprintf(file, " IncrementalBuild = \"");
|
||||
fprintf(file, strcmp(kind, "aspnet") == 0 ? "false" : "true");
|
||||
fprintf(file, "\"\n");
|
||||
if (version == 2003)
|
||||
{
|
||||
fprintf(file, " NoStdLib = \"false\"\n");
|
||||
fprintf(file, " NoWarn = \"\"\n");
|
||||
}
|
||||
fprintf(file, " Optimize = \"%s\"\n", optimize ? "true" : "false");
|
||||
|
||||
fprintf(file, " OutputPath = \"");
|
||||
fprintf(file, reversePath(path, project->binaries, WIN32));
|
||||
insertPath(file, getDirectory(config->target), WIN32);
|
||||
fprintf(file, "\"\n");
|
||||
|
||||
fprintf(file, " RegisterForComInterop = \"false\"\n");
|
||||
fprintf(file, " RemoveIntegerChecks = \"false\"\n");
|
||||
fprintf(file, " TreatWarningsAsErrors = \"false\"\n");
|
||||
fprintf(file, " WarningLevel = \"4\"\n");
|
||||
fprintf(file, " />\n");
|
||||
}
|
||||
|
||||
fprintf(file, " </Settings>\n");
|
||||
|
||||
// VS7 requires same references for all configurations
|
||||
fprintf(file, " <References>\n");
|
||||
writeList(file, package->config[0]->links, " <Reference\n", " />\n", "", checkRefs, package);
|
||||
fprintf(file, " </References>\n");
|
||||
fprintf(file, " </Build>\n");
|
||||
|
||||
fprintf(file, " <Files>\n");
|
||||
fprintf(file, " <Include>\n");
|
||||
writeList(file, package->files, " <File\n RelPath = \"", " />\n", "", checkSrcFileType, package);
|
||||
fprintf(file, " </Include>\n");
|
||||
fprintf(file, " </Files>\n");
|
||||
fprintf(file, " </CSHARP>\n");
|
||||
fprintf(file, "</VisualStudioProject>\n");
|
||||
|
||||
fclose(file);
|
||||
|
||||
// Now write the .csproj.user file for non-web applications or
|
||||
// .csproj.webinfo for web applications
|
||||
|
||||
if (strcmp(kind, "aspnet") != 0)
|
||||
{
|
||||
file = openFile(path, name, ".csproj.user");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
fprintf(file, "<VisualStudioProject>\n");
|
||||
fprintf(file, " <CSHARP>\n");
|
||||
fprintf(file, " <Build>\n");
|
||||
fprintf(file, " <Settings ReferencePath = \"");
|
||||
writeList(file, package->config[0]->libPaths, "", ";", "", checkRefPaths, (void*)path);
|
||||
target = makeAbsolute(".", project->binaries);
|
||||
if (target != NULL) fprintf(file, target);
|
||||
fprintf(file, "\" >\n");
|
||||
|
||||
for (i = 0; i < package->numConfigs; ++i)
|
||||
{
|
||||
fprintf(file, " <Config\n");
|
||||
fprintf(file, " Name = \"%s\"\n", package->config[i]->name);
|
||||
fprintf(file, " EnableASPDebugging = \"false\"\n");
|
||||
fprintf(file, " EnableASPXDebugging = \"false\"\n");
|
||||
fprintf(file, " EnableUnmanagedDebugging = \"false\"\n");
|
||||
fprintf(file, " EnableSQLServerDebugging = \"false\"\n");
|
||||
fprintf(file, " RemoteDebugEnabled = \"false\"\n");
|
||||
fprintf(file, " RemoteDebugMachine = \"\"\n");
|
||||
fprintf(file, " StartAction = \"Project\"\n");
|
||||
fprintf(file, " StartArguments = \"\"\n");
|
||||
fprintf(file, " StartPage = \"\"\n");
|
||||
fprintf(file, " StartProgram = \"\"\n");
|
||||
fprintf(file, " StartURL = \"\"\n");
|
||||
fprintf(file, " StartWorkingDirectory = \"\"\n");
|
||||
fprintf(file, " StartWithIE = \"false\"\n");
|
||||
fprintf(file, " />\n");
|
||||
}
|
||||
|
||||
fprintf(file, " </Settings>\n");
|
||||
fprintf(file, " </Build>\n");
|
||||
fprintf(file, " <OtherProjectSettings\n");
|
||||
fprintf(file, " CopyProjectDestinationFolder = \"\"\n");
|
||||
fprintf(file, " CopyProjectUncPath = \"\"\n");
|
||||
fprintf(file, " CopyProjectOption = \"0\"\n");
|
||||
fprintf(file, " ProjectView = \"ProjectFiles\"\n");
|
||||
fprintf(file, " ProjectTrust = \"0\"\n");
|
||||
fprintf(file, " />\n");
|
||||
fprintf(file, " </CSHARP>\n");
|
||||
fprintf(file, "</VisualStudioProject>\n");
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (package->url == NULL)
|
||||
{
|
||||
sprintf(buffer, "http://localhost/%s", package->name);
|
||||
package->url = buffer;
|
||||
}
|
||||
|
||||
file = openFile(path, name, ".csproj.webinfo");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
fprintf(file, "<VisualStudioUNCWeb>\n");
|
||||
fprintf(file, " <Web URLPath = \"%s/%s.csproj\" />\n", package->url, package->name);
|
||||
fprintf(file, "</VisualStudioUNCWeb>\n");
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Premake - windows.c
|
||||
//
|
||||
// MS Windows file and directory manipulation functions.
|
||||
//
|
||||
// Copyright (C) 2002-2004 by Jason Perkins
|
||||
// Source code licensed under the GPL, see LICENSE.txt for details.
|
||||
//
|
||||
// $Id: windows.c,v 1.10 2004/01/09 20:48:02 jason379 Exp $
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char nativePathSep = '\\';
|
||||
const char* osIdent = "windows";
|
||||
|
||||
static int (__stdcall *CoCreateGuid)(char*) = NULL;
|
||||
static HANDLE hDir;
|
||||
static WIN32_FIND_DATA entry;
|
||||
static int first;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_chdir(const char* path)
|
||||
{
|
||||
return SetCurrentDirectory(path);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_copyFile(const char* src, const char* dest)
|
||||
{
|
||||
return CopyFile(src, dest, FALSE);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void plat_deleteDir(const char* path)
|
||||
{
|
||||
WIN32_FIND_DATA data;
|
||||
HANDLE hDir;
|
||||
|
||||
char* buffer = (char*)malloc(strlen(path) + 6);
|
||||
strcpy(buffer, path);
|
||||
strcat(buffer, "\\*.*");
|
||||
hDir = FindFirstFile(buffer, &data);
|
||||
if (hDir == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
free(buffer);
|
||||
|
||||
do
|
||||
{
|
||||
if (strcmp(data.cFileName, ".") == 0) continue;
|
||||
if (strcmp(data.cFileName, "..") == 0) continue;
|
||||
|
||||
buffer = (char*)malloc(strlen(path) + strlen(data.cFileName) + 2);
|
||||
strcpy(buffer, path);
|
||||
strcat(buffer, "\\");
|
||||
strcat(buffer, data.cFileName);
|
||||
|
||||
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
plat_deleteDir(buffer);
|
||||
else
|
||||
DeleteFile(buffer);
|
||||
|
||||
free(buffer);
|
||||
} while (FindNextFile(hDir, &data));
|
||||
FindClose(hDir);
|
||||
|
||||
RemoveDirectory(path);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void plat_deleteFile(const char* path)
|
||||
{
|
||||
DeleteFile(path);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_findLib(const char* lib, char* buffer, int size)
|
||||
{
|
||||
HMODULE hLib = LoadLibrary(lib);
|
||||
if (hLib != NULL)
|
||||
{
|
||||
char* ptr;
|
||||
|
||||
GetModuleFileName(hLib, buffer, size);
|
||||
for (ptr = buffer; *ptr != '\0'; ++ptr)
|
||||
if (*ptr == '\\') *ptr = '/';
|
||||
|
||||
ptr = strrchr(buffer, '/');
|
||||
if (ptr) *ptr = '\0';
|
||||
|
||||
FreeLibrary(hLib);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void plat_generateUUID(char* uuid)
|
||||
{
|
||||
if (CoCreateGuid == NULL)
|
||||
{
|
||||
HMODULE hOleDll = LoadLibrary("OLE32.DLL");
|
||||
*((void**)&CoCreateGuid) = GetProcAddress(hOleDll, "CoCreateGuid");
|
||||
}
|
||||
|
||||
CoCreateGuid(uuid);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void plat_getcwd(char* buffer, int size)
|
||||
{
|
||||
GetCurrentDirectory(size, buffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_isAbsPath(const char* buffer)
|
||||
{
|
||||
return (buffer[0] == '/' || buffer[0] == '\\' || buffer[1] == ':');
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int plat_dirOpen(const char* mask)
|
||||
{
|
||||
hDir = FindFirstFile(mask, &entry);
|
||||
first = 1;
|
||||
return (hDir != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
void plat_dirClose()
|
||||
{
|
||||
if (hDir != INVALID_HANDLE_VALUE)
|
||||
FindClose(hDir);
|
||||
}
|
||||
|
||||
int plat_dirGetNext()
|
||||
{
|
||||
if (hDir == INVALID_HANDLE_VALUE) return 0;
|
||||
if (first)
|
||||
{
|
||||
first = !first;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FindNextFile(hDir, &entry);
|
||||
}
|
||||
}
|
||||
|
||||
const char* plat_dirGetName()
|
||||
{
|
||||
return entry.cFileName;
|
||||
}
|
||||
|
||||
int plat_dirIsFile()
|
||||
{
|
||||
return (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
project.name = "Premake"
|
||||
|
||||
package.language = "c++"
|
||||
package.kind = "exe"
|
||||
package.target = "premake"
|
||||
|
||||
package.buildflags = { "no-64bit-checks", "static-runtime" }
|
||||
package.config["Release"].buildflags = { "no-symbols", "optimize-size" }
|
||||
|
||||
package.files =
|
||||
{
|
||||
"Src/premake.c",
|
||||
"Src/project.h",
|
||||
"Src/project.c",
|
||||
"Src/util.h",
|
||||
"Src/util.c",
|
||||
"Src/clean.c",
|
||||
"Src/gnu.c",
|
||||
"Src/sharpdev.c",
|
||||
"Src/vs7.c",
|
||||
"Src/vs6.c",
|
||||
matchfiles("Src/Lua/*.c", "Src/Lua/*.h")
|
||||
}
|
||||
|
||||
if (OS == "windows") then
|
||||
tinsert(package.files, "Src/windows.c")
|
||||
else
|
||||
tinsert(package.files, "Src/posix.c")
|
||||
end
|
||||
|
@ -1,33 +1,14 @@
|
||||
@ECHO OFF
|
||||
REM Create Visual Studio Workspaces on Windows
|
||||
@echo off
|
||||
rem ** Create Visual Studio Workspaces on Windows **
|
||||
|
||||
mkdir vc6
|
||||
mkdir vc7
|
||||
mkdir vc2002
|
||||
mkdir vc2003
|
||||
|
||||
REM Change to the lua project name, this must correspond to the base file name
|
||||
REM of the created project files
|
||||
SET PROJECT=pyrogenesis
|
||||
mkdir vc2005
|
||||
|
||||
cd ..\premake
|
||||
|
||||
REM Minor hack to make sure the relative paths are correct:
|
||||
mkdir tmp
|
||||
copy premake.lua tmp
|
||||
cd tmp
|
||||
premake --target vs2002 --outpath ../workspaces/vc2002 %*
|
||||
premake --target vs2003 --outpath ../workspaces/vc2003 %*
|
||||
premake --target vs2005 --outpath ../workspaces/vc2005 %*
|
||||
|
||||
REM Just copy *.sln/etc indiscriminately, because it might include both pyrogenesis.sln and sced.sln (or might not)
|
||||
|
||||
..\premake --target vs6 %*
|
||||
move *.dsw ..\..\workspaces\vc6
|
||||
move *.dsp ..\..\workspaces\vc6
|
||||
|
||||
..\premake --target vs7 %*
|
||||
move *.sln ..\..\workspaces\vc7
|
||||
move *.vcproj ..\..\workspaces\vc7
|
||||
|
||||
..\premake --target vs2003 %*
|
||||
move *.sln ..\..\workspaces\vc2003
|
||||
move *.vcproj ..\..\workspaces\vc2003
|
||||
|
||||
cd ..\..\workspaces
|
||||
cd ..\workspaces
|
||||
|
@ -10,15 +10,8 @@ cd $premake_dir
|
||||
|
||||
# build/premake/
|
||||
|
||||
mkdir -p tmp
|
||||
cp premake.lua tmp
|
||||
cd tmp
|
||||
|
||||
# build/premake/tmp/
|
||||
../premake --target gnu
|
||||
|
||||
mkdir -p $workspace_dir
|
||||
mv -f Makefile pyrogenesis.make $workspace_dir
|
||||
./premake --target gnu --outpath $workspace_dir
|
||||
|
||||
# These files need to be linked; premake makefiles assume that the
|
||||
# lua file is accessible from the makefile directory
|
||||
|
Loading…
Reference in New Issue
Block a user