706 lines
18 KiB
C
Vendored
706 lines
18 KiB
C
Vendored
/**
|
|
* \file premake.c
|
|
* \brief Program entry point.
|
|
* \author Copyright (c) 2002-2017 Jason Perkins and the Premake project
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include "premake.h"
|
|
#include "lua_shimtable.h"
|
|
|
|
#if PLATFORM_MACOSX
|
|
#include <CoreFoundation/CFBundle.h>
|
|
#endif
|
|
|
|
#if PLATFORM_BSD
|
|
#include <sys/types.h>
|
|
#include <sys/sysctl.h>
|
|
#endif
|
|
|
|
#define ERROR_MESSAGE "Error: %s\n"
|
|
|
|
|
|
static void build_premake_path(lua_State* L);
|
|
static int process_arguments(lua_State* L, int argc, const char** argv);
|
|
static int run_premake_main(lua_State* L, const char* script);
|
|
|
|
|
|
/* A search path for script files */
|
|
const char* scripts_path = NULL;
|
|
|
|
|
|
/* Built-in functions */
|
|
static const luaL_Reg criteria_functions[] = {
|
|
{ "_compile", criteria_compile },
|
|
{ "_delete", criteria_delete },
|
|
{ "matches", criteria_matches },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg debug_functions[] = {
|
|
{ "prompt", debug_prompt },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg path_functions[] = {
|
|
{ "getabsolute", path_getabsolute },
|
|
{ "getrelative", path_getrelative },
|
|
{ "isabsolute", path_isabsolute },
|
|
{ "join", path_join },
|
|
{ "deferredjoin", path_deferred_join },
|
|
{ "hasdeferredjoin", path_has_deferred_join },
|
|
{ "resolvedeferredjoin", path_resolve_deferred_join },
|
|
{ "normalize", path_normalize },
|
|
{ "translate", path_translate },
|
|
{ "wildcards", path_wildcards },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg os_functions[] = {
|
|
{ "chdir", os_chdir },
|
|
{ "chmod", os_chmod },
|
|
{ "comparefiles", os_comparefiles },
|
|
{ "copyfile", os_copyfile },
|
|
{ "_is64bit", os_is64bit },
|
|
{ "isdir", os_isdir },
|
|
{ "getcwd", os_getcwd },
|
|
{ "getpass", os_getpass },
|
|
{ "getWindowsRegistry", os_getWindowsRegistry },
|
|
{ "listWindowsRegistry", os_listWindowsRegistry },
|
|
{ "getversion", os_getversion },
|
|
{ "host", os_host },
|
|
{ "isfile", os_isfile },
|
|
{ "islink", os_islink },
|
|
{ "locate", os_locate },
|
|
{ "matchdone", os_matchdone },
|
|
{ "matchisfile", os_matchisfile },
|
|
{ "matchname", os_matchname },
|
|
{ "matchnext", os_matchnext },
|
|
{ "matchstart", os_matchstart },
|
|
{ "mkdir", os_mkdir },
|
|
#if PLATFORM_WINDOWS
|
|
// utf8 functions for Windows (assuming posix already handle utf8)
|
|
{"remove", os_remove },
|
|
{"rename", os_rename },
|
|
#endif
|
|
{ "pathsearch", os_pathsearch },
|
|
{ "realpath", os_realpath },
|
|
{ "rmdir", os_rmdir },
|
|
{ "stat", os_stat },
|
|
{ "uuid", os_uuid },
|
|
{ "writefile_ifnotequal", os_writefile_ifnotequal },
|
|
{ "touchfile", os_touchfile },
|
|
{ "compile", os_compile },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg premake_functions[] = {
|
|
{ "getEmbeddedResource", premake_getEmbeddedResource },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg string_functions[] = {
|
|
{ "endswith", string_endswith },
|
|
{ "hash", string_hash },
|
|
{ "sha1", string_sha1 },
|
|
{ "startswith", string_startswith },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg buffered_functions[] = {
|
|
{ "new", buffered_new },
|
|
{ "write", buffered_write },
|
|
{ "writeln", buffered_writeln },
|
|
{ "tostring", buffered_tostring },
|
|
{ "close", buffered_close },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg term_functions[] = {
|
|
{ "getTextColor", term_getTextColor },
|
|
{ "setTextColor", term_setTextColor },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
#ifdef PREMAKE_CURL
|
|
static const luaL_Reg http_functions[] = {
|
|
{ "get", http_get },
|
|
{ "post", http_post },
|
|
{ "download", http_download },
|
|
{ NULL, NULL }
|
|
};
|
|
#endif
|
|
|
|
#ifdef PREMAKE_COMPRESSION
|
|
static const luaL_Reg zip_functions[] = {
|
|
{ "extract", zip_extract },
|
|
{ NULL, NULL }
|
|
};
|
|
#endif
|
|
|
|
|
|
static void lua_getorcreate_table(lua_State *L, const char *modname)
|
|
{
|
|
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); // get _LOADED table stack = {_LOADED}
|
|
lua_getfield(L, -1, modname); // get _LOADED[modname] stack = { _LOADED, result }
|
|
if (!lua_istable(L, -1)) // not found? stack = { _LOADED, result }
|
|
{
|
|
lua_pop(L, 1); // remove previous result stack = { _LOADED }
|
|
lua_pushglobaltable(L); // push _G onto stack stack = { _LOADED, _G }
|
|
lua_createtable(L, 0, 0); // new table for field stack = { _LOADED, _G, result }
|
|
lua_pushlstring(L, modname, strlen(modname)); // stack = { _LOADED, _G, result, modname }
|
|
lua_pushvalue(L, -2); // stack = { _LOADED, _G, result, modname, result }
|
|
lua_settable(L, -4); // _G[modname] = result stack = { _LOADED, _G, result }
|
|
lua_remove(L, -2); // remove _G from stack stack = { _LOADED, result }
|
|
lua_pushvalue(L, -1); // duplicate result stack = { _LOADED, result, result }
|
|
lua_setfield(L, -3, modname); // _LOADED[modname] = result stack = { _LOADED, result }
|
|
}
|
|
|
|
lua_remove(L, -2); // remove _LOADED from stack stack = { result }
|
|
}
|
|
|
|
|
|
void luaL_register(lua_State *L, const char *libname, const luaL_Reg *l)
|
|
{
|
|
lua_getorcreate_table(L, libname);
|
|
luaL_setfuncs(L, l, 0);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
|
|
/**
|
|
* Initialize the Premake Lua environment.
|
|
*/
|
|
int premake_init(lua_State* L)
|
|
{
|
|
const char* value;
|
|
|
|
luaL_register(L, "premake", premake_functions);
|
|
luaL_register(L, "criteria", criteria_functions);
|
|
luaL_register(L, "debug", debug_functions);
|
|
luaL_register(L, "path", path_functions);
|
|
luaL_register(L, "os", os_functions);
|
|
luaL_register(L, "string", string_functions);
|
|
luaL_register(L, "buffered", buffered_functions);
|
|
luaL_register(L, "term", term_functions);
|
|
|
|
#ifdef PREMAKE_CURL
|
|
luaL_register(L, "http", http_functions);
|
|
#endif
|
|
|
|
#ifdef PREMAKE_COMPRESSION
|
|
luaL_register(L, "zip", zip_functions);
|
|
#endif
|
|
|
|
lua_pushlightuserdata(L, &s_shimTable);
|
|
lua_rawseti(L, LUA_REGISTRYINDEX, 0x5348494D); // equal to 'SHIM'
|
|
|
|
/* push the application metadata */
|
|
lua_pushstring(L, LUA_COPYRIGHT);
|
|
lua_setglobal(L, "_COPYRIGHT");
|
|
|
|
lua_pushstring(L, PREMAKE_VERSION);
|
|
lua_setglobal(L, "_PREMAKE_VERSION");
|
|
|
|
lua_pushstring(L, PREMAKE_COPYRIGHT);
|
|
lua_setglobal(L, "_PREMAKE_COPYRIGHT");
|
|
|
|
lua_pushstring(L, PREMAKE_PROJECT_URL);
|
|
lua_setglobal(L, "_PREMAKE_URL");
|
|
|
|
/* set the OS platform variable */
|
|
lua_pushstring(L, PLATFORM_STRING);
|
|
lua_setglobal(L, "_TARGET_OS");
|
|
|
|
/* find the user's home directory */
|
|
value = getenv("HOME");
|
|
if (!value) value = getenv("USERPROFILE");
|
|
if (!value) value = "~";
|
|
lua_pushstring(L, value);
|
|
lua_setglobal(L, "_USER_HOME_DIR");
|
|
|
|
/* publish the initial working directory */
|
|
os_getcwd(L);
|
|
lua_setglobal(L, "_WORKING_DIR");
|
|
|
|
#if !defined(PREMAKE_NO_BUILTIN_SCRIPTS)
|
|
/* let native modules initialize themselves */
|
|
registerModules(L);
|
|
#endif
|
|
|
|
return OKAY;
|
|
}
|
|
|
|
|
|
static void setErrorColor(lua_State* L)
|
|
{
|
|
int errorColor = 12;
|
|
|
|
lua_getglobal(L, "term");
|
|
lua_pushstring(L, "errorColor");
|
|
lua_gettable(L, -2);
|
|
|
|
if (!lua_isnil(L, -1))
|
|
errorColor = (int)luaL_checkinteger(L, -1);
|
|
|
|
term_doSetTextColor(errorColor);
|
|
|
|
lua_pop(L, 2);
|
|
}
|
|
|
|
|
|
|
|
void printLastError(lua_State* L)
|
|
{
|
|
const char* message = lua_tostring(L, -1);
|
|
int oldColor = term_doGetTextColor();
|
|
setErrorColor(L);
|
|
printf(ERROR_MESSAGE, message);
|
|
term_doSetTextColor(oldColor);
|
|
}
|
|
|
|
static int lua_error_handler(lua_State* L)
|
|
{
|
|
// in debug mode, show full traceback on all errors
|
|
#if !defined(NDEBUG)
|
|
lua_getglobal(L, "debug");
|
|
lua_getfield(L, -1, "traceback");
|
|
lua_remove(L, -2); // remove debug table
|
|
lua_insert(L, -2); // insert traceback function before error message
|
|
lua_pushinteger(L, 3); // push level
|
|
lua_call(L, 2, 1); // call traceback
|
|
#else
|
|
(void) L;
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
int premake_pcall(lua_State* L, int nargs, int nresults)
|
|
{
|
|
lua_pushcfunction(L, lua_error_handler);
|
|
|
|
int error_handler_index = lua_gettop(L) - nargs - 1;
|
|
lua_insert(L, error_handler_index); // insert lua_error_handler before call parameters
|
|
int result = lua_pcall(L, nargs, nresults, error_handler_index);
|
|
lua_remove(L, error_handler_index); // remove lua_error_handler from stack
|
|
return result;
|
|
}
|
|
|
|
int premake_execute(lua_State* L, int argc, const char** argv, const char* script)
|
|
{
|
|
/* push the absolute path to the Premake executable */
|
|
lua_pushcfunction(L, path_getabsolute);
|
|
premake_locate_executable(L, argv[0]);
|
|
lua_call(L, 1, 1);
|
|
lua_setglobal(L, "_PREMAKE_COMMAND");
|
|
|
|
/* Parse the command line arguments */
|
|
if (process_arguments(L, argc, argv) != OKAY) {
|
|
return !OKAY;
|
|
}
|
|
|
|
/* Use --scripts and PREMAKE_PATH to populate premake.path */
|
|
build_premake_path(L);
|
|
|
|
/* Find and run the main Premake bootstrapping script */
|
|
if (run_premake_main(L, script) != OKAY) {
|
|
printLastError(L);
|
|
return !OKAY;
|
|
}
|
|
|
|
/* and call the main entry point */
|
|
lua_getglobal(L, "_premake_main");
|
|
if (premake_pcall(L, 0, 1) != OKAY) {
|
|
printLastError(L);
|
|
return !OKAY;
|
|
}
|
|
else {
|
|
int exitCode = (int)lua_tonumber(L, -1);
|
|
return exitCode;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Locate the Premake executable, and push its full path to the Lua stack.
|
|
* Based on:
|
|
* http://sourceforge.net/tracker/index.php?func=detail&aid=3351583&group_id=71616&atid=531880
|
|
* http://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c
|
|
* http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
|
|
*/
|
|
int premake_locate_executable(lua_State* L, const char* argv0)
|
|
{
|
|
char buffer[PATH_MAX];
|
|
const char* path = NULL;
|
|
|
|
#if PLATFORM_WINDOWS
|
|
wchar_t widebuffer[PATH_MAX];
|
|
|
|
DWORD len = GetModuleFileNameW(NULL, widebuffer, PATH_MAX);
|
|
if (len > 0)
|
|
{
|
|
WideCharToMultiByte(CP_UTF8, 0, widebuffer, len, buffer, PATH_MAX, NULL, NULL);
|
|
|
|
buffer[len] = 0;
|
|
path = buffer;
|
|
}
|
|
#endif
|
|
|
|
#if PLATFORM_MACOSX
|
|
CFURLRef bundleURL = CFBundleCopyExecutableURL(CFBundleGetMainBundle());
|
|
CFStringRef pathRef = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
|
|
if (CFStringGetCString(pathRef, buffer, PATH_MAX - 1, kCFStringEncodingUTF8))
|
|
path = buffer;
|
|
#endif
|
|
|
|
#if PLATFORM_LINUX
|
|
int len = readlink("/proc/self/exe", buffer, PATH_MAX - 1);
|
|
if (len > 0)
|
|
{
|
|
buffer[len] = 0;
|
|
path = buffer;
|
|
}
|
|
#endif
|
|
|
|
#if PLATFORM_BSD && !defined(__OpenBSD__)
|
|
int len = readlink("/proc/curproc/file", buffer, PATH_MAX - 1);
|
|
if (len < 0)
|
|
len = readlink("/proc/curproc/exe", buffer, PATH_MAX - 1);
|
|
if (len < 0)
|
|
{
|
|
int mib[4];
|
|
mib[0] = CTL_KERN;
|
|
mib[1] = KERN_PROC;
|
|
mib[2] = KERN_PROC_PATHNAME;
|
|
mib[3] = -1;
|
|
size_t cb = sizeof(buffer);
|
|
sysctl(mib, 4, buffer, &cb, NULL, 0);
|
|
len = (int)cb;
|
|
}
|
|
if (len > 0)
|
|
{
|
|
buffer[len] = 0;
|
|
path = buffer;
|
|
}
|
|
#endif
|
|
|
|
#if PLATFORM_SOLARIS
|
|
int len = readlink("/proc/self/path/a.out", buffer, PATH_MAX - 1);
|
|
if (len > 0)
|
|
{
|
|
buffer[len] = 0;
|
|
path = buffer;
|
|
}
|
|
#endif
|
|
|
|
/* As a fallback, search the PATH with argv[0] */
|
|
if (!path)
|
|
{
|
|
lua_pushcfunction(L, os_pathsearch);
|
|
lua_pushstring(L, argv0);
|
|
lua_pushstring(L, getenv("PATH"));
|
|
if (lua_pcall(L, 2, 1, 0) == OKAY && !lua_isnil(L, -1))
|
|
{
|
|
lua_pushstring(L, "/");
|
|
lua_pushstring(L, argv0);
|
|
lua_concat(L, 3);
|
|
path = lua_tostring(L, -1);
|
|
}
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
/* If all else fails, use argv[0] as-is and hope for the best */
|
|
if (!path)
|
|
{
|
|
/* make it absolute, if needed */
|
|
os_getcwd(L);
|
|
lua_pushstring(L, "/");
|
|
lua_pushstring(L, argv0);
|
|
|
|
if (!do_isabsolute(argv0)) {
|
|
lua_concat(L, 3);
|
|
}
|
|
else {
|
|
lua_pop(L, 3);
|
|
lua_pushstring(L, argv0);
|
|
}
|
|
|
|
path = lua_tostring(L, -1);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
lua_pushstring(L, path);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Checks one or more of the standard script search locations to locate the
|
|
* specified file. If found, returns the discovered path to the script on
|
|
* the top of the Lua stack.
|
|
*/
|
|
int premake_test_file(lua_State* L, const char* filename, int searchMask)
|
|
{
|
|
if (searchMask & TEST_LOCAL) {
|
|
if (do_isfile(L, filename)) {
|
|
lua_pushcfunction(L, path_getabsolute);
|
|
lua_pushstring(L, filename);
|
|
lua_call(L, 1, 1);
|
|
return OKAY;
|
|
}
|
|
}
|
|
|
|
if (scripts_path && (searchMask & TEST_SCRIPTS)) {
|
|
if (do_locate(L, filename, scripts_path)) return OKAY;
|
|
}
|
|
|
|
if (searchMask & TEST_PATH) {
|
|
const char* path = getenv("PREMAKE_PATH");
|
|
if (path && do_locate(L, filename, path)) return OKAY;
|
|
}
|
|
|
|
#if !defined(PREMAKE_NO_BUILTIN_SCRIPTS)
|
|
if ((searchMask & TEST_EMBEDDED) != 0) {
|
|
/* Try to locate a record matching the filename */
|
|
if (premake_find_embedded_script(filename) != NULL) {
|
|
lua_pushstring(L, "$/");
|
|
lua_pushstring(L, filename);
|
|
lua_concat(L, 2);
|
|
return OKAY;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return !OKAY;
|
|
}
|
|
|
|
|
|
|
|
static const char* set_scripts_path(const char* relativePath)
|
|
{
|
|
char* path = (char*)malloc(PATH_MAX);
|
|
do_getabsolute(path, relativePath, NULL);
|
|
scripts_path = path;
|
|
return scripts_path;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Set the premake.path variable, pulling from the --scripts argument
|
|
* and PREMAKE_PATH environment variable if present.
|
|
*/
|
|
static void build_premake_path(lua_State* L)
|
|
{
|
|
int top;
|
|
const char* value;
|
|
|
|
lua_getglobal(L, "premake");
|
|
top = lua_gettop(L);
|
|
|
|
/* Start by searching the current working directory */
|
|
lua_pushstring(L, ".");
|
|
|
|
/* The --scripts argument goes next, if present */
|
|
if (scripts_path) {
|
|
lua_pushstring(L, ";");
|
|
lua_pushstring(L, scripts_path);
|
|
}
|
|
|
|
/* Then the PREMAKE_PATH environment variable */
|
|
value = getenv("PREMAKE_PATH");
|
|
if (value) {
|
|
lua_pushstring(L, ";");
|
|
lua_pushstring(L, value);
|
|
}
|
|
|
|
/* Then in ~/.premake */
|
|
lua_pushstring(L, ";");
|
|
lua_getglobal(L, "_USER_HOME_DIR");
|
|
lua_pushstring(L, "/.premake");
|
|
|
|
/* In the user's Application Support folder */
|
|
#if defined(PLATFORM_MACOSX)
|
|
lua_pushstring(L, ";");
|
|
lua_getglobal(L, "_USER_HOME_DIR");
|
|
lua_pushstring(L, "/Library/Application Support/Premake");
|
|
#endif
|
|
|
|
/* In the /usr tree */
|
|
lua_pushstring(L, ";/usr/local/share/premake;/usr/share/premake");
|
|
|
|
/* Put it all together */
|
|
lua_concat(L, lua_gettop(L) - top);
|
|
|
|
/* Match Lua's package.path; use semicolon separators */
|
|
#if !defined(PLATFORM_WINDOWS)
|
|
lua_getglobal(L, "string");
|
|
lua_getfield(L, -1, "gsub");
|
|
lua_pushvalue(L, -3);
|
|
lua_pushstring(L, ":");
|
|
lua_pushstring(L, ";");
|
|
lua_call(L, 3, 1);
|
|
/* remove the string global table */
|
|
lua_remove(L, -2);
|
|
/* remove the previously concatonated result */
|
|
lua_remove(L, -2);
|
|
#endif
|
|
|
|
/* Store it in premake.path */
|
|
lua_setfield(L, -2, "path");
|
|
|
|
/* Remove the premake namespace table */
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Copy all command line arguments into the script-side _ARGV global, and
|
|
* check for the presence of a /scripts=<path> argument to help locate
|
|
* the manifest if needed.
|
|
* \returns OKAY if successful.
|
|
*/
|
|
static int process_arguments(lua_State* L, int argc, const char** argv)
|
|
{
|
|
int i;
|
|
|
|
/* Copy all arguments in the _ARGV global */
|
|
lua_newtable(L);
|
|
for (i = 1; i < argc; ++i)
|
|
{
|
|
lua_pushstring(L, argv[i]);
|
|
lua_rawseti(L, -2, luaL_len(L, -2) + 1);
|
|
|
|
/* The /scripts option gets picked up here; used later to find the
|
|
* manifest and scripts later if necessary */
|
|
if (strncmp(argv[i], "/scripts=", 9) == 0)
|
|
{
|
|
argv[i] = set_scripts_path(argv[i] + 9);
|
|
}
|
|
else if (strncmp(argv[i], "--scripts=", 10) == 0)
|
|
{
|
|
argv[i] = set_scripts_path(argv[i] + 10);
|
|
}
|
|
}
|
|
lua_setglobal(L, "_ARGV");
|
|
|
|
return OKAY;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Find and run the main Premake bootstrapping script. The loading of the
|
|
* bootstrap and the other core scripts use a limited set of search paths
|
|
* to avoid mismatches between the native host code and the scripts
|
|
* themselves.
|
|
*/
|
|
static int run_premake_main(lua_State* L, const char* script)
|
|
{
|
|
/* Release builds want to load the embedded scripts, with --scripts
|
|
* argument allowed as an override. Debug builds will look at the
|
|
* local file system first, then fall back to embedded. */
|
|
#if defined(NDEBUG)
|
|
int z = premake_test_file(L, script,
|
|
TEST_SCRIPTS | TEST_EMBEDDED);
|
|
#else
|
|
int z = premake_test_file(L, script,
|
|
TEST_LOCAL | TEST_SCRIPTS | TEST_PATH | TEST_EMBEDDED);
|
|
#endif
|
|
|
|
/* If no embedded script can be found, release builds will then
|
|
* try to fall back to the local file system, just in case */
|
|
#if defined(NDEBUG)
|
|
if (z != OKAY) {
|
|
z = premake_test_file(L, script, TEST_LOCAL | TEST_PATH);
|
|
}
|
|
#endif
|
|
|
|
if (z == OKAY) {
|
|
const char* filename = lua_tostring(L, -1);
|
|
z = luaL_dofile(L, filename);
|
|
}
|
|
|
|
return z;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Locate a file in the embedded script index. If found, returns the
|
|
* contents of the file's script.
|
|
*/
|
|
|
|
const buildin_mapping* premake_find_embedded_script(const char* filename)
|
|
{
|
|
#if !defined(PREMAKE_NO_BUILTIN_SCRIPTS)
|
|
int i;
|
|
for (i = 0; builtin_scripts[i].name != NULL; ++i) {
|
|
if (strcmp(builtin_scripts[i].name, filename) == 0) {
|
|
return builtin_scripts + i;
|
|
}
|
|
}
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Load a script that was previously embedded into the executable. If
|
|
* successful, a function containing the new script chunk is pushed to
|
|
* the stack, just like luaL_loadfile would do had the chunk been loaded
|
|
* from a file.
|
|
*/
|
|
|
|
int premake_load_embedded_script(lua_State* L, const char* filename)
|
|
{
|
|
#if !defined(NDEBUG)
|
|
static int warned = 0;
|
|
#endif
|
|
|
|
const buildin_mapping* chunk = premake_find_embedded_script(filename);
|
|
if (chunk == NULL) {
|
|
return LUA_ERRFILE;
|
|
}
|
|
|
|
/* Debug builds probably want to be loading scripts from the disk */
|
|
#if !defined(NDEBUG)
|
|
if (!warned) {
|
|
warned = 1;
|
|
printf("** warning: using embedded script '%s'; use /scripts argument to load from files\n", filename);
|
|
}
|
|
#endif
|
|
|
|
/* "Fully qualify" the filename by turning it into the form $/filename */
|
|
lua_pushstring(L, "$/");
|
|
lua_pushstring(L, filename);
|
|
lua_concat(L, 2);
|
|
|
|
/* Load the chunk */
|
|
return luaL_loadbuffer(L, (const char*)chunk->bytecode, chunk->length, filename);
|
|
}
|
|
|
|
|
|
/**
|
|
* Give the lua runtime raw access to embedded files.
|
|
*/
|
|
int premake_getEmbeddedResource(lua_State* L)
|
|
{
|
|
const char* filename = luaL_checkstring(L, 1);
|
|
const buildin_mapping* chunk = premake_find_embedded_script(filename);
|
|
if (chunk == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
lua_pushlstring(L, (const char*)chunk->bytecode, chunk->length);
|
|
return 1;
|
|
}
|