#include "lua_dependency_tree.h" #include "lua_platform.h" #include "lua_filesystem.h" #include #include // From lua static int msghandler(lua_State* L) { if (!lua_isstring(L, 1)) /* 'message' not a string? */ return 1; /* keep it intact */ lua_getfield(L, LUA_GLOBALSINDEX, "debug"); if (!lua_istable(L, -1)) { lua_pop(L, 1); return 1; } lua_getfield(L, -1, "traceback"); if (!lua_isfunction(L, -1)) { lua_pop(L, 2); return 1; } lua_pushvalue(L, 1); /* pass error message */ lua_pushinteger(L, 2); /* skip this function and traceback */ lua_call(L, 2, 1); /* call debug.traceback */ return 1; } int main(int argc, char** argv) { const char* exec_file = "lbs.lua"; int argstart = 1; if (argc > 2 && ( strcmp(argv[1], "--buildscript") == 0 || strcmp(argv[1], "-s") == 0)) { exec_file = argv[2]; argstart += 2; } if (!std::filesystem::exists(exec_file)) { fprintf(stderr, "Failed to find buildscript %s to execute\n", exec_file); return EXIT_FAILURE; } lua_State* L = luaL_newstate(); luaL_openlibs(L); luaopen_dependency_tree(L); luaopen_platform(L); luaopen_filesystem(L); luaL_loadfile(L, exec_file); for (int i = (argstart+1); i < argc; ++i) lua_pushstring(L, argv[i]); int err = LUA_OK; int msg_base = lua_gettop(L) - argc - argstart - 1; lua_pushcfunction(L, msghandler); lua_insert(L, msg_base); if ( (err = lua_pcall(L, argc - argstart - 1, LUA_MULTRET, msg_base)) != LUA_OK) { if (err == LUA_ERRRUN) fprintf(stderr, "A runtime error when running the script %s has occured\n%s\n", exec_file, lua_tostring(L, -1)); else if (err == LUA_ERRMEM) fprintf(stderr, "A memory allocation error when running the script %s has occured\n%s\n", exec_file, lua_tostring(L, -1)); else if (err == LUA_ERRERR) fprintf(stderr, "A error handling function has errored when running the script %s\n%s\n", exec_file, lua_tostring(L, -1)); else fprintf(stderr, "An unknown error has occured when running the script %s\n%s\n", exec_file, lua_tostring(L, -1)); lua_close(L); return EXIT_FAILURE; } lua_remove(L, msg_base); const char* lbs_cmd = argv[argstart]; if (argstart >= argc) lbs_cmd = "main"; lua_getglobal(L, lbs_cmd); if (lua_isnil(L, -1)) { fprintf(stderr, "Failed to find command %s in buildscript %s to execute\n", lbs_cmd, exec_file); lua_close(L); return EXIT_FAILURE; } for (int i = (argstart + 1); i < argc; ++i) lua_pushstring(L, argv[i]); msg_base = lua_gettop(L) - argc - argstart - 1; lua_pushcfunction(L, msghandler); lua_insert(L, msg_base); if ( (err = lua_pcall(L, argc - argstart - 1, LUA_MULTRET, msg_base)) != LUA_OK) { if (err == LUA_ERRRUN) fprintf(stderr, "A runtime error when running the command %s in the script %s has occured\n%s\n", lbs_cmd, exec_file, lua_tostring(L, -1)); else if (err == LUA_ERRMEM) fprintf(stderr, "A memory allocation error when running the command %s in the script %s has occured\n%s\n", lbs_cmd, exec_file, lua_tostring(L, -1)); else if (err == LUA_ERRERR) fprintf(stderr, "A error handling function has errored when running the command %s in the script %s\n%s\n", lbs_cmd, exec_file, lua_tostring(L, -1)); else fprintf(stderr, "An unknown error has occured when running the command %s in the script %s\n%s\n", lbs_cmd, exec_file, lua_tostring(L, -1)); lua_close(L); return EXIT_FAILURE; } lua_remove(L, msg_base); // If a return value was provided, return it if (lua_isnumber(L, -1)) { int rc = lua_tointeger(L, -1); lua_close(L); return rc; } // Otherwise return success lua_close(L); return EXIT_SUCCESS; }