// Author: Marek K. /* 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 3 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, see . */ #define CONFIG_FILE "config.lua" #define CONFIG_VALUE ""\ "menu = {\"Test\", \"License\", \"Exit\"}\n"\ "menu_items = 3\n"\ "\n"\ "input_text = \"\\nOption: \"\n"\ "\n"\ "license = [==[\n"\ "\n"\ "This program is free software: you can redistribute it and/or modify\n"\ "it under the terms of the GNU General Public License as published by\n"\ "the Free Software Foundation, either version 3 of the License, or\n"\ "(at your option) any later version.\n"\ "\n"\ "This program is distributed in the hope that it will be useful,\n"\ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"\ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"\ "GNU General Public License for more details.\n"\ "\n"\ "You should have received a copy of the GNU General Public License\n"\ "along with this program. If not, see .]==]\n"\ "\n"\ "function Test()\n"\ " if isHere() == 0.0 and TestMemory() then\n"\ " return false\n"\ " else\n"\ " return true\n"\ " end\n"\ "end\n"\ "\n"\ "success_text = \"\\nStatus: Success :-)\"\n"\ "failure_text = \"\\nStatus: Failed :-(\"\n"\ #include #include #include #include #include #include #include // include lua.h lualib.h luaxlib.h #include // Lua functions int isHere(lua_State * Lua) noexcept { lua_pushnumber(Lua, system(NULL)); return 1; } int TestMemory(lua_State * Lua) noexcept { char * ptr = (char *) malloc(sizeof(char)); if(ptr == NULL) lua_pushboolean(Lua, 0); else lua_pushboolean(Lua, 1); free(ptr); return 1; } // Functions void Test(lua_State * Lua) { lua_getglobal(Lua, "Test"); if(lua_pcall(Lua, 0, 1, 0)) throw std::runtime_error("Can not call function Test!"); if(! lua_isboolean(Lua, -1)) throw std::runtime_error("Return value is not a boolean!"); if(lua_toboolean(Lua, -1)) lua_getglobal(Lua, "success_text"); else lua_getglobal(Lua, "failure_text"); if(! lua_isstring(Lua, -1)) throw std::runtime_error("success_text or failure_text are not strings!"); std::cout << lua_tostring(Lua, -1) << std::endl; } void License(lua_State * Lua) { lua_getglobal(Lua, "license"); if(! lua_isstring(Lua, -1)) throw std::runtime_error("license is not a string!"); std::cout << lua_tostring(Lua, -1) << std::endl; } int main() { try { lua_State * Lua = luaL_newstate(); if(Lua == nullptr || Lua == NULL) throw std::runtime_error("Can not open Lua state!"); luaL_openlibs(Lua); lua_pushcfunction(Lua, isHere); lua_setglobal(Lua, "isHere"); lua_pushcfunction(Lua, TestMemory); lua_setglobal(Lua, "TestMemory"); std::ifstream check_file(CONFIG_FILE); if(! check_file) { std::ofstream fil(CONFIG_FILE); if(! fil.good()) throw std::runtime_error("Can not write to file " CONFIG_FILE "!"); fil << CONFIG_VALUE; fil.close(); } check_file.close(); if(luaL_dofile(Lua, CONFIG_FILE)) throw std::runtime_error("Can not read " CONFIG_FILE "!"); lua_getglobal(Lua, "menu_items"); if(! lua_isnumber(Lua, -1)) throw std::runtime_error("menu_itens is not a number!"); size_t menu_items = (size_t) lua_tonumber(Lua, -1); lua_getglobal(Lua, "menu"); if(! lua_istable(Lua, -1)) throw std::runtime_error("menu is not a table!"); for(size_t i = 0; i < menu_items; i++) { lua_rawgeti(Lua, -1, i + 1); if(! lua_isstring(Lua, -1)) throw std::runtime_error("menu value is not a string!"); std::cout << i + 1 << " - " << lua_tostring(Lua, -1) << std::endl; lua_pop(Lua, 1); } lua_getglobal(Lua, "input_text"); if(! lua_isstring(Lua, -1)) throw std::runtime_error("input_text is not a string"); std::cout << lua_tostring(Lua, -1); lua_settop(Lua, 0); unsigned short option; std::cin >> option; if(std::cin.fail() || option == 0 || option > 3) throw std::runtime_error("Invalid input!"); switch(option) { case 1: Test(Lua); break; case 2: License(Lua); break; case 3: exit(EXIT_SUCCESS); } lua_settop(Lua, 0); } catch(std::exception & e) { std::cerr << "Error: " << e.what() << std::endl; exit(EXIT_FAILURE); } return EXIT_SUCCESS; }