diff options
author | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
commit | b62e7979600feee23dc7cdb61042a8fc7673122b (patch) | |
tree | f7351372f37979dd2d048e0b68a16a4cd3b2aadb /src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | |
parent | 1b11b310be61e51b3ac5ebb83f7c8a33aef3d6e8 (diff) | |
download | uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.zip uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.gz uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.bz2 |
Major Refactoring v2.0
Diffstat (limited to 'src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp')
-rw-r--r-- | src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 441 |
1 files changed, 209 insertions, 232 deletions
diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index f6cb570..6fc5ac4 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -17,10 +17,10 @@ * @endcond */ -#include <boost/algorithm/string.hpp> - #include "uscxml/Common.h" +#include "uscxml/util/URL.h" #include "uscxml/util/String.h" + #include "LuaDataModel.h" // disable forcing to bool performance warning @@ -29,31 +29,71 @@ #include "LuaBridge.h" #pragma warning(pop) -#include "uscxml/dom/DOMUtils.h" - -#include "uscxml/Message.h" -#include <glog/logging.h> +#include "uscxml/messages/Event.h" +#include "uscxml/util/DOM.h" +#include <easylogging++.h> +#include <boost/algorithm/string.hpp> -#ifdef BUILD_AS_PLUGINS -#include <Pluma/Connector.hpp> -#endif +//#include "LuaDOM.cpp.inc" namespace uscxml { -#ifdef BUILD_AS_PLUGINS -PLUMA_CONNECTOR -bool pluginConnect(pluma::Host& host) { - host.add( new LuaDataModelProvider() ); - return true; -} -#endif - -static int luaInspect(lua_State * l) { - return 0; -} +//static int luaInspect(lua_State * l) { +// return 0; +//} bool _luaHasXMLParser = false; +static int luaEval(lua_State* luaState, const std::string& expr) { + int preStack = lua_gettop(luaState); + int error = luaL_loadstring(luaState, expr.c_str()) || lua_pcall(luaState, 0, LUA_MULTRET, 0); + if (error) { + std::string errMsg = lua_tostring(luaState, -1); + lua_pop(luaState, 1); /* pop error message from the stack */ + ERROR_EXECUTION_THROW(errMsg); + } + int postStack = lua_gettop(luaState); + return postStack - preStack; +} + +static Data getLuaAsData(lua_State* _luaState, const luabridge::LuaRef& lua) { + Data data; + if (lua.isFunction()) { + // TODO: this might lead to a stack-overflow + luabridge::LuaRef luaEvald = lua(); + return getLuaAsData(_luaState, luaEvald); + } else if(lua.isLightUserdata() || lua.isUserdata()) { + // not sure what to do + } else if(lua.isThread()) { + // not sure what to do + } else if(lua.isNil()) { + data.atom = "nil"; + data.type = Data::INTERPRETED; + } else if(lua.isNumber()) { + data.atom = toStr(lua.cast<int>()); + data.type = Data::INTERPRETED; + } else if(lua.isString()) { + data.atom = lua.tostring(); + data.type = Data::VERBATIM; + } else if(lua.isTable()) { + bool isArray = false; + bool isMap = false; + for (luabridge::Iterator iter (lua); !iter.isNil(); ++iter) { + luabridge::LuaRef luaKey = iter.key(); + luabridge::LuaRef luaVal = *iter; + if (luaKey.isString()) { + assert(!isArray); + isMap = true; + data.compound[luaKey.tostring()] = getLuaAsData(_luaState, luaVal); + } else { + assert(!isMap); + isArray = true; + data.array.push_back(getLuaAsData(_luaState, luaVal)); + } + } + } + return data; +} static luabridge::LuaRef getDataAsLua(lua_State* _luaState, const Data& data) { luabridge::LuaRef luaData (_luaState); @@ -80,24 +120,24 @@ static luabridge::LuaRef getDataAsLua(lua_State* _luaState, const Data& data) { luaData[compoundIter->first] = getDataAsLua(_luaState, compoundIter->second); compoundIter++; } - luaData["inspect"] = luaInspect; +// luaData["inspect"] = luaInspect; return luaData; } if (data.array.size() > 0) { luaData = luabridge::newTable(_luaState); std::list<Data>::const_iterator arrayIter = data.array.begin(); - uint32_t index = 0; +// uint32_t index = 0; while(arrayIter != data.array.end()) { - luaData[index++] = getDataAsLua(_luaState, *arrayIter); +// luaData[index++] = getDataAsLua(_luaState, *arrayIter); + luaData.append(getDataAsLua(_luaState, *arrayIter)); arrayIter++; } - luaData["inspect"] = luaInspect; +// luaData["inspect"] = luaInspect; return luaData; } if (data.atom.size() > 0) { switch (data.type) { case Data::VERBATIM: { -// luaData = "\"" + data.atom + "\""; luaData = data.atom; break; } @@ -109,29 +149,34 @@ static luabridge::LuaRef getDataAsLua(lua_State* _luaState, const Data& data) { luaData = strTo<long>(data.atom); } } else { - luaData = data.atom; + int retVals = luaEval(_luaState, "return(" + data.atom + ");"); + if (retVals == 1) { + luaData = luabridge::LuaRef::fromStack(_luaState, -1); + } + lua_pop(_luaState, retVals); } } } return luaData; } - return luaData; + // hopefully this is nil + return luabridge::LuaRef(_luaState); } LuaDataModel::LuaDataModel() { _luaState = NULL; } -static int luaInFunction(lua_State * l) { - luabridge::LuaRef ref = luabridge::getGlobal(l, "__interpreter"); - InterpreterInfo* interpreter = ref.cast<InterpreterInfo*>(); +int LuaDataModel::luaInFunction(lua_State * l) { + luabridge::LuaRef ref = luabridge::getGlobal(l, "__datamodel"); + LuaDataModel* dm = ref.cast<LuaDataModel*>(); int stackSize = lua_gettop(l); for (size_t i = 0; i < stackSize; i++) { if (!lua_isstring(l, -1 - i)) continue; std::string stateName = lua_tostring(l, -1 - i); - if (interpreter->isInState(stateName)) + if (dm->_callbacks->isInState(stateName)) continue; lua_pushboolean(l, 0); return 1; @@ -140,9 +185,9 @@ static int luaInFunction(lua_State * l) { return 1; } -boost::shared_ptr<DataModelImpl> LuaDataModel::create(InterpreterInfo* interpreter) { - boost::shared_ptr<LuaDataModel> dm = boost::shared_ptr<LuaDataModel>(new LuaDataModel()); - dm->_interpreter = interpreter; +std::shared_ptr<DataModelImpl> LuaDataModel::create(DataModelCallbacks* callbacks) { + std::shared_ptr<LuaDataModel> dm(new LuaDataModel()); + dm->_callbacks = callbacks; dm->_luaState = luaL_newstate(); luaL_openlibs(dm->_luaState); @@ -161,23 +206,33 @@ boost::shared_ptr<DataModelImpl> LuaDataModel::create(InterpreterInfo* interpret LOG(INFO) << e.what(); } - luabridge::getGlobalNamespace(dm->_luaState).beginClass<InterpreterInfo>("Interpreter").endClass(); - luabridge::setGlobal(dm->_luaState, dm->_interpreter, "__interpreter"); + luabridge::getGlobalNamespace(dm->_luaState).beginClass<LuaDataModel>("DataModel").endClass(); + luabridge::setGlobal(dm->_luaState, dm.get(), "__datamodel"); luabridge::getGlobalNamespace(dm->_luaState).addCFunction("In", luaInFunction); luabridge::LuaRef ioProcTable = luabridge::newTable(dm->_luaState); - - std::map<std::string, IOProcessor>::const_iterator ioProcIter = dm->_interpreter->getIOProcessors().begin(); - while(ioProcIter != dm->_interpreter->getIOProcessors().end()) { + std::map<std::string, IOProcessor> ioProcs = dm->_callbacks->getIOProcessors(); + std::map<std::string, IOProcessor>::const_iterator ioProcIter = ioProcs.begin(); + while(ioProcIter != ioProcs.end()) { Data ioProcData = ioProcIter->second.getDataModelVariables(); ioProcTable[ioProcIter->first] = getDataAsLua(dm->_luaState, ioProcData); ioProcIter++; } luabridge::setGlobal(dm->_luaState, ioProcTable, "_ioprocessors"); - luabridge::setGlobal(dm->_luaState, dm->_interpreter->getName(), "_name"); - luabridge::setGlobal(dm->_luaState, dm->_interpreter->getSessionId(), "_sessionid"); + luabridge::LuaRef invTable = luabridge::newTable(dm->_luaState); + std::map<std::string, Invoker> invokers = dm->_callbacks->getInvokers(); + std::map<std::string, Invoker>::const_iterator invIter = invokers.begin(); + while(invIter != invokers.end()) { + Data invData = invIter->second.getDataModelVariables(); + invTable[invIter->first] = getDataAsLua(dm->_luaState, invData); + invIter++; + } + luabridge::setGlobal(dm->_luaState, invTable, "_invokers"); + + luabridge::setGlobal(dm->_luaState, dm->_callbacks->getName(), "_name"); + luabridge::setGlobal(dm->_luaState, dm->_callbacks->getSessionId(), "_sessionid"); return dm; } @@ -187,42 +242,8 @@ LuaDataModel::~LuaDataModel() { lua_close(_luaState); } -void LuaDataModel::pushContext() { -} - -void LuaDataModel::popContext() { -} - -void LuaDataModel::initialize() { -} - -static Data getLuaAsData(const luabridge::LuaRef& lua) { - Data data; - if (lua.isFunction()) { - // TODO: this might lead to a stack-overflow - luabridge::LuaRef luaEvald = lua(); - return getLuaAsData(luaEvald); - } else if(lua.isLightUserdata() || lua.isUserdata()) { - // not sure what to do - } else if(lua.isThread()) { - // not sure what to do - } else if(lua.isNil()) { - data.atom = "undefined"; - data.type = Data::INTERPRETED; - } else if(lua.isString()) { - data.atom = lua.tostring(); - data.type = Data::VERBATIM; - } else if(lua.isNumber()) { - data.atom = lua.tostring(); - data.type = Data::INTERPRETED; - } else if(lua.isTable()) { - for (luabridge::Iterator iter (lua); !iter.isNil (); ++iter) { - luabridge::LuaRef luaKey = iter.key(); - luabridge::LuaRef luaVal = *iter; - data.compound[luaKey.tostring()] = getLuaAsData(luaVal); - } - } - return data; +void LuaDataModel::addExtension(DataModelExtension* ext) { + ERROR_EXECUTION_THROW("Extensions unimplemented in lua datamodel"); } void LuaDataModel::setEvent(const Event& event) { @@ -230,14 +251,17 @@ void LuaDataModel::setEvent(const Event& event) { luaEvent = luabridge::newTable(_luaState); luaEvent["name"] = event.name; - luaEvent["raw"] = event.raw; - luaEvent["xml"] = event.xml; - luaEvent["origin"] = event.origin; - luaEvent["origintype"] = event.origintype; - luaEvent["content"] = event.content; - luaEvent["invokeId"] = event.invokeid; - luaEvent["sendId"] = event.sendid; - luaEvent["inspect"] = luaInspect; + if (event.raw.size() > 0) + luaEvent["raw"] = event.raw; + if (event.origin.size() > 0) + luaEvent["origin"] = event.origin; + if (event.origintype.size() > 0) + luaEvent["origintype"] = event.origintype; + if (event.invokeid.size() > 0) + luaEvent["invokeid"] = event.invokeid; + if (!event.hideSendId) + luaEvent["sendid"] = event.sendid; +// luaEvent["inspect"] = luaInspect; switch (event.eventType) { case Event::INTERNAL: @@ -254,64 +278,44 @@ void LuaDataModel::setEvent(const Event& event) { break; } - if (event.dom) { + if (event.data.node) { if (_luaHasXMLParser) { const luabridge::LuaRef& luaLom = luabridge::getGlobal(_luaState, "lxp.lom"); const luabridge::LuaRef& luaLomParse = luaLom["parse"]; assert(luaLomParse.isFunction()); std::stringstream luaXMLSS; - luaXMLSS << event.dom; + luaXMLSS << event.data.node; try { luaEvent["data"] = luaLomParse(luaXMLSS.str()); } catch (luabridge::LuaException e) { ERROR_EXECUTION_THROW(e.what()); } } else { - // some error events have a dom node attached - do not throw for them - // issue65 - if (!nameMatch("error.*", event.name)) { - ERROR_EXECUTION_THROW("No DOM support in Lua datamodel"); - } - } - } else if (event.content.length() > 0) { - // _event.data is a string or JSON - Data json = Data::fromJSON(event.content); - if (!json.empty()) { - luaEvent["data"] = getDataAsLua(_luaState, json); - } else { - // test179 - std::string trimmed = boost::trim_copy(event.content); - if ((boost::starts_with(trimmed, "'") && boost::ends_with(trimmed, "'")) || - (boost::starts_with(trimmed, "\"") && boost::ends_with(trimmed, "\""))) { - luaEvent["data"] = spaceNormalize(event.content); - } else { - Data tmp(event.content, Data::INTERPRETED); - luaEvent["data"] = getDataAsLua(_luaState, tmp); - } + ERROR_EXECUTION_THROW("No DOM support in Lua datamodel"); } } else { // _event.data is KVP - Event eventCopy(event); + Data d = event.data; - if (!eventCopy.params.empty()) { - Event::params_t::iterator paramIter = eventCopy.params.begin(); - while(paramIter != eventCopy.params.end()) { - eventCopy.data.compound[paramIter->first] = paramIter->second; + if (!event.params.empty()) { + Event::params_t::const_iterator paramIter = event.params.begin(); + while(paramIter != event.params.end()) { + d.compound[paramIter->first] = paramIter->second; paramIter++; } } - if (!eventCopy.namelist.empty()) { - Event::namelist_t::iterator nameListIter = eventCopy.namelist.begin(); - while(nameListIter != eventCopy.namelist.end()) { - eventCopy.data.compound[nameListIter->first] = nameListIter->second; + if (!event.namelist.empty()) { + Event::namelist_t::const_iterator nameListIter = event.namelist.begin(); + while(nameListIter != event.namelist.end()) { + d.compound[nameListIter->first] = nameListIter->second; nameListIter++; } } - if (!eventCopy.data.empty()) { - luabridge::LuaRef luaData = getDataAsLua(_luaState, eventCopy.data); + if (!d.empty()) { + luabridge::LuaRef luaData = getDataAsLua(_luaState, d); assert(luaEvent.isTable()); - assert(luaData.isTable()); + // assert(luaData.isTable()); // not necessarily test179 luaEvent["data"] = luaData; } } @@ -319,31 +323,29 @@ void LuaDataModel::setEvent(const Event& event) { luabridge::setGlobal(_luaState, luaEvent, "_event"); } -Data LuaDataModel::getStringAsData(const std::string& content) { -// Data data = Data::fromJSON(content); +Data LuaDataModel::evalAsData(const std::string& content) { Data data; - if (data.empty()) { - std::string trimmedExpr = boost::trim_copy(content); - if (!boost::starts_with(trimmedExpr, "return")) { - trimmedExpr = "return(" + trimmedExpr + ");"; - } - int retVals = luaEval(Arabica::DOM::Element<std::string>(), trimmedExpr); + std::string trimmedExpr = boost::trim_copy(content); + + try { + int retVals = luaEval(_luaState, "return(" + trimmedExpr + ")"); if (retVals == 1) { - data = getLuaAsData(luabridge::LuaRef::fromStack(_luaState, -1)); + data = getLuaAsData(_luaState, luabridge::LuaRef::fromStack(_luaState, -1)); } lua_pop(_luaState, retVals); - + } catch (ErrorEvent e) { + int retVals = luaEval(_luaState, trimmedExpr); + if (retVals == 1) { + data = getLuaAsData(_luaState, luabridge::LuaRef::fromStack(_luaState, -1)); + lua_pop(_luaState, retVals); + } else { + lua_pop(_luaState, retVals); + throw e; // we will assume syntax error and throw + } } - return data; -} -bool LuaDataModel::validate(const std::string& location, const std::string& schema) { - return true; -} - -bool LuaDataModel::isLocation(const std::string& expr) { - return true; + return data; } bool LuaDataModel::isValidSyntax(const std::string& expr) { @@ -368,7 +370,9 @@ uint32_t LuaDataModel::getLength(const std::string& expr) { trimmedExpr = "return(#" + trimmedExpr + ")"; } - int retVals = luaEval(Arabica::DOM::Element<std::string>(), trimmedExpr); + int retVals = luaEval(_luaState, trimmedExpr); + +#if 1 if (retVals == 1 && lua_isnumber(_luaState, -1)) { int result = lua_tointeger(_luaState, -1); @@ -379,6 +383,21 @@ uint32_t LuaDataModel::getLength(const std::string& expr) { lua_pop(_luaState, retVals); ERROR_EXECUTION_THROW("'" + expr + "' does not evaluate to an array."); return 0; +#else + + if (retVals == 1) { + luabridge::LuaRef luaData = luabridge::LuaRef::fromStack(_luaState, -1); + if (luaData.isNumber()) { + lua_pop(_luaState, retVals); + return luaData.cast<int>(); + } + } + lua_pop(_luaState, retVals); + + ERROR_EXECUTION_THROW("'" + expr + "' does not evaluate to an array."); + return 0; + +#endif } void LuaDataModel::setForeach(const std::string& item, @@ -390,152 +409,110 @@ void LuaDataModel::setForeach(const std::string& item, const luabridge::LuaRef& arrRef = luabridge::getGlobal(_luaState, array.c_str()); if (arrRef.isTable()) { - // trigger syntax error for invalid items - int retVals = luaEval(Arabica::DOM::Element<std::string>(), "return(" + item + ");"); + // triggers syntax error for invalid items, test 152 + int retVals = luaEval(_luaState, item + " = " + array + "[" + toStr(iteration) + "]"); lua_pop(_luaState, retVals); - const luabridge::LuaRef& val = arrRef[iteration]; - luabridge::setGlobal(_luaState, val, item.c_str()); - if (index.length() > 0) { - // assign iteration element to index - luabridge::setGlobal(_luaState, iteration, index.c_str()); + int retVals = luaEval(_luaState, index + " = " + toStr(iteration)); + lua_pop(_luaState, retVals); } } } -void LuaDataModel::eval(const Arabica::DOM::Element<std::string>& scriptElem, - const std::string& expr) { - luaEval(scriptElem, expr); -} - -int LuaDataModel::luaEval(const Arabica::DOM::Element<std::string>& scriptElem, - const std::string& expr) { - int preStack = lua_gettop(_luaState); - int error = luaL_loadstring(_luaState, expr.c_str()) || lua_pcall(_luaState, 0, LUA_MULTRET, 0); - if (error) { - std::string errMsg = lua_tostring(_luaState, -1); - lua_pop(_luaState, 1); /* pop error message from the stack */ - ERROR_EXECUTION_THROW(errMsg); - } - int postStack = lua_gettop(_luaState); - return postStack - preStack; -} - bool LuaDataModel::isDeclared(const std::string& expr) { // see: http://lua-users.org/wiki/DetectingUndefinedVariables return true; } -void LuaDataModel::assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Node<std::string>& node, - const std::string& content) { - std::string key; - if (HAS_ATTR(assignElem, "id")) { - key = ATTR(assignElem, "id"); - } else if (HAS_ATTR(assignElem, "location")) { - key = ATTR(assignElem, "location"); - } - if (key.length() == 0) { + +void LuaDataModel::assign(const std::string& location, const Data& data) { + if (location.length() == 0) { ERROR_EXECUTION_THROW("Assign element has neither id nor location"); } // flags on attribute are ignored? - if (key.compare("_sessionid") == 0) // test 322 + if (location.compare("_sessionid") == 0) // test 322 ERROR_EXECUTION_THROW("Cannot assign to _sessionId"); - if (key.compare("_name") == 0) + if (location.compare("_name") == 0) ERROR_EXECUTION_THROW("Cannot assign to _name"); - if (key.compare("_ioprocessors") == 0) // test 326 + if (location.compare("_ioprocessors") == 0) // test 326 ERROR_EXECUTION_THROW("Cannot assign to _ioprocessors"); - if (key.compare("_invokers") == 0) + if (location.compare("_invokers") == 0) ERROR_EXECUTION_THROW("Cannot assign to _invokers"); - if (key.compare("_event") == 0) + if (location.compare("_event") == 0) ERROR_EXECUTION_THROW("Cannot assign to _event"); -// lua_pushnil(_luaState); -// lua_setglobal(_luaState, key.c_str()); + if (data.node) { + ERROR_EXECUTION_THROW("Cannot assign xml nodes in lua datamodel"); -// luabridge::setGlobal(_luaState, luabridge::Nil(), key.c_str()); -// luabridge::LuaRef val = luabridge::getGlobal(_luaState, key.c_str()); -// std::cout << val.tostring() << std::endl; + // TODO: DOM is prepared by swig - int retVals = 0; +// return SWIG_JSC_NewPointerObj(_ctx, +// (void*)node, +// SWIG_TypeDynamicCast(SWIGTYPE_p_XERCES_CPP_NAMESPACE__DOMNode, +// SWIG_as_voidptrptr(&node)), +// 0); - if (HAS_ATTR(assignElem, "expr")) { - retVals = luaEval(Arabica::DOM::Element<std::string>(), key + " = " + ATTR(assignElem, "expr") + ";"); - } else if (node) { - ERROR_EXECUTION_THROW("Cannot assign xml nodes in lua datamodel"); - } else if (content.size() > 0) { - try { - eval(Arabica::DOM::Element<std::string>(), key + " = " + content + ";"); - } catch (...) { - eval(Arabica::DOM::Element<std::string>(), key + " = " + "\"" + spaceNormalize(content) + "\";"); - } + +// JSObjectSetProperty(_ctx, JSContextGetGlobalObject(_ctx), JSStringCreateWithUTF8CString(location.c_str()), getNodeAsValue(data.node), 0, &exception); } else { - eval(Arabica::DOM::Element<std::string>(), key + " = " + "nil;"); - } -// val = luabridge::getGlobal(_luaState, key.c_str()); -// std::cout << val.tostring() << std::endl; + // trigger error.execution for undefined locations, test286 test311 + int retVals = luaEval(_luaState, location + " = " + location); + lua_pop(_luaState, retVals); -} + luabridge::LuaRef lua = getDataAsLua(_luaState, data); + luabridge::setGlobal(_luaState, lua, location.c_str()); -void LuaDataModel::assign(const std::string& location, const Data& data) { - luabridge::setGlobal(_luaState, getDataAsLua(_luaState, data), location.c_str()); -} - -void LuaDataModel::init(const Arabica::DOM::Element<std::string>& dataElem, - const Arabica::DOM::Node<std::string>& node, - const std::string& content) { - assign(dataElem, node, content); +// std::cout << Data::toJSON(evalAsData(location)) << std::endl; + } } void LuaDataModel::init(const std::string& location, const Data& data) { + luabridge::setGlobal(_luaState, luabridge::Nil(), location.c_str()); assign(location, data); } -/** - * The boolean expression language consists of the In predicate only. It has the - * form 'In(id)', where id is the id of a state in the enclosing state machine. - * The predicate must return 'true' if and only if that state is in the current - * state configuration. - */ -bool LuaDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { +bool LuaDataModel::evalAsBool(const std::string& expr) { // we need the result of the expression on the lua stack -> has to "return"! std::string trimmedExpr = boost::trim_copy(expr); - if (!boost::starts_with(trimmedExpr, "return")) { - trimmedExpr = "return(" + trimmedExpr + ");"; - } - int retVals = luaEval(Arabica::DOM::Element<std::string>(), trimmedExpr); + int retVals = luaEval(_luaState, "return(" + trimmedExpr + ")"); - if (retVals == 1 && lua_isboolean(_luaState, -1)) { + if (retVals == 1) { bool result = lua_toboolean(_luaState, -1); lua_pop(_luaState, 1); return result; } lua_pop(_luaState, retVals); + return false; } +Data LuaDataModel::getAsData(const std::string& content) { + Data data; + std::string trimmedExpr = boost::trim_copy(content); -std::string LuaDataModel::evalAsString(const std::string& expr) { - std::string trimmedExpr = boost::trim_copy(expr); - if (!boost::starts_with(trimmedExpr, "return")) { - trimmedExpr = "return(" + trimmedExpr + ")"; + int retVals = luaEval(_luaState, "__tmp = " + content + "; return __tmp"); + if (retVals == 1) { + data = getLuaAsData(_luaState, luabridge::LuaRef::fromStack(_luaState, -1)); } + lua_pop(_luaState, retVals); - int retVals = luaEval(Arabica::DOM::Element<std::string>(), trimmedExpr); - - if (retVals == 1 && lua_isstring(_luaState, -1)) { - std::string result = lua_tostring(_luaState, -1); - lua_pop(_luaState, 1); - return result; + // escape as a string, this is sometimes the case with <content> + if (data.atom == "nil" && data.type == Data::INTERPRETED) { + int retVals = luaEval(_luaState, "__tmp = '" + content + "'; return __tmp"); + if (retVals == 1) { + data = getLuaAsData(_luaState, luabridge::LuaRef::fromStack(_luaState, -1)); + } + lua_pop(_luaState, retVals); } - lua_pop(_luaState, retVals); - return ""; + + return data; } + std::string LuaDataModel::andExpressions(std::list<std::string> exprs) { std::stringstream exprSS; std::list<std::string>::const_iterator listIter; |