// Copyright (c) 2013, Thomas Goyne // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /// @file auto4_lua_scriptreader.cpp /// @brief Script-file reader for Lua 5.1-based scripting engine /// @ingroup scripting /// #include "auto4_lua_scriptreader.h" #include "auto4_lua_utils.h" #include #include namespace Automation4 { bool LoadFile(lua_State *L, agi::fs::path const& raw_filename) { auto filename = raw_filename; try { filename = agi::fs::Canonicalize(raw_filename); } catch (agi::fs::FileSystemUnknownError const& e) { LOG_E("auto4/lua") << "Error canonicalizing path: " << e.GetChainedMessage(); } agi::read_file_mapping file(filename); auto buff = file.read(); size_t size = file.size(); // Discard the BOM if present if (size >= 3 && buff[0] == -17 && buff[1] == -69 && buff[2] == -65) { buff += 3; size -= 3; } if (!agi::fs::HasExtension(filename, "moon")) return luaL_loadbuffer(L, buff, size, filename.string().c_str()) == 0; // Save the text we'll be loading for the line number rewriting in the // error handling push_value(L, buff); lua_setfield(L, LUA_REGISTRYINDEX, ("raw moonscript: " + filename.string()).c_str()); // We have a MoonScript file, so we need to load it with that // It might be nice to have a dedicated lua state for compiling // MoonScript to Lua if (luaL_dostring(L, "return require('moonscript').loadstring")) return false; // Leaves error message on stack lua_pushlstring(L, buff, size); lua_pushstring(L, filename.string().c_str()); if (lua_pcall(L, 2, 2, 0)) return false; // Leaves error message on stack // loadstring returns nil, error on error or a function on success if (lua_isnil(L, 1)) { lua_remove(L, 1); return false; } lua_pop(L, 1); // Remove the extra nil for the stackchecker return true; } }