Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/premake-4.x-stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/premake.c')
-rw-r--r--src/host/premake.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/src/host/premake.c b/src/host/premake.c
new file mode 100644
index 0000000..cecca20
--- /dev/null
+++ b/src/host/premake.c
@@ -0,0 +1,265 @@
+/**
+ * \file premake.c
+ * \brief Program entry point.
+ * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "premake.h"
+
+
+#define VERSION "SVN"
+#define COPYRIGHT "Copyright (C) 2002-2008 Jason Perkins and the Premake Project"
+#define ERROR_MESSAGE "%s\n"
+
+
+static int process_arguments(lua_State* L, int argc, const char** argv);
+static int process_option(lua_State* L, const char* arg);
+static int load_builtin_scripts(lua_State* L);
+
+
+/* A search path for script files */
+static const char* scripts_path = NULL;
+
+
+/* precompiled bytecode buffer; in bytecode.c */
+extern const char* builtin_bytecode[];
+extern int builtin_sizes[];
+
+
+/* Built-in functions */
+static const luaL_Reg os_functions[] = {
+ { "chdir", os_chdir },
+ { "isdir", os_isdir },
+ { "getcwd", os_getcwd },
+ { "isfile", os_isfile },
+ { "matchdone", os_matchdone },
+ { "matchisfile", os_matchisfile },
+ { "matchname", os_matchname },
+ { "matchnext", os_matchnext },
+ { "matchstart", os_matchstart },
+ { "mkdir", os_mkdir },
+ { "pathsearch", os_pathsearch },
+ { "rmdir", os_rmdir },
+ { NULL, NULL }
+};
+
+
+
+/**
+ * Program entry point.
+ */
+int main(int argc, const char** argv)
+{
+ lua_State* L;
+ int z = OKAY;
+
+ /* prepare Lua for use */
+ L = lua_open();
+ luaL_openlibs(L);
+ luaL_register(L, "os", os_functions);
+
+ /* push the application metadata */
+ lua_pushstring(L, LUA_COPYRIGHT);
+ lua_setglobal(L, "_COPYRIGHT");
+
+ lua_pushstring(L, VERSION);
+ lua_setglobal(L, "_PREMAKE_VERSION");
+
+ lua_pushstring(L, COPYRIGHT);
+ lua_setglobal(L, "_PREMAKE_COPYRIGHT");
+
+ /* set the OS platform variable */
+ lua_pushstring(L, PLATFORM_STRING);
+ lua_setglobal(L, "_OS");
+
+ /* Parse the command line arguments */
+ if (z == OKAY) z = process_arguments(L, argc, argv);
+
+ /* Run the built-in Premake scripts */
+ if (z == OKAY) z = load_builtin_scripts(L);
+
+ /* Clean up and turn off the lights */
+ lua_close(L);
+ return z;
+}
+
+
+
+/**
+ * Process the command line arguments, splitting them into options, the
+ * target action, and any arguments to that action. The results are pushed
+ * into the session for later use. I could have done this in the scripts,
+ * but I need the value of the /scripts option to find them.
+ * \returns OKAY if successful.
+ */
+int process_arguments(lua_State* L, int argc, const char** argv)
+{
+ int i;
+
+ /* Create empty lists for Options and Args */
+ lua_newtable(L);
+ lua_newtable(L);
+
+ for (i = 1; i < argc; ++i)
+ {
+ /* Options start with '/' or '--'. The first argument that isn't an option
+ * is the action. Anything after that is an argument to the action */
+ if (argv[i][0] == '/')
+ {
+ process_option(L, argv[i] + 1);
+ }
+ else if (argv[i][0] == '-' && argv[i][1] == '-')
+ {
+ process_option(L, argv[i] + 2);
+ }
+ else
+ {
+ /* not an option, is the action */
+ lua_pushstring(L, argv[i++]);
+ lua_setglobal(L, "_ACTION");
+
+ /* everything else is an argument */
+ while (i < argc)
+ {
+ lua_pushstring(L, argv[i++]);
+ lua_rawseti(L, -2, luaL_getn(L, -2) + 1);
+ }
+ }
+ }
+
+ /* push the Options and Args lists */
+ lua_setglobal(L, "_ARGS");
+ lua_setglobal(L, "_OPTIONS");
+ return OKAY;
+}
+
+
+
+/**
+ * Parse an individual command-line option.
+ * \returns OKAY if successful.
+ */
+int process_option(lua_State* L, const char* arg)
+{
+ char key[512];
+ const char* value;
+
+ /* If a value is specified, split the option into a key/value pair */
+ char* ptr = strchr(arg, '=');
+ if (ptr)
+ {
+ int len = ptr - arg;
+ if (len > 511) len = 511;
+ strncpy(key, arg, len);
+ key[len] = '\0';
+ value = ptr + 1;
+ }
+ else
+ {
+ strcpy(key, arg);
+ value = "";
+ }
+
+ /* Store it in the Options table, which is already on the stack */
+ lua_pushstring(L, value);
+ lua_setfield(L, -3, key);
+
+ /* The /scripts option gets picked up here to find the built-in scripts */
+ if (strcmp(key, "scripts") == 0 && strlen(value) > 0)
+ {
+ scripts_path = value;
+ }
+
+ return OKAY;
+}
+
+
+
+#if defined(_DEBUG)
+/**
+ * When running in debug mode, the scripts are loaded from the disk. The path to
+ * the scripts must be provided via either the /scripts command line option or
+ * the PREMAKE_PATH environment variable.
+ */
+int load_builtin_scripts(lua_State* L)
+{
+ const char* filename;
+
+ /* call os.pathsearch() to locate _premake_main.lua */
+ lua_pushcfunction(L, os_pathsearch);
+ lua_pushstring(L, "_premake_main.lua");
+ lua_pushstring(L, scripts_path);
+ lua_pushstring(L, getenv("PREMAKE_PATH"));
+ lua_call(L, 3, 1);
+
+ if (lua_isnil(L, -1))
+ {
+ printf(ERROR_MESSAGE,
+ "Unable to find _premake_main.lua; use /scripts option when in debug mode!\n"
+ "Please refer to the documentation (or build in release mode instead)."
+ );
+ return !OKAY;
+ }
+
+ /* run the bootstrapping script */
+ scripts_path = lua_tostring(L, -1);
+ filename = lua_pushfstring(L, "%s/_premake_main.lua", scripts_path);
+ if (luaL_dofile(L, filename))
+ {
+ printf(ERROR_MESSAGE, lua_tostring(L, -1));
+ return !OKAY;
+ }
+
+ /* hand off control to the scripts */
+ lua_getglobal(L, "_premake_main");
+ lua_pushstring(L, scripts_path);
+ if (lua_pcall(L, 1, 1, 0) != OKAY)
+ {
+ printf(ERROR_MESSAGE, lua_tostring(L, -1));
+ return !OKAY;
+ }
+ else
+ {
+ return (int)lua_tonumber(L, -1);
+ }
+}
+#endif
+
+
+#if defined(NDEBUG)
+/**
+ * When running in release mode, the scripts are loaded from a static data
+ * buffer, where they were stored as bytecode by a preprocess. To regenerate
+ * the bytecodes, run `premake --compile` and then rebuild.
+ */
+int load_builtin_scripts(lua_State* L)
+{
+ int i;
+ for (i = 0; builtin_sizes[i] > 0; ++i)
+ {
+ /* use loadstring() to put the bytecodes on the stack */
+ lua_getglobal(L, "loadstring");
+ lua_pushlstring(L, builtin_bytecode[i], builtin_sizes[i]);
+
+ /* evaluate the chunk */
+ lua_pcall(L, 1, 1, 0);
+ if (lua_pcall(L, 0, 0, 0) != OKAY)
+ {
+ printf(ERROR_MESSAGE, lua_tostring(L,-1));
+ return !OKAY;
+ }
+ }
+
+ /* hand off control to the scripts */
+ lua_getglobal(L, "_premake_main");
+ if (lua_pcall(L, 0, 1, 0) != OKAY)
+ {
+ printf(ERROR_MESSAGE, lua_tostring(L,-1));
+ return !OKAY;
+ }
+
+ return OKAY;
+}
+#endif