From d6fa07c2b4b3eb0c8db4f79927f88de72892dcc2 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Fri, 22 Aug 2014 12:46:02 +0200 Subject: Corrected for a MSVC compiler bug and more tests in validate() --- src/uscxml/Interpreter.cpp | 145 +++++++++++++++------- src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 10 +- test/src/test-w3c.cpp | 8 ++ 3 files changed, 116 insertions(+), 47 deletions(-) diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 06b8b37..370bef0 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -784,6 +784,96 @@ std::list InterpreterImpl::validate() { allExecContents.push_back(scripts); allExecContents.push_back(cancels); + NodeSet allElements; + allElements.push_back(allStates); + allElements.push_back(allExecContents); + allElements.push_back(transitions); + allElements.push_back(initials); + allElements.push_back(onEntries); + allElements.push_back(onExits); + allElements.push_back(dataModels); + allElements.push_back(datas); + allElements.push_back(doneDatas); + allElements.push_back(contents); + allElements.push_back(params); + allElements.push_back(invokes); + allElements.push_back(finalizes); + + + std::set execContentSet; + execContentSet.insert("raise"); + execContentSet.insert("if"); + execContentSet.insert("elseif"); + execContentSet.insert("else"); + execContentSet.insert("foreach"); + execContentSet.insert("log"); + execContentSet.insert("send"); + execContentSet.insert("assign"); + execContentSet.insert("script"); + execContentSet.insert("cancel"); + + std::map > validChildren; + validChildren["scxml"].insert("state"); + validChildren["scxml"].insert("parallel"); + validChildren["scxml"].insert("final"); + validChildren["scxml"].insert("datamodel"); + validChildren["scxml"].insert("script"); + + validChildren["state"].insert("onentry"); + validChildren["state"].insert("onexit"); + validChildren["state"].insert("transition"); + validChildren["state"].insert("initial"); + validChildren["state"].insert("state"); + validChildren["state"].insert("parallel"); + validChildren["state"].insert("final"); + validChildren["state"].insert("history"); + validChildren["state"].insert("datamodel"); + validChildren["state"].insert("invoke"); + + validChildren["parallel"].insert("onentry"); + validChildren["parallel"].insert("onexit"); + validChildren["parallel"].insert("transition"); + validChildren["parallel"].insert("state"); + validChildren["parallel"].insert("parallel"); + validChildren["parallel"].insert("history"); + validChildren["parallel"].insert("datamodel"); + validChildren["parallel"].insert("invoke"); + + validChildren["transition"] = execContentSet; + validChildren["onentry"] = execContentSet; + validChildren["onexit"] = execContentSet; + validChildren["finalize"] = execContentSet; + + validChildren["if"] = execContentSet; + validChildren["elseif"] = execContentSet; + validChildren["else"] = execContentSet; + validChildren["foreach"] = execContentSet; + + validChildren["initial"].insert("transition"); + validChildren["history"].insert("transition"); + + validChildren["final"].insert("onentry"); + validChildren["final"].insert("onexit"); + validChildren["final"].insert("donedata"); + + validChildren["datamodel"].insert("data"); + + validChildren["donedata"].insert("content"); + validChildren["donedata"].insert("param"); + + validChildren["send"].insert("content"); + validChildren["send"].insert("param"); + + validChildren["invoke"].insert("content"); + validChildren["invoke"].insert("param"); + validChildren["invoke"].insert("finalize"); + + std::map > validParents; + for (std::map >::iterator parentIter = validChildren.begin(); parentIter != validChildren.end(); parentIter++) { + for (std::set::iterator childIter = parentIter->second.begin(); childIter != parentIter->second.end(); childIter++) { + validParents[*childIter].insert(parentIter->first); + } + } for (int i = 0; i < allStates.size(); i++) { Element state = Element(allStates[i]); @@ -929,60 +1019,27 @@ std::list InterpreterImpl::validate() { } } - // check that all SCXML elements are in valid containers - - // check that all states are in states + // check that all SCXML elements have valid parents { - NodeSet validStateParents; - validStateParents.push_back(allStates); - validStateParents.push_back(scxmls); - - for (int i = 0; i < allStates.size(); i++) { - Element state = Element(allStates[i]); - if (!state.getParentNode() || state.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) { - issues.push_back(InterpreterIssue("State's parent node is no element", state, InterpreterIssue::USCXML_ISSUE_INFO)); + for (int i = 0; i < allElements.size(); i++) { + Element element = Element(allElements[i]); + std::string localName = LOCALNAME(element); + if (!element.getParentNode() || element.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) { + issues.push_back(InterpreterIssue("Parent of " + localName + " is no element", element, InterpreterIssue::USCXML_ISSUE_INFO)); continue; } - Element parent = Element(state.getParentNode()); - if (!isMember(parent, validStateParents)) { - issues.push_back(InterpreterIssue("State has invalid parent element", state, InterpreterIssue::USCXML_ISSUE_INFO)); - continue; - } - } - } - - // check that all executable content is in a executable content container - { - NodeSet validExecContentParents; - validExecContentParents.push_back(transitions); - validExecContentParents.push_back(onExits); - validExecContentParents.push_back(onEntries); - - for (int i = 0; i < allExecContents.size(); i++) { - Element execContent = Element(allExecContents[i]); - if (!execContent.getParentNode() || execContent.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) { - issues.push_back(InterpreterIssue("Executable content's parent node is no element", execContent, InterpreterIssue::USCXML_ISSUE_INFO)); - continue; - } + Element parent = Element(element.getParentNode()); + std::string parentName = LOCALNAME(parent); - Node parent = execContent.getParentNode(); - if (parent == _scxml && isMember(execContent, scripts)) - continue; - - while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) { - if (isMember(parent, validExecContentParents)) { - break; - } - parent = parent.getParentNode(); - } - if (!parent) { - issues.push_back(InterpreterIssue("Executable content is not in a valid parent", execContent, InterpreterIssue::USCXML_ISSUE_INFO)); + if (validParents[localName].find(parentName) == validParents[localName].end()) { + issues.push_back(InterpreterIssue("Element " + parentName + " can be no parent of " + localName, element, InterpreterIssue::USCXML_ISSUE_INFO)); continue; } } } + // check that the datamodel is known if (HAS_ATTR(_scxml, "datamodel")) { if (!_factory->hasDataModel(ATTR(_scxml, "datamodel"))) { diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index 02b97c3..6fa56df 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -22,8 +22,11 @@ #include "uscxml/Common.h" #include "LuaDataModel.h" +// disable forcing to bool performance warning +#pragma warning(push) +#pragma warning(disable : 4800) #include "LuaBridge.h" -//#include "RefCountedPtr.h" +#pragma warning(pop) #include "uscxml/DOMUtils.h" @@ -136,7 +139,6 @@ static int luaInFunction(lua_State * l) { return 1; } - boost::shared_ptr LuaDataModel::create(InterpreterImpl* interpreter) { boost::shared_ptr dm = boost::shared_ptr(new LuaDataModel()); dm->_interpreter = interpreter; @@ -147,7 +149,9 @@ boost::shared_ptr LuaDataModel::create(InterpreterImpl* interpret const luabridge::LuaRef& requireFunc = luabridge::getGlobal(dm->_luaState, "require"); const luabridge::LuaRef& resultLxp = requireFunc("lxp"); const luabridge::LuaRef& resultLxpLOM = requireFunc("lxp.lom"); - if (resultLxp && resultLxpLOM) { + + // MSVC compiler bug with implicit cast operators, see comments in LuaRef class + if ((bool)resultLxp && (bool)resultLxpLOM) { _luaHasXMLParser = true; luabridge::setGlobal(dm->_luaState, resultLxp, "lxp"); luabridge::setGlobal(dm->_luaState, resultLxpLOM, "lxp.lom"); diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp index 6a3294d..4bd27b1 100644 --- a/test/src/test-w3c.cpp +++ b/test/src/test-w3c.cpp @@ -202,6 +202,14 @@ int main(int argc, char** argv) { } if (interpreter) { +// std::list issues = interpreter.validate(); +// if (issues.size() > 0) { +// for (std::list::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) { +// std::cout << *issueIter << std::endl; +// } +// exit(EXIT_FAILURE); +// } + // interpreter.setCmdLineOptions(argc, argv); // interpreter->setCapabilities(Interpreter::CAN_NOTHING); // interpreter->setCapabilities(Interpreter::CAN_BASIC_HTTP | Interpreter::CAN_GENERIC_HTTP); -- cgit v0.12