From 510ee7dfff87dea0f583f6cb52b42d399be80fdc Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 15 Mar 2012 20:48:27 +0000 Subject: [PATCH] - bugfixes for loading XML and not dropping newlines - started work on trying to save lua state (global variables only) --- .../glest_game/menu/menu_state_scenario.cpp | 14 ++- source/shared_lib/include/lua/lua_script.h | 2 + source/shared_lib/sources/lua/lua_script.cpp | 105 +++++++++++++++++- source/shared_lib/sources/xml/xml_parser.cpp | 21 ++-- 4 files changed, 131 insertions(+), 11 deletions(-) diff --git a/source/glest_game/menu/menu_state_scenario.cpp b/source/glest_game/menu/menu_state_scenario.cpp index a42fb87ec..07c5c76f4 100644 --- a/source/glest_game/menu/menu_state_scenario.cpp +++ b/source/glest_game/menu/menu_state_scenario.cpp @@ -42,6 +42,18 @@ MenuStateScenario::MenuStateScenario(Program *program, MainMenu *mainMenu, const Lang &lang= Lang::getInstance(); NetworkManager &networkManager= NetworkManager::getInstance(); + try { + networkManager.init(nrServer); + } + catch(const std::exception &ex) { + char szBuf[4096]=""; + sprintf(szBuf,"In [%s::%s %d] Error detected:\n%s\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); + + mainMessageBoxState=1; + showMessageBox( "Error: " + string(ex.what()), "Error detected", false); + } mainMessageBox.registerGraphicComponent(containerName,"mainMessageBox"); mainMessageBox.init(lang.get("Ok")); @@ -96,8 +108,6 @@ MenuStateScenario::MenuStateScenario(Program *program, MainMenu *mainMenu, const labelInfo.setText(scenarioInfo.desc); GraphicComponent::applyAllCustomProperties(containerName); - - networkManager.init(nrServer); } catch(const std::exception &ex) { char szBuf[4096]=""; diff --git a/source/shared_lib/include/lua/lua_script.h b/source/shared_lib/include/lua/lua_script.h index f64762e08..8193db941 100644 --- a/source/shared_lib/include/lua/lua_script.h +++ b/source/shared_lib/include/lua/lua_script.h @@ -37,6 +37,8 @@ private: string currentLuaFunction; bool currentLuaFunctionIsValid; + void DumpGlobals(); + public: LuaScript(); ~LuaScript(); diff --git a/source/shared_lib/sources/lua/lua_script.cpp b/source/shared_lib/sources/lua/lua_script.cpp index 1194fbfcf..60b7de149 100644 --- a/source/shared_lib/sources/lua/lua_script.cpp +++ b/source/shared_lib/sources/lua/lua_script.cpp @@ -61,9 +61,103 @@ LuaScript::LuaScript() { argumentCount= -1; } +void LuaScript::DumpGlobals() +{ + LuaHandle *L = luaState; + // push the first key (nil = beginning of table) + lua_pushnil(L); + + // lua_next will: + // 1 - pop the key + // 2 - push the next key + // 3 - push the value at that key + // ... so the key will be at index -2 and the value at index -1 + while (lua_next(L, LUA_GLOBALSINDEX) != 0) { + // get type of key and value + int key_type = lua_type(L, -2); + int value_type = lua_type(L, -1); + + // support only string keys + // globals aren't likely to have a non-string key, but just to be certain ... + if (key_type != LUA_TSTRING) { + lua_pop(L, 1); // pop the value so that the top contains the key for the next iteration + continue; + } + + // support only number, boolean and string values + if (value_type != LUA_TNUMBER && + value_type != LUA_TBOOLEAN && + value_type != LUA_TSTRING) { + lua_pop(L, 1); // again, pop the value before going to the next loop iteration + continue; + } + + // get the key as a string + string key_string = lua_tostring(L, -2); // no copy required - we already know this is a string + + // do not support variables that start with '_' + // lua has some predefined values like _VERSION. They all start with underscore + + if (!key_string.size()) { // this again is highly unlikely, but still ... + lua_pop(L, 1); + continue; + } + if (key_string[0] == '_') { + lua_pop(L, 1); + continue; + } + + string value_string; + + // convert the value to a string. This depends on its type + switch (value_type) { + case LUA_TSTRING: + case LUA_TNUMBER: + // numbers can be converted to strings + + // get the value as a string (this requires a copy because traversing tables + // uses the top of the stack as an index. If conversion from a number to string + // happens, the top of the stack will be altered and the table index will become invalid) + lua_pushvalue(L, -1); + value_string = lua_tostring(L, -1); + lua_pop(L, 1); + break; + case LUA_TBOOLEAN: + value_string = lua_toboolean(L, -1) == 0 ? "false" : "true"; + break; + } + + // enclose the value in "" if it is a string + if (value_type == LUA_TSTRING) { + value_string = "\"" + value_string + "\""; + } + + // resulting line. Somehow save this and when you need to restore it, just + // call luaL_dostring with that line. + //SaveLine(key_string + " = " + value_string); // Pop the value so the index remains on top of the stack for the next iteration + printf("Found global LUA var: %s = %s\n",key_string.c_str(),value_string.c_str()); + lua_pop(L, 1); + } +} + LuaScript::~LuaScript() { Lua_STREFLOP_Wrapper streflopWrapper; +// LuaInterface.LuaTable luatab; +// +// luatab = lua.GetTable("_G"); +// +// +// foreach (DictionaryEntry d in luatab) +// +// { +// +// Console.WriteLine("{0} -> {1}", d.Key, d.Value); +// +// } + + //DumpGlobals(); + lua_close(luaState); } @@ -73,7 +167,12 @@ void LuaScript::loadCode(const string &code, const string &name){ //printf("Code [%s]\nName [%s]\n",code.c_str(),name.c_str()); int errorCode= luaL_loadbuffer(luaState, code.c_str(), code.length(), name.c_str()); - if(errorCode !=0 ) { + if(errorCode != 0 ) { + printf("=========================================================\n"); + printf("Error loading lua code: %s\n",errorToString(errorCode).c_str()); + printf("Function name [%s]\ncode:\n%s\n",name.c_str(),code.c_str()); + printf("=========================================================\n"); + throw runtime_error("Error loading lua code: " + errorToString(errorCode)); } @@ -82,6 +181,10 @@ void LuaScript::loadCode(const string &code, const string &name){ //run code errorCode= lua_pcall(luaState, 0, 0, 0); if(errorCode !=0 ) { + printf("=========================================================\n"); + printf("Error calling lua pcall: %s\n",errorToString(errorCode).c_str()); + printf("=========================================================\n"); + throw runtime_error("Error initializing lua: " + errorToString(errorCode)); } diff --git a/source/shared_lib/sources/xml/xml_parser.cpp b/source/shared_lib/sources/xml/xml_parser.cpp index 2cb803870..f8f94d895 100644 --- a/source/shared_lib/sources/xml/xml_parser.cpp +++ b/source/shared_lib/sources/xml/xml_parser.cpp @@ -272,9 +272,9 @@ XmlNode *XmlIoRapid::load(const string &path, std::map mapTagRepl try { #if defined(WIN32) && !defined(__MINGW32__) FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb"); - ifstream xmlFile(fp); + ifstream xmlFile(fp,ios::binary); #else - ifstream xmlFile(path.c_str()); + ifstream xmlFile(path.c_str(),ios::binary); #endif if(xmlFile.is_open() == false) { throw runtime_error("Can not open file: [" + path + "]"); @@ -282,10 +282,15 @@ XmlNode *XmlIoRapid::load(const string &path, std::map mapTagRepl // read file into input_xml string inputXml = ""; - string line = ""; - while(getline(xmlFile,line)) { - inputXml += line; - } + const int bufsize = 32 * 1024; + char buff[bufsize]=""; + while(xmlFile) { + xmlFile.read(buff,bufsize); + if(buff[0] != '\0') { + inputXml += buff; + } + } + // make a safe-to-modify copy of input_xml // (you should never modify the contents of an std::string directly) vector buffer(inputXml.begin(), inputXml.end()); @@ -356,10 +361,10 @@ void XmlIoRapid::save(const string &path, const XmlNode *node){ // // xml_no_indent now contains non-indented XML #if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(path).c_str(), L"wt"); + FILE *fp = _wfopen(utf8_decode(path).c_str(), L"wb"); ofstream xmlFile(fp); #else - ofstream xmlFile(path.c_str()); + ofstream xmlFile(path.c_str(),ios::binary); #endif if(xmlFile.is_open() == false) { throw runtime_error("Can not open file: [" + path + "]");