From fc78cfdc4d1f5bba8dbd6a412f23651e185cb191 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Wed, 18 Jan 2017 18:15:46 +0100 Subject: Worked on passing even more IRP tests --- apps/uscxml-browser.cpp | 15 +- src/bindings/swig/wrapped/WrappedDataModel.h | 12 +- src/bindings/swig/wrapped/WrappedIOProcessor.cpp | 4 +- src/bindings/swig/wrapped/WrappedIOProcessor.h | 6 +- src/uscxml/interpreter/BasicContentExecutor.cpp | 29 +- src/uscxml/interpreter/BasicDelayedEventQueue.cpp | 18 +- src/uscxml/interpreter/ContentExecutorImpl.h | 3 +- src/uscxml/interpreter/InterpreterImpl.cpp | 47 +- src/uscxml/interpreter/InterpreterImpl.h | 10 +- src/uscxml/messages/Data.cpp | 4 +- src/uscxml/messages/Data.h | 35 +- src/uscxml/plugins/DataModel.cpp | 12 +- src/uscxml/plugins/DataModel.h | 10 +- src/uscxml/plugins/DataModelImpl.h | 19 +- src/uscxml/plugins/EventHandler.h | 3 - src/uscxml/plugins/Factory.cpp | 15 +- src/uscxml/plugins/Factory.h | 3 +- src/uscxml/plugins/IOProcessorImpl.h | 23 +- src/uscxml/plugins/InvokerImpl.h | 2 +- .../ecmascript/JavaScriptCore/JSCDataModel.cpp | 31 +- .../ecmascript/JavaScriptCore/JSCDataModel.h | 10 +- .../datamodel/ecmascript/v8/V8DataModel.cpp | 46 +- .../plugins/datamodel/ecmascript/v8/V8DataModel.h | 10 +- src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 24 +- src/uscxml/plugins/datamodel/lua/LuaDataModel.h | 10 +- src/uscxml/plugins/datamodel/null/NULLDataModel.h | 14 +- .../plugins/datamodel/promela/PromelaDataModel.cpp | 132 +-- .../plugins/datamodel/promela/PromelaDataModel.h | 10 +- .../plugins/datamodel/promela/PromelaParser.h | 2 +- .../plugins/invoker/dirmon/DirMonInvoker.cpp | 10 +- src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp | 22 +- .../ioprocessor/basichttp/BasicHTTPIOProcessor.cpp | 10 +- .../ioprocessor/basichttp/BasicHTTPIOProcessor.h | 4 +- .../plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp | 40 +- .../plugins/ioprocessor/scxml/SCXMLIOProcessor.h | 6 +- test/CMakeLists.txt | 12 +- test/ctest/CTestCustom.ctest.in | 92 +- test/ctest/scripts/run_header_compiles.cmake | 1 + test/ctest/scripts/test_generated_java.cmake | 4 +- test/src/test-extensions.cpp | 8 +- test/src/test-gen-c.cpp | 78 +- test/src/test-http-debugger.pl | 9 +- test/w3c/TESTS.md | 994 +++++++++++++++------ test/w3c/confLua.xsl | 2 +- test/w3c/create-test-table.pl | 3 +- test/w3c/lua/test488.scxml | 2 +- 46 files changed, 1223 insertions(+), 633 deletions(-) diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp index 8ab5524..e8d8305 100644 --- a/apps/uscxml-browser.cpp +++ b/apps/uscxml-browser.cpp @@ -21,13 +21,6 @@ int main(int argc, char** argv) { InterpreterOptions options = InterpreterOptions::fromCmdLine(argc, argv); - if (options.pluginPath.length() > 0) { - Factory::setDefaultPluginPath(options.pluginPath); - } - - if (options.verbose) { - Factory::getInstance()->listComponents(); - } if (!options) { InterpreterOptions::printUsageAndExit(argv[0]); } @@ -49,6 +42,14 @@ int main(int argc, char** argv) { } HTTPServer::getInstance(options.httpPort, options.wsPort, sslConf); + if (options.pluginPath.length() > 0) { + Factory::setDefaultPluginPath(options.pluginPath); + } + + if (options.verbose) { + Factory::getInstance()->listComponents(); + } + // instantiate and configure interpreters std::list interpreters; for(int i = 0; i < options.interpreters.size(); i++) { diff --git a/src/bindings/swig/wrapped/WrappedDataModel.h b/src/bindings/swig/wrapped/WrappedDataModel.h index 1fefcbe..de0c4a9 100644 --- a/src/bindings/swig/wrapped/WrappedDataModel.h +++ b/src/bindings/swig/wrapped/WrappedDataModel.h @@ -82,16 +82,16 @@ public: return true; } - virtual void assign(const std::string& location, const Data& data) {} - virtual void init(const std::string& location, const Data& data) {} + virtual void assign(const std::string& location, + const Data& data, + const std::map& attr) {} + virtual void init(const std::string& location, + const Data& data, + const std::map& attr) {} virtual void addExtension(DataModelExtension* ext) { } - virtual std::string andExpressions(std::list) { - return ""; - } - protected: DataModelCallbacks* callbacks; }; diff --git a/src/bindings/swig/wrapped/WrappedIOProcessor.cpp b/src/bindings/swig/wrapped/WrappedIOProcessor.cpp index 6c96840..741e88d 100644 --- a/src/bindings/swig/wrapped/WrappedIOProcessor.cpp +++ b/src/bindings/swig/wrapped/WrappedIOProcessor.cpp @@ -21,8 +21,8 @@ namespace uscxml { -WrappedIOProcessor::WrappedIOProcessor(InterpreterImpl* interpreter) { - _interpreter = interpreter; +WrappedIOProcessor::WrappedIOProcessor(IOProcessorCallbacks* callbacks) { + _callbacks = callbacks; } WrappedIOProcessor::~WrappedIOProcessor() {} diff --git a/src/bindings/swig/wrapped/WrappedIOProcessor.h b/src/bindings/swig/wrapped/WrappedIOProcessor.h index f1820a4..98774b2 100644 --- a/src/bindings/swig/wrapped/WrappedIOProcessor.h +++ b/src/bindings/swig/wrapped/WrappedIOProcessor.h @@ -36,15 +36,15 @@ namespace uscxml { class WrappedIOProcessor : public IOProcessorImpl { public: - WrappedIOProcessor(InterpreterImpl* interpreter); + WrappedIOProcessor(IOProcessorCallbacks* callbacks); virtual ~WrappedIOProcessor(); virtual std::list getNames() { return std::list(); }; - virtual std::shared_ptr create(InterpreterImpl* interpreter) { - std::shared_ptr ioProc = std::shared_ptr(new WrappedIOProcessor(interpreter)); + virtual std::shared_ptr create(IOProcessorCallbacks* callbacks) { + std::shared_ptr ioProc = std::shared_ptr(new WrappedIOProcessor(callbacks)); return ioProc; } diff --git a/src/uscxml/interpreter/BasicContentExecutor.cpp b/src/uscxml/interpreter/BasicContentExecutor.cpp index bbd6bca..192e714 100644 --- a/src/uscxml/interpreter/BasicContentExecutor.cpp +++ b/src/uscxml/interpreter/BasicContentExecutor.cpp @@ -118,7 +118,7 @@ void BasicContentExecutor::processSend(XERCESC_NS::DOMElement* element) { */ sendEvent.sendid = ATTR(getParentState(element), "id") + "." + UUID::getUUID(); if (HAS_ATTR(element, "idlocation")) { - _callbacks->assign(ATTR(element, "idlocation"), Data(sendEvent.sendid, Data::VERBATIM)); + _callbacks->assign(ATTR(element, "idlocation"), Data(sendEvent.sendid, Data::VERBATIM), std::map()); } else { sendEvent.hideSendId = true; } @@ -242,7 +242,16 @@ void BasicContentExecutor::processIf(XERCESC_NS::DOMElement* content) { void BasicContentExecutor::processAssign(XERCESC_NS::DOMElement* content) { std::string location = ATTR(content, "location"); - _callbacks->assign(location, elementAsData(content)); + + std::map additionalAttr; + auto xmlAttrs = content->getAttributes(); + size_t nrAttrs = xmlAttrs->getLength(); + for (size_t i = 0; i < nrAttrs; i++) { + auto attr = xmlAttrs->item(i); + additionalAttr[X(attr->getNodeName()).str()] = X(attr->getNodeValue()).str(); + } + + _callbacks->assign(location, elementAsData(content, true), additionalAttr); } void BasicContentExecutor::processForeach(XERCESC_NS::DOMElement* content) { @@ -321,10 +330,10 @@ void BasicContentExecutor::process(XERCESC_NS::DOMElement* block, const X& xmlPr for (std::list::iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) { if (event.namelist.find(*nameIter) != event.namelist.end()) { // scxml i/o proc keeps a dedicated namelist - _callbacks->assign(*nameIter, event.namelist.at(*nameIter)); + _callbacks->assign(*nameIter, event.namelist.at(*nameIter), std::map()); } else if (event.data.compound.find(*nameIter) != event.data.compound.end()) { // this is where it would end up with non scxml i/o processors - _callbacks->assign(*nameIter, event.data.compound.at(*nameIter)); + _callbacks->assign(*nameIter, event.data.compound.at(*nameIter), std::map()); } } } @@ -405,7 +414,7 @@ void BasicContentExecutor::invoke(XERCESC_NS::DOMElement* element) { } else { invokeEvent.invokeid = ATTR(getParentState(element), "id") + "." + UUID::getUUID(); if (HAS_ATTR(element, "idlocation")) { - _callbacks->assign(ATTR(element, "idlocation"), Data(invokeEvent.invokeid, Data::VERBATIM)); + _callbacks->assign(ATTR(element, "idlocation"), Data(invokeEvent.invokeid, Data::VERBATIM), std::map()); } } @@ -684,12 +693,10 @@ Data BasicContentExecutor::elementAsData(XERCESC_NS::DOMElement* element, bool a if (asExpression) // not actually used, but likely expected return Data(contentSS.str(), Data::INTERPRETED); - // test153 - try { - Data d = _callbacks->getAsData(contentSS.str()); - if (!d.empty()) - return d; - } catch(...) {} + // test153, we need to throw for test150 in promela + Data d = _callbacks->getAsData(contentSS.str()); + if (!d.empty()) + return d; // never actually occurs with the w3c tests return Data(spaceNormalize(contentSS.str()), Data::VERBATIM); diff --git a/src/uscxml/interpreter/BasicDelayedEventQueue.cpp b/src/uscxml/interpreter/BasicDelayedEventQueue.cpp index 3521dc6..74ab757 100644 --- a/src/uscxml/interpreter/BasicDelayedEventQueue.cpp +++ b/src/uscxml/interpreter/BasicDelayedEventQueue.cpp @@ -69,14 +69,22 @@ std::shared_ptr BasicDelayedEventQueue::create(DelayedEve void BasicDelayedEventQueue::timerCallback(evutil_socket_t fd, short what, void *arg) { struct callbackData *data = (struct callbackData*)arg; - std::lock_guard lock(data->eventQueue->_mutex); + { + std::lock_guard lock(data->eventQueue->_mutex); - if (data->eventQueue->_callbackData.find(data->eventUUID) == data->eventQueue->_callbackData.end()) - return; + if (data->eventQueue->_callbackData.find(data->eventUUID) == data->eventQueue->_callbackData.end()) + return; + + event_free(data->event); + } - event_free(data->event); + // we cannot hold the mutex as this may trigger a delayed send data->eventQueue->_callbacks->eventReady(data->userData, data->eventUUID); - data->eventQueue->_callbackData.erase(data->eventUUID); + + { + std::lock_guard lock(data->eventQueue->_mutex); + data->eventQueue->_callbackData.erase(data->eventUUID); + } } void BasicDelayedEventQueue::enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { diff --git a/src/uscxml/interpreter/ContentExecutorImpl.h b/src/uscxml/interpreter/ContentExecutorImpl.h index 278cbb9..e8c89f9 100644 --- a/src/uscxml/interpreter/ContentExecutorImpl.h +++ b/src/uscxml/interpreter/ContentExecutorImpl.h @@ -28,6 +28,7 @@ #include #include +#include namespace XERCESC_NS { class DOMDocument; @@ -59,7 +60,7 @@ public: virtual Data evalAsData(const std::string& expr) = 0; virtual Data getAsData(const std::string& expr) = 0; - virtual void assign(const std::string& location, const Data& data) = 0; + virtual void assign(const std::string& location, const Data& data, const std::map& attrs) = 0; virtual std::string getInvokeId() = 0; diff --git a/src/uscxml/interpreter/InterpreterImpl.cpp b/src/uscxml/interpreter/InterpreterImpl.cpp index 60ce29d..33a1169 100644 --- a/src/uscxml/interpreter/InterpreterImpl.cpp +++ b/src/uscxml/interpreter/InterpreterImpl.cpp @@ -388,18 +388,26 @@ void InterpreterImpl::init() { void InterpreterImpl::initData(XERCESC_NS::DOMElement* root) { std::string id = ATTR(root, "id"); Data d; + + std::map additionalAttr; + auto xmlAttrs = root->getAttributes(); + size_t nrAttrs = xmlAttrs->getLength(); + for (size_t i = 0; i < nrAttrs; i++) { + auto attr = xmlAttrs->item(i); + additionalAttr[X(attr->getNodeName()).str()] = X(attr->getNodeValue()).str(); + } + try { if (Event::getParam(_invokeReq.params, id, d)) { - _dataModel.init(id, d); + _dataModel.init(id, d, additionalAttr); } else if (_invokeReq.namelist.find(id) != _invokeReq.namelist.end()) { - _dataModel.init(id, _invokeReq.namelist[id]); + _dataModel.init(id, _invokeReq.namelist[id], additionalAttr); } else { try { - _dataModel.init(id, _execContent.elementAsData(root)); + _dataModel.init(id, _execContent.elementAsData(root), additionalAttr); } catch (ErrorEvent e) { // test 453 - _dataModel.init(id, _execContent.elementAsData(root, true)); - + _dataModel.init(id, _execContent.elementAsData(root, true), additionalAttr); } } } catch(ErrorEvent e) { @@ -408,8 +416,8 @@ void InterpreterImpl::initData(XERCESC_NS::DOMElement* root) { } } -void InterpreterImpl::assign(const std::string& location, const Data& data) { - _dataModel.assign(location, data); +void InterpreterImpl::assign(const std::string& location, const Data& data, const std::map& attrs) { + _dataModel.assign(location, data, attrs); } bool InterpreterImpl::isMatched(const Event& event, const std::string& eventDesc) { @@ -556,4 +564,29 @@ void InterpreterImpl::uninvoke(const std::string& invokeId) { } +void InterpreterImpl::enqueueAtInvoker(const std::string& invokeId, const Event& event) { + if (_invokers.find(invokeId) != _invokers.end()) { + std::lock_guard lock(_instanceMutex); + try { + _invokers[invokeId].eventFromSCXML(event); + } catch (const std::exception &e) { + ERROR_COMMUNICATION_THROW("Exception caught while sending event to invoker '" + invokeId + "': " + e.what()); + } catch(...) { + ERROR_COMMUNICATION_THROW("Exception caught while sending event to invoker '" + invokeId + "'"); + } + } else { + ERROR_COMMUNICATION_THROW("Can not send to invoked component '" + invokeId + "', no such invokeId"); + } + +} + +void InterpreterImpl::enqueueAtParent(const Event& event) { + if (_parentQueue) { + _parentQueue.enqueue(event); + } else { + ERROR_COMMUNICATION_THROW("Sending to parent invoker, but none is set"); + } + +} + } diff --git a/src/uscxml/interpreter/InterpreterImpl.h b/src/uscxml/interpreter/InterpreterImpl.h index 2b12624..bd3898c 100644 --- a/src/uscxml/interpreter/InterpreterImpl.h +++ b/src/uscxml/interpreter/InterpreterImpl.h @@ -31,6 +31,7 @@ #include "uscxml/util/URL.h" #include "uscxml/plugins/Factory.h" #include "uscxml/plugins/DataModelImpl.h" +#include "uscxml/plugins/IOProcessorImpl.h" #include "uscxml/interpreter/MicroStepImpl.h" #include "uscxml/interpreter/ContentExecutorImpl.h" #include "uscxml/interpreter/EventQueue.h" @@ -49,6 +50,7 @@ class InterpreterIssue; class USCXML_API InterpreterImpl : public MicroStepCallbacks, public DataModelCallbacks, + public IOProcessorCallbacks, public ContentExecutorCallbacks, public DelayedEventQueueCallbacks, public std::enable_shared_from_this { @@ -187,7 +189,7 @@ public: return _dataModel.getAsData(expr); } - virtual void assign(const std::string& location, const Data& data); + virtual void assign(const std::string& location, const Data& data, const std::map& attrs); virtual std::string getInvokeId() { return _invokeId; @@ -206,6 +208,12 @@ public: } /** + IOProcessorCallbacks + */ + virtual void enqueueAtInvoker(const std::string& invokeId, const Event& event); + virtual void enqueueAtParent(const Event& event); + + /** DelayedEventQueueCallbacks */ diff --git a/src/uscxml/messages/Data.cpp b/src/uscxml/messages/Data.cpp index 277b7d8..6c48c46 100644 --- a/src/uscxml/messages/Data.cpp +++ b/src/uscxml/messages/Data.cpp @@ -350,8 +350,8 @@ std::string Data::jsonEscape(const std::string& expr) { os << "\\n"; } else if (expr[i] == '\r') { os << "\\r"; - } else if (expr[i] == '\'') { - os << "\\'"; +// } else if (expr[i] == '\'') { +// os << "\\\'"; } else if (expr[i] == '\"') { os << "\\\""; } else if (expr[i] == '\\') { diff --git a/src/uscxml/messages/Data.h b/src/uscxml/messages/Data.h index 19134dd..b279696 100644 --- a/src/uscxml/messages/Data.h +++ b/src/uscxml/messages/Data.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "uscxml/Common.h" #include "uscxml/util/Convenience.h" @@ -49,27 +50,27 @@ public: Data() : node(NULL), type(INTERPRETED) {} - Data(const char* data, size_t size, const std::string& mimeType, bool adopt = false); + explicit Data(const char* data, size_t size, const std::string& mimeType, bool adopt = false); // convenience constructors - Data(bool atom) : node(NULL), type(VERBATIM) { - if (atom) { - this->atom = "true"; - } else { - this->atom = "false"; - } - } +// explicit Data(bool atom) : node(NULL), type(VERBATIM) { +// if (atom) { +// this->atom = "true"; +// } else { +// this->atom = "false"; +// } +// } explicit Data(XERCESC_NS::DOMNode* node_) : node(node_) {} - // template Data(T value, Type type = INTERPRETED) : atom(toStr(value)), type(type) {} - // we will have to drop this constructor as it interferes with operator Data() and requires C++11 - template - explicit Data(T value, typename std::enable_if::value>::type* = nullptr) - : node(NULL), atom(toStr(value)), type(VERBATIM) {} + explicit Data(const std::string& value) : node(NULL), atom(toStr(value)), type(VERBATIM) {} + + template ::value, T>::type> + explicit Data(T value) + : node(NULL), atom(toStr(value)), type(INTERPRETED) {} + template - explicit Data(T value, Type type, typename std::enable_if::value>::type* = nullptr) - : node(NULL), atom(toStr(value)), type(type) {} + explicit Data(T value, Type type) : node(NULL), atom(toStr(value)), type(type) {} ~Data() { } @@ -170,11 +171,11 @@ public: } bool operator==(const Data &other) const { - return (*this < other || other < *this); + return !(*this != other); } bool operator!=(const Data &other) const { - return !(*this == other); + return (*this < other || other < *this); } operator std::string() const { diff --git a/src/uscxml/plugins/DataModel.cpp b/src/uscxml/plugins/DataModel.cpp index 96afd89..07fd4b4 100644 --- a/src/uscxml/plugins/DataModel.cpp +++ b/src/uscxml/plugins/DataModel.cpp @@ -57,12 +57,12 @@ void DataModel::setForeach(const std::string& item, return _impl->setForeach(item, array, index, iteration); } -void DataModel::assign(const std::string& location, const Data& data) { - return _impl->assign(location, data); +void DataModel::assign(const std::string& location, const Data& data, const std::map& attr) { + return _impl->assign(location, data, attr); } -void DataModel::init(const std::string& location, const Data& data) { - return _impl->init(location, data); +void DataModel::init(const std::string& location, const Data& data, const std::map& attr) { + return _impl->init(location, data, attr); } bool DataModel::isDeclared(const std::string& expr) { @@ -73,10 +73,6 @@ size_t DataModel::replaceExpressions(std::string& content) { return _impl->replaceExpressions(content); } -std::string DataModel::andExpressions(std::list expressions) { - return _impl->andExpressions(expressions); -} - void DataModel::addExtension(DataModelExtension* ext) { return _impl->addExtension(ext); } diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h index 7716ad7..9185cc8 100644 --- a/src/uscxml/plugins/DataModel.h +++ b/src/uscxml/plugins/DataModel.h @@ -66,17 +66,19 @@ public: uint32_t iteration); /// @copydoc DataModelImpl::assign() - virtual void assign(const std::string& location, const Data& data); + virtual void assign(const std::string& location, + const Data& data, + const std::map& attr = std::map()); /// @copydoc DataModelImpl::init() - virtual void init(const std::string& location, const Data& data); + virtual void init(const std::string& location, + const Data& data, + const std::map& attr = std::map()); /// @copydoc DataModelImpl::isDeclared() virtual bool isDeclared(const std::string& expr); /// @copydoc DataModelImpl::replaceExpressions() size_t replaceExpressions(std::string& content); - /// @copydoc DataModelImpl::andExpressions() - std::string andExpressions(std::list expressions); /// @copydoc DataModelImpl::addExtension() virtual void addExtension(DataModelExtension* ext); diff --git a/src/uscxml/plugins/DataModelImpl.h b/src/uscxml/plugins/DataModelImpl.h index e93361d..b1fbd88 100644 --- a/src/uscxml/plugins/DataModelImpl.h +++ b/src/uscxml/plugins/DataModelImpl.h @@ -182,8 +182,11 @@ public: \endverbatim * @param location A variable or locatio to assign to. * @param data The Data object with the respective data. + * @param attr Additional attributes of the XML assign element. */ - virtual void assign(const std::string& location, const Data& data) = 0; + virtual void assign(const std::string& location, + const Data& data, + const std::map& attr = std::map()) = 0; /** * Initialize a variable / location in the data-model with a given data object. @@ -192,8 +195,11 @@ public: * * @param location A variable or locatio to assign to. * @param data The Data object with the respective data. + * @param attr Additional attributes of the XML data element. */ - virtual void init(const std::string& location, const Data& data) = 0; + virtual void init(const std::string& location, + const Data& data, + const std::map& attr = std::map()) = 0; /** * Register an extension to get data into and out of the data-model. @@ -201,15 +207,6 @@ public: */ virtual void addExtension(DataModelExtension* ext); - /** - * Concat the given terms into a conjunctive form. - * @todo This is required to automatically transform a state-chart into a - * state-machine. Actual transformation is still only available in legacy though. - */ - virtual std::string andExpressions(std::list) { - return ""; - } - protected: DataModelCallbacks* _callbacks; }; diff --git a/src/uscxml/plugins/EventHandler.h b/src/uscxml/plugins/EventHandler.h index 436f878..5122e9b 100644 --- a/src/uscxml/plugins/EventHandler.h +++ b/src/uscxml/plugins/EventHandler.h @@ -53,9 +53,6 @@ public: * @return An object to be represented at `_x['name']` */ virtual Data getDataModelVariables() = 0; - -protected: - InterpreterImpl* _interpreter; }; /** diff --git a/src/uscxml/plugins/Factory.cpp b/src/uscxml/plugins/Factory.cpp index 443cb59..60e7a3e 100644 --- a/src/uscxml/plugins/Factory.cpp +++ b/src/uscxml/plugins/Factory.cpp @@ -106,7 +106,6 @@ void Factory::registerPlugins() { } #endif - #ifdef WITH_DM_ECMA_V8 { V8DataModel* dataModel = new V8DataModel(); @@ -352,12 +351,12 @@ bool Factory::hasIOProcessor(const std::string& type) { return false; } -std::shared_ptr Factory::createIOProcessor(const std::string& type, InterpreterImpl* interpreter) { +std::shared_ptr Factory::createIOProcessor(const std::string& type, IOProcessorCallbacks* callbacks) { // do we have this type ourself? if (_ioProcessorAliases.find(type) != _ioProcessorAliases.end()) { std::string canonicalName = _ioProcessorAliases[type]; if (_ioProcessors.find(canonicalName) != _ioProcessors.end()) { - std::shared_ptr ioProc = _ioProcessors[canonicalName]->create(interpreter); + std::shared_ptr ioProc = _ioProcessors[canonicalName]->create(callbacks); // ioProc->setInterpreter(interpreter); return ioProc; } @@ -365,7 +364,7 @@ std::shared_ptr Factory::createIOProcessor(const std::string& t // lookup in parent factory if (_parentFactory) { - return _parentFactory->createIOProcessor(type, interpreter); + return _parentFactory->createIOProcessor(type, callbacks); } else { ERROR_EXECUTION_THROW("No IOProcessor named '" + type + "' known"); } @@ -497,9 +496,9 @@ void IOProcessorImpl::eventToSCXML(Event& event, event.origintype = type; if (internal) { - _interpreter->enqueueInternal(event); + _callbacks->enqueueInternal(event); } else { - _interpreter->enqueueExternal(event); + _callbacks->enqueueExternal(event); } } @@ -517,9 +516,9 @@ void InvokerImpl::eventToSCXML(Event& event, event.origintype = type; if (internal) { - _interpreter->enqueueInternal(event); + _callbacks->enqueueInternal(event); } else { - _interpreter->enqueueExternal(event); + _callbacks->enqueueExternal(event); } } diff --git a/src/uscxml/plugins/Factory.h b/src/uscxml/plugins/Factory.h index f80b581..9653107 100644 --- a/src/uscxml/plugins/Factory.h +++ b/src/uscxml/plugins/Factory.h @@ -25,6 +25,7 @@ #include "uscxml/plugins/ExecutableContent.h" #include "uscxml/plugins/EventHandler.h" #include "uscxml/plugins/IOProcessor.h" +#include "uscxml/plugins/IOProcessorImpl.h" #include "uscxml/plugins/Invoker.h" #include "uscxml/plugins/DataModelImpl.h" @@ -53,7 +54,7 @@ public: void registerExecutableContent(ExecutableContentImpl* executableContent); std::shared_ptr createDataModel(const std::string& type, DataModelCallbacks* callbacks); - std::shared_ptr createIOProcessor(const std::string& type, InterpreterImpl* interpreter); + std::shared_ptr createIOProcessor(const std::string& type, IOProcessorCallbacks* callbacks); std::shared_ptr createInvoker(const std::string& type, InterpreterImpl* interpreter); std::shared_ptr createExecutableContent(const std::string& localName, const std::string& nameSpace, InterpreterImpl* interpreter); diff --git a/src/uscxml/plugins/IOProcessorImpl.h b/src/uscxml/plugins/IOProcessorImpl.h index bd28406..24d2631 100644 --- a/src/uscxml/plugins/IOProcessorImpl.h +++ b/src/uscxml/plugins/IOProcessorImpl.h @@ -23,13 +23,31 @@ #include "uscxml/Common.h" #include "uscxml/plugins/EventHandler.h" +#include "uscxml/interpreter/Logging.h" #include "uscxml/messages/Event.h" -#include "uscxml/interpreter/InterpreterImpl.h" namespace uscxml { /** * @ingroup ioproc + * @ingroup callback + * Callbacks available for every IO processor. + */ +class USCXML_API IOProcessorCallbacks { +public: + virtual ~IOProcessorCallbacks() {} ///< silence virtual destructor warning from swig + virtual const std::string& getName() = 0; + virtual const std::string& getSessionId() = 0; + virtual void enqueueInternal(const Event& event) = 0; + virtual void enqueueExternal(const Event& event) = 0; + virtual void enqueueAtInvoker(const std::string& invokeId, const Event& event) = 0; + virtual void enqueueAtParent(const Event& event) = 0; + virtual Logger getLogger() = 0; + +}; + +/** + * @ingroup ioproc * @ingroup abstract * Abstract base class for IOProcessor%s implementations. */ @@ -41,7 +59,7 @@ public: * @param interpreter The imlementation of the associated Interpreter * @todo We will eventually introduce callbacks and prevent complete access to the interpreter. */ - virtual std::shared_ptr create(InterpreterImpl* interpreter) = 0; + virtual std::shared_ptr create(IOProcessorCallbacks* callbacks) = 0; /** * We received an event from the SCXML Interpreter we are associated with. @@ -67,6 +85,7 @@ protected: */ void eventToSCXML(Event& event, const std::string& type, const std::string& origin, bool internal = false); + IOProcessorCallbacks* _callbacks; }; } diff --git a/src/uscxml/plugins/InvokerImpl.h b/src/uscxml/plugins/InvokerImpl.h index e0446e1..e5f7366 100644 --- a/src/uscxml/plugins/InvokerImpl.h +++ b/src/uscxml/plugins/InvokerImpl.h @@ -115,7 +115,7 @@ protected: XERCESC_NS::DOMElement* _finalize; std::string _invokeId; - + InterpreterImpl* _callbacks; }; } diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 22e8ccc..bcde9c9 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -420,7 +420,12 @@ Data JSCDataModel::getAsData(const std::string& content) { (trimmed[0] == '\'' && trimmed[trimmed.length() - 1] == '\''))) { d = Data(trimmed.substr(1, trimmed.length() - 2), Data::VERBATIM); } else { - d = Data(trimmed, Data::INTERPRETED); + // test558, test562 + ERROR_EXECUTION(e, "Given content cannot be interpreted as data"); + e.data.compound["literal"] = Data(trimmed, Data::VERBATIM); + throw e; + +// d = Data(trimmed, Data::INTERPRETED); } } return d; @@ -684,7 +689,7 @@ JSValueRef JSCDataModel::getNodeAsValue(const DOMNode* node) { // } } -void JSCDataModel::assign(const std::string& location, const Data& data) { +void JSCDataModel::assign(const std::string& location, const Data& data, const std::map& attr) { // flags on attribute are ignored? if (location.compare("_sessionid") == 0) // test 322 @@ -714,7 +719,7 @@ void JSCDataModel::assign(const std::string& location, const Data& data) { handleException(exception); } -void JSCDataModel::init(const std::string& location, const Data& data) { +void JSCDataModel::init(const std::string& location, const Data& data, const std::map& attr) { try { if (data.empty()) { assign(location, Data("null", Data::INTERPRETED)); @@ -728,26 +733,6 @@ void JSCDataModel::init(const std::string& location, const Data& data) { } } -std::string JSCDataModel::andExpressions(std::list expressions) { - if (expressions.size() == 0) - return ""; - - if (expressions.size() == 1) - return *(expressions.begin()); - - std::ostringstream exprSS; - exprSS << "("; - std::string conjunction = ""; - for (std::list::const_iterator exprIter = expressions.begin(); - exprIter != expressions.end(); - exprIter++) { - exprSS << conjunction << "(" << *exprIter << ")"; - conjunction = " && "; - } - exprSS << ")"; - return exprSS.str(); -} - void JSCDataModel::handleException(JSValueRef exception) { JSStringRef exceptionStringRef = JSValueToStringCopy(_ctx, exception, NULL); size_t maxSize = JSStringGetMaximumUTF8CStringSize(exceptionStringRef); diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h index c5129a4..3a53da2 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h @@ -80,10 +80,12 @@ public: virtual bool isDeclared(const std::string& expr); - virtual void assign(const std::string& location, const Data& data); - virtual void init(const std::string& location, const Data& data); - - virtual std::string andExpressions(std::list); + virtual void assign(const std::string& location, + const Data& data, + const std::map& attr = std::map()); + virtual void init(const std::string& location, + const Data& data, + const std::map& attr = std::map()); protected: diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index 283372d..61eb815 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -408,7 +408,7 @@ void V8DataModel::setEvent(const Event& event) { } } if (!data.empty()) { -// std::cout << Data::toJSON(eventCopy.data); +// std::cout << Data::toJSON(data); eventObj->Set(v8::String::NewSymbol("data"), getDataAsValue(data)); // set data part of _event } else { // test 343 / test 488 @@ -436,7 +436,10 @@ Data V8DataModel::getAsData(const std::string& content) { (trimmed[0] == '\'' && trimmed[trimmed.length() - 1] == '\''))) { d = Data(trimmed.substr(1, trimmed.length() - 2), Data::VERBATIM); } else { - d = Data(trimmed, Data::INTERPRETED); + // test558, test562 + ERROR_EXECUTION(e, "Given content cannot be interpreted as data"); + e.data.compound["literal"] = Data(trimmed, Data::VERBATIM); + throw e; } } return d; @@ -631,12 +634,22 @@ void V8DataModel::jsIn(const v8::FunctionCallbackInfo& info) { } bool V8DataModel::isValidSyntax(const std::string& expr) { + v8::Locker locker(_isolate); + v8::Isolate::Scope isoScope(_isolate); + v8::HandleScope scope(_isolate); + + v8::Local ctx = v8::Local::New(_isolate, _context); + v8::Context::Scope contextScope(ctx); // segfaults at newinstance without! + v8::TryCatch tryCatch; v8::Local source = v8::String::New(expr.c_str()); - v8::Local script = v8::Script::Compile(source); + if (tryCatch.HasCaught() || source.IsEmpty()) { + return false; + } - if (script.IsEmpty() || tryCatch.HasCaught()) { + v8::Local script = v8::Script::Compile(source); + if (tryCatch.HasCaught() || script.IsEmpty()) { return false; } @@ -726,7 +739,7 @@ bool V8DataModel::evalAsBool(const std::string& expr) { } -void V8DataModel::assign(const std::string& location, const Data& data) { +void V8DataModel::assign(const std::string& location, const Data& data, const std::map& attr) { v8::Locker locker(_isolate); v8::Isolate::Scope isoScope(_isolate); @@ -754,8 +767,7 @@ void V8DataModel::assign(const std::string& location, const Data& data) { } } -void V8DataModel::init(const std::string& location, - const Data& data) { +void V8DataModel::init(const std::string& location, const Data& data, const std::map& attr) { v8::Locker locker(_isolate); v8::Isolate::Scope isoScope(_isolate); v8::HandleScope scope(_isolate); @@ -774,26 +786,6 @@ void V8DataModel::init(const std::string& location, } } -std::string V8DataModel::andExpressions(std::list expressions) { - if (expressions.size() == 0) - return ""; - - if (expressions.size() == 1) - return *(expressions.begin()); - - std::ostringstream exprSS; - exprSS << "("; - std::string conjunction = ""; - for (std::list::const_iterator exprIter = expressions.begin(); - exprIter != expressions.end(); - exprIter++) { - exprSS << conjunction << "(" << *exprIter << ")"; - conjunction = " && "; - } - exprSS << ")"; - return exprSS.str(); -} - v8::Local V8DataModel::evalAsValue(const std::string& expr, bool dontThrow) { // v8::Locker locker(_isolate); diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h index 3b4d776..a9dbca1 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h @@ -73,10 +73,12 @@ public: virtual bool isDeclared(const std::string& expr); - virtual void assign(const std::string& location, const Data& data); - virtual void init(const std::string& location, const Data& data); - - virtual std::string andExpressions(std::list); + virtual void assign(const std::string& location, + const Data& data, + const std::map& attr = std::map()); + virtual void init(const std::string& location, + const Data& data, + const std::map& attr = std::map()); protected: diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index 2ad89b5..ad35f80 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -349,9 +349,12 @@ Data LuaDataModel::evalAsData(const std::string& content) { throw originalError; // we will assume syntax error and throw } - if (retVals == 0) +#if 1 + // Note: Empty result is not an error test302, but how to do test488? + if (retVals == 0 && !isValidSyntax(trimmedExpr)) { throw originalError; // we will assume syntax error and throw - + } +#endif try { if (retVals == 1) { @@ -446,7 +449,7 @@ bool LuaDataModel::isDeclared(const std::string& expr) { } -void LuaDataModel::assign(const std::string& location, const Data& data) { +void LuaDataModel::assign(const std::string& location, const Data& data, const std::map& attr) { if (location.length() == 0) { ERROR_EXECUTION_THROW("Assign element has neither id nor location"); } @@ -539,7 +542,7 @@ void LuaDataModel::assign(const std::string& location, const Data& data) { } } -void LuaDataModel::init(const std::string& location, const Data& data) { +void LuaDataModel::init(const std::string& location, const Data& data, const std::map& attr) { luabridge::setGlobal(_luaState, luabridge::Nil(), location.c_str()); assign(location, data); } @@ -582,17 +585,4 @@ Data LuaDataModel::getAsData(const std::string& content) { return data; } - -std::string LuaDataModel::andExpressions(std::list exprs) { - std::stringstream exprSS; - std::list::const_iterator listIter; - std::string andExpr; - for (listIter = exprs.begin(); listIter != exprs.end(); listIter++) { - exprSS << andExpr << *listIter; - andExpr = " && "; - } - return exprSS.str(); -} - - } diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.h b/src/uscxml/plugins/datamodel/lua/LuaDataModel.h index 7b7121f..85d7b53 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.h +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.h @@ -77,10 +77,12 @@ public: virtual bool isDeclared(const std::string& expr); - virtual void assign(const std::string& location, const Data& data); - virtual void init(const std::string& location, const Data& data); - - virtual std::string andExpressions(std::list); + virtual void assign(const std::string& location, + const Data& data, + const std::map& attr = std::map()); + virtual void init(const std::string& location, + const Data& data, + const std::map& attr = std::map()); protected: diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.h b/src/uscxml/plugins/datamodel/null/NULLDataModel.h index 4bea664..fba8577 100644 --- a/src/uscxml/plugins/datamodel/null/NULLDataModel.h +++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.h @@ -90,24 +90,14 @@ public: return true; } - virtual void assign(const XERCESC_NS::DOMElement* assignElem, - const XERCESC_NS::DOMNode* node, - const std::string& content) {} - virtual void assign(const std::string& location, const Data& data) {} - - virtual void init(const XERCESC_NS::DOMElement* dataElem, - const XERCESC_NS::DOMNode* node, - const std::string& content) {} - virtual void init(const std::string& location, const Data& data) {} + virtual void assign(const std::string& location, const Data& data, const std::map& attr) {} + virtual void init(const std::string& location, const Data& data, const std::map& attr) {} virtual void setCallbacks(DataModelCallbacks* callbacks) { _callbacks = callbacks; } virtual void addExtension(DataModelExtension* ext) {} - virtual std::string andExpressions(std::list) { - return ""; - } protected: diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp index a524c7e..14d24c3 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -146,7 +146,7 @@ void PromelaDataModel::setEvent(const Event& event) { start != end; start = event.params.upper_bound(start->first)) { // only set first param key if (isNumeric(start->second.atom.c_str(), 10)) { - variable.compound["value"].compound["data"].compound[start->first] = strTo(start->second.atom); + variable.compound["value"].compound["data"].compound[start->first] = Data(strTo(start->second.atom)); } else { variable.compound["value"].compound["data"].compound[start->first] = start->second; } @@ -154,7 +154,7 @@ void PromelaDataModel::setEvent(const Event& event) { for (Event::namelist_t::const_iterator iter = event.namelist.begin(); iter != event.namelist.end(); iter++) { if (isNumeric(iter->second.atom.c_str(), 10)) { - variable.compound["value"].compound["data"].compound[iter->first] = strTo(iter->second.atom); + variable.compound["value"].compound["data"].compound[iter->first] = Data(strTo(iter->second.atom)); } else { variable.compound["value"].compound["data"].compound[iter->first] = iter->second; } @@ -225,11 +225,25 @@ void PromelaDataModel::setEvent(const Event& event) { PromelaParser arrayParser(ss.str(), 1, PromelaParser::PROMELA_EXPR); - setVariable(itemParser.ast, getVariable(arrayParser.ast)); + try { + setVariable(itemParser.ast, getVariable(arrayParser.ast)); + } catch (ErrorEvent e) { + // test150 + PromelaParser itemDeclParser("int " + item); // this is likely the wrong type + evaluateDecl(itemDeclParser.ast); + setVariable(itemParser.ast, getVariable(arrayParser.ast)); + } if (index.length() > 0) { PromelaParser indexParser(index, 1, PromelaParser::PROMELA_EXPR); - setVariable(indexParser.ast, iteration); + try { + setVariable(indexParser.ast, Data(iteration)); + } catch (ErrorEvent e) { + // test150 + PromelaParser indexDeclParser("int " + index); + evaluateDecl(indexDeclParser.ast); + setVariable(indexParser.ast, Data(iteration)); + } } } @@ -322,7 +336,7 @@ void PromelaDataModel::setEvent(const Event& event) { PromelaParserNode* name = *opIterAsgn++; int size = dataToInt(evaluateExpr(*opIterAsgn++)); - variable.compound["size"] = size; + variable.compound["size"] = Data(size); for (size_t i = 0; i < size; i++) { variable.compound["value"].array.push_back(Data(0, Data::INTERPRETED)); } @@ -385,7 +399,7 @@ void PromelaDataModel::setEvent(const Event& event) { return Data(false); if (iequals(node->value, "true")) return Data(true); - return strTo(node->value); + return Data(strTo(node->value)); case PML_NAME: case PML_VAR_ARRAY: case PML_CMPND: @@ -396,13 +410,13 @@ void PromelaDataModel::setEvent(const Event& event) { // return Data(node->value, Data::INTERPRETED); } case PML_PLUS: - return dataToInt(evaluateExpr(*opIter++)) + dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) + dataToInt(evaluateExpr(*opIter++))); case PML_MINUS: - return dataToInt(evaluateExpr(*opIter++)) - dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) - dataToInt(evaluateExpr(*opIter++))); case PML_DIVIDE: - return dataToInt(evaluateExpr(*opIter++)) / dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) / dataToInt(evaluateExpr(*opIter++))); case PML_MODULO: - return dataToInt(evaluateExpr(*opIter++)) % dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) % dataToInt(evaluateExpr(*opIter++))); case PML_EQ: { PromelaParserNode* lhs = *opIter++; PromelaParserNode* rhs = *opIter++; @@ -418,24 +432,24 @@ void PromelaDataModel::setEvent(const Event& event) { || (left.type == Data::VERBATIM && right.type == Data::VERBATIM)) { return (left.atom.compare(right.atom) == 0 ? Data(true) : Data(false)); } - return dataToInt(left) == dataToInt(right); + return Data(dataToInt(left) == dataToInt(right)); } case PML_NEG: - return !dataToBool(evaluateExpr(*opIter++)); + return Data(!dataToBool(evaluateExpr(*opIter++))); case PML_LT: - return dataToInt(evaluateExpr(*opIter++)) < dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) < dataToInt(evaluateExpr(*opIter++))); case PML_LE: - return dataToInt(evaluateExpr(*opIter++)) <= dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) <= dataToInt(evaluateExpr(*opIter++))); case PML_GT: - return dataToInt(evaluateExpr(*opIter++)) > dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) > dataToInt(evaluateExpr(*opIter++))); case PML_GE: - return dataToInt(evaluateExpr(*opIter++)) >= dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) >= dataToInt(evaluateExpr(*opIter++))); case PML_TIMES: - return dataToInt(evaluateExpr(*opIter++)) * dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) * dataToInt(evaluateExpr(*opIter++))); case PML_LSHIFT: - return dataToInt(evaluateExpr(*opIter++)) << dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) << dataToInt(evaluateExpr(*opIter++))); case PML_RSHIFT: - return dataToInt(evaluateExpr(*opIter++)) >> dataToInt(evaluateExpr(*opIter++)); + return Data(dataToInt(evaluateExpr(*opIter++)) >> dataToInt(evaluateExpr(*opIter++))); case PML_AND: case PML_OR: { PromelaParserNode* lhs = *opIter++; @@ -452,15 +466,15 @@ void PromelaDataModel::setEvent(const Event& event) { bool truthRight = dataToBool(right); if (node->type == PML_AND) { - return truthLeft && truthRight; + return Data(truthLeft && truthRight); } else { - return truthLeft || truthRight; + return Data(truthLeft || truthRight); } } default: ERROR_EXECUTION_THROW("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); } - return 0; + return Data(0, Data::INTERPRETED); } void PromelaDataModel::evaluateStmnt(void* ast) { @@ -481,12 +495,12 @@ void PromelaDataModel::setEvent(const Event& event) { } case PML_INCR: { PromelaParserNode* name = *opIter++; - setVariable(name, strTo(getVariable(name)) + 1); + setVariable(name, Data(strTo(getVariable(name)) + 1)); break; } case PML_DECR: { PromelaParserNode* name = *opIter++; - setVariable(name, strTo(getVariable(name)) - 1); + setVariable(name, Data(strTo(getVariable(name)) - 1)); break; } default: @@ -503,11 +517,6 @@ void PromelaDataModel::setEvent(const Event& event) { ERROR_EXECUTION_THROW("Cannot assign to " + node->value); } -// if (_variables.compound.find(name->value) == _variables.compound.end()) { -// // declare implicitly / convenience -// evaluateDecl(ast); -// } - switch (node->type) { case PML_VAR_ARRAY: { std::list::iterator opIter = node->operands.begin(); @@ -515,6 +524,10 @@ void PromelaDataModel::setEvent(const Event& event) { PromelaParserNode* name = *opIter++; PromelaParserNode* expr = *opIter++; + if (!_variables.hasKey(name->value)) { + ERROR_EXECUTION_THROW("Variable " + name->value + " is undeclared"); + } + // is the location an array? if (!_variables[name->value].hasKey("size")) { ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); @@ -532,6 +545,10 @@ void PromelaDataModel::setEvent(const Event& event) { } case PML_NAME: { // location is an array, but no array was passed + if (!_variables.hasKey(node->value)) { + ERROR_EXECUTION_THROW("Variable " + node->value + " is undeclared"); + } + if (_variables[node->value].hasKey("size")) { if (value.compound.size() > 0 || value.atom.size() > 0) ERROR_EXECUTION_THROW("Variable " + node->value + " is an array"); @@ -547,6 +564,10 @@ void PromelaDataModel::setEvent(const Event& event) { std::list::iterator opIter = node->operands.begin(); PromelaParserNode* name = *opIter++; + if (!_variables.hasKey(name->value)) { + ERROR_EXECUTION_THROW("Variable " + name->value + " is undeclared"); + } + // location is no array if (_variables[name->value].hasKey("size")) { ERROR_EXECUTION_THROW("Variable " + name->value + " is an array"); @@ -657,38 +678,43 @@ void PromelaDataModel::setEvent(const Event& event) { default: ERROR_EXECUTION_THROW("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); } - return 0; + return Data(0, Data::INTERPRETED); } - std::string PromelaDataModel::andExpressions(std::list expressions) { + void PromelaDataModel::assign(const std::string& location, const Data& data, const std::map& attr) { + PromelaParser parser(location); + if (data.atom.size() > 0 && data.type == Data::INTERPRETED) { + setVariable(parser.ast, evalAsData(data.atom)); + } else { + setVariable(parser.ast, data); + } + } - if (expressions.size() == 0) - return ""; + void PromelaDataModel::init(const std::string& location, const Data& data, const std::map& attr) { + { + std::string type = (attr.find("type") != attr.end() ? attr.at("type") : "auto"); + std::string arrSize; - if (expressions.size() == 1) - return *(expressions.begin()); + size_t bracketPos = type.find("["); + if (bracketPos != std::string::npos) { + arrSize = type.substr(bracketPos, type.length() - bracketPos); + type = type.substr(0, bracketPos); + } - std::ostringstream exprSS; - exprSS << "("; - std::string conjunction = ""; - for (std::list::const_iterator exprIter = expressions.begin(); - exprIter != expressions.end(); - exprIter++) { - exprSS << conjunction << "(" << *exprIter << ")"; - conjunction = " && "; + std::string expr = type + " " + location + arrSize; + PromelaParser parser(expr, 1, PromelaParser::PROMELA_DECL); + evaluateDecl(parser.ast); } - exprSS << ")"; - return exprSS.str(); - } - void PromelaDataModel::assign(const std::string& location, const Data& data) { - // used for e.g. to assign command line parameters and idlocation PromelaParser parser(location); - setVariable(parser.ast, data); - } - - void PromelaDataModel::init(const std::string& location, const Data& data) { - assign(location, data); + if (data.atom.size() > 0 && data.type == Data::INTERPRETED) { + Data d = Data::fromJSON(data); + if (!d.empty()) + setVariable(parser.ast, Data::fromJSON(data)); + setVariable(parser.ast, data); + } else { + setVariable(parser.ast, data); + } } bool PromelaDataModel::isDeclared(const std::string& expr) { diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h index 2c1f58d..4a763ac 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h @@ -60,10 +60,12 @@ public: virtual bool isDeclared(const std::string& expr); - virtual void assign(const std::string& location, const Data& data); - virtual void init(const std::string& location, const Data& data); - - virtual std::string andExpressions(std::list); + virtual void assign(const std::string& location, + const Data& data, + const std::map& attr = std::map()); + virtual void init(const std::string& location, + const Data& data, + const std::map& attr = std::map()); protected: diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.h b/src/uscxml/plugins/datamodel/promela/PromelaParser.h index 51a2111..236233d 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.h @@ -83,7 +83,7 @@ public: PromelaParserNode* ast; Type type; - Event pendingException; + ErrorEvent pendingException; operator bool() const { return ast != NULL; } diff --git a/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp b/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp index d6d0f99..b5d7e8b 100644 --- a/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp +++ b/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp @@ -65,7 +65,7 @@ DirMonInvoker::~DirMonInvoker() { std::shared_ptr DirMonInvoker::create(InterpreterImpl* interpreter) { std::shared_ptr invoker(new DirMonInvoker()); - invoker->_interpreter = interpreter; + invoker->_callbacks = interpreter; return invoker; } @@ -99,7 +99,7 @@ void DirMonInvoker::eventFromSCXML(const Event& event) { void DirMonInvoker::invoke(const std::string& source, const Event& req) { if (req.params.find("dir") == req.params.end()) { - LOG(_interpreter->getLogger(), USCXML_ERROR) << "No dir param given"; + LOG(_callbacks->getLogger(), USCXML_ERROR) << "No dir param given"; return; } @@ -134,10 +134,10 @@ void DirMonInvoker::invoke(const std::string& source, const Event& req) { std::multimap::const_iterator dirIter = req.params.find("dir"); while(dirIter != req.params.upper_bound("dir")) { // this is simplified - Data might be more elaborate than a simple string atom - URL url = URL::resolve(dirIter->second.atom, _interpreter->getBaseURL()); + URL url = URL::resolve(dirIter->second.atom, _callbacks->getBaseURL()); if (!url.isAbsolute()) { - LOG(_interpreter->getLogger(), USCXML_ERROR) << "Given directory '" << dirIter->second << "' cannot be transformed to absolute path"; + LOG(_callbacks->getLogger(), USCXML_ERROR) << "Given directory '" << dirIter->second << "' cannot be transformed to absolute path"; } else { _dir = url.path(); } @@ -145,7 +145,7 @@ void DirMonInvoker::invoke(const std::string& source, const Event& req) { } _watcher = new DirectoryWatch(_dir, _recurse); - _watcher->setLogger(_interpreter->getLogger()); + _watcher->setLogger(_callbacks->getLogger()); _watcher->addMonitor(this); _watcher->updateEntries(true); diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index 0f7cc24..9ac8621 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -134,7 +134,7 @@ void USCXMLInvoker::run(void* instance) { e.eventType = Event::PLATFORM; e.invokeid = INSTANCE->_invokedInterpreter.getImpl()->getInvokeId(); e.name = "done.invoke." + e.invokeid; - INSTANCE->_interpreter->enqueueExternal(e); + INSTANCE->_callbacks->enqueueExternal(e); } INSTANCE->_isActive = false; @@ -142,7 +142,7 @@ void USCXMLInvoker::run(void* instance) { std::shared_ptr USCXMLInvoker::create(InterpreterImpl* interpreter) { std::shared_ptr invoker(new USCXMLInvoker()); - invoker->_interpreter = interpreter; + invoker->_callbacks = interpreter; return invoker; } @@ -163,10 +163,10 @@ void USCXMLInvoker::invoke(const std::string& source, const Event& invokeEvent) document->appendChild(newNode); // TODO: where do we get the namespace from? - _invokedInterpreter = Interpreter::fromDocument(document, _interpreter->getBaseURL(), false); + _invokedInterpreter = Interpreter::fromDocument(document, _callbacks->getBaseURL(), false); } else if (invokeEvent.data.atom.size() > 0) { // test530 when deserializing - _invokedInterpreter = Interpreter::fromXML(invokeEvent.data.atom, _interpreter->getBaseURL()); + _invokedInterpreter = Interpreter::fromXML(invokeEvent.data.atom, _callbacks->getBaseURL()); } else { _isActive = false; @@ -181,17 +181,17 @@ void USCXMLInvoker::invoke(const std::string& source, const Event& invokeEvent) // create new instances from the parent's ActionLanguage #if 1 InterpreterImpl* invoked = _invokedInterpreter.getImpl().get(); - invoked->_execContent = _interpreter->_execContent.getImpl()->create(invoked); - invoked->_delayQueue = _interpreter->_delayQueue.getImplDelayed()->create(invoked); - invoked->_internalQueue = _interpreter->_internalQueue.getImplBase()->create(); - invoked->_externalQueue = _interpreter->_externalQueue.getImplBase()->create(); - invoked->_microStepper = _interpreter->_microStepper.getImpl()->create(invoked); + invoked->_execContent = _callbacks->_execContent.getImpl()->create(invoked); + invoked->_delayQueue = _callbacks->_delayQueue.getImplDelayed()->create(invoked); + invoked->_internalQueue = _callbacks->_internalQueue.getImplBase()->create(); + invoked->_externalQueue = _callbacks->_externalQueue.getImplBase()->create(); + invoked->_microStepper = _callbacks->_microStepper.getImpl()->create(invoked); // TODO: setup invokers dom, check datamodel attribute and create new instance from parent if matching? #endif // copy monitors - std::set::const_iterator monIter = _interpreter->_monitors.begin(); - while(monIter != _interpreter->_monitors.end()) { + std::set::const_iterator monIter = _callbacks->_monitors.begin(); + while(monIter != _callbacks->_monitors.end()) { if ((*monIter)->copyToInvokers()) { _invokedInterpreter.getImpl()->_monitors.insert(*monIter); } diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index d6993dc..cc0c9d4 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -72,16 +72,16 @@ BasicHTTPIOProcessor::~BasicHTTPIOProcessor() { } -std::shared_ptr BasicHTTPIOProcessor::create(InterpreterImpl* interpreter) { +std::shared_ptr BasicHTTPIOProcessor::create(IOProcessorCallbacks* callbacks) { std::shared_ptr io(new BasicHTTPIOProcessor()); - io->_interpreter = interpreter; + io->_callbacks = callbacks; // register at http server - std::string path = interpreter->getName(); + std::string path = callbacks->getName(); int i = 2; while (!HTTPServer::registerServlet(path + "/basichttp", io.get())) { std::stringstream ss; - ss << interpreter->getName() << i++; + ss << callbacks->getName() << i++; path = ss.str(); } @@ -184,7 +184,7 @@ void BasicHTTPIOProcessor::eventFromSCXML(const std::string& target, const Event // TODO: is this still needed with isValidTarget()? if (target.length() == 0) { - _interpreter->enqueueInternal(Event("error.communication", Event::PLATFORM)); + _callbacks->enqueueInternal(Event("error.communication", Event::PLATFORM)); return; } diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.h b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.h index b70ce8e..dec22fe 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.h +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.h @@ -59,7 +59,7 @@ class USCXML_PLUGIN_API BasicHTTPIOProcessor : public IOProcessorImpl, public HT public: BasicHTTPIOProcessor(); virtual ~BasicHTTPIOProcessor(); - virtual std::shared_ptr create(uscxml::InterpreterImpl* interpreter); + virtual std::shared_ptr create(uscxml::IOProcessorCallbacks* callbacks); virtual std::list getNames() { std::list names; @@ -102,4 +102,4 @@ PLUMA_INHERIT_PROVIDER(BasicHTTPIOProcessor, IOProcessorImpl); } -#endif /* end of include guard: BASICHTTPIOPROCESSOR_H_2CUY93KU */ \ No newline at end of file +#endif /* end of include guard: BASICHTTPIOPROCESSOR_H_2CUY93KU */ diff --git a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp index c53915b..5a82860 100644 --- a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp @@ -41,16 +41,16 @@ SCXMLIOProcessor::~SCXMLIOProcessor() { } -std::shared_ptr SCXMLIOProcessor::create(InterpreterImpl* interpreter) { +std::shared_ptr SCXMLIOProcessor::create(IOProcessorCallbacks* callbacks) { std::shared_ptr io(new SCXMLIOProcessor()); - io->_interpreter = interpreter; + io->_callbacks = callbacks; return io; } Data SCXMLIOProcessor::getDataModelVariables() { Data data; - data.compound["location"] = Data("#_scxml_" + _interpreter->getSessionId(), Data::VERBATIM); + data.compound["location"] = Data("#_scxml_" + _callbacks->getSessionId(), Data::VERBATIM); return data; } @@ -71,7 +71,7 @@ void SCXMLIOProcessor::eventFromSCXML(const std::string& target, const Event& ev eventCopy.origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; // test 336 - eventCopy.origin = "#_scxml_" + _interpreter->getSessionId(); + eventCopy.origin = "#_scxml_" + _callbacks->getSessionId(); if (false) { } else if(target.length() == 0) { @@ -85,14 +85,14 @@ void SCXMLIOProcessor::eventFromSCXML(const std::string& target, const Event& ev // reqCopy.sendid = ""; // test 198 - _interpreter->enqueueExternal(eventCopy); + _callbacks->enqueueExternal(eventCopy); } else if (iequals(target, "#_internal")) { /** * #_internal: If the target is the special term '#_internal', the Processor * must add the event to the internal event queue of the sending session. */ - _interpreter->enqueueInternal(eventCopy); + _callbacks->enqueueInternal(eventCopy); } else if (iequals(target, "#_parent")) { /** @@ -100,13 +100,7 @@ void SCXMLIOProcessor::eventFromSCXML(const std::string& target, const Event& ev * add the event to the external event queue of the SCXML session that invoked * the sending session, if there is one. */ - - if (_interpreter->_parentQueue) { - _interpreter->_parentQueue.enqueue(eventCopy); - } else { - ERROR_COMMUNICATION_THROW("Sending to parent invoker, but none is set"); - } - + _callbacks->enqueueAtParent(eventCopy); } else if (target.length() > 8 && iequals(target.substr(0, 8), "#_scxml_")) { /** * #_scxml_sessionid: If the target is the special term '#_scxml_sessionid', @@ -117,7 +111,7 @@ void SCXMLIOProcessor::eventFromSCXML(const std::string& target, const Event& ev */ std::string sessionId = target.substr(8); - std::lock_guard lock(_interpreter->_instanceMutex); + std::lock_guard lock(InterpreterImpl::_instanceMutex); std::map > instances = InterpreterImpl::getInstances(); if (instances.find(sessionId) != instances.end()) { std::shared_ptr otherSession = instances[sessionId].lock(); @@ -138,21 +132,7 @@ void SCXMLIOProcessor::eventFromSCXML(const std::string& target, const Event& ev * session. */ std::string invokeId = target.substr(2); - if (_interpreter->_invokers.find(invokeId) != _interpreter->_invokers.end()) { - std::lock_guard lock(_interpreter->_instanceMutex); - try { - _interpreter->_invokers[invokeId].eventFromSCXML(eventCopy); - } catch(Event e) { - // Is this the right thing to do? -// _interpreter->enqueueExternal(eventCopy); - } catch (const std::exception &e) { - ERROR_COMMUNICATION_THROW("Exception caught while sending event to invoker '" + invokeId + "': " + e.what()); - } catch(...) { - ERROR_COMMUNICATION_THROW("Exception caught while sending event to invoker '" + invokeId + "'"); - } - } else { - ERROR_COMMUNICATION_THROW("Can not send to invoked component '" + invokeId + "', no such invokeId"); - } + _callbacks->enqueueAtInvoker(invokeId, eventCopy); } else { ERROR_COMMUNICATION_THROW("Not sure what to make of the target '" + target + "' - raising error"); } @@ -160,4 +140,4 @@ void SCXMLIOProcessor::eventFromSCXML(const std::string& target, const Event& ev -} \ No newline at end of file +} diff --git a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.h b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.h index 21fd13a..6494873 100644 --- a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.h +++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.h @@ -32,7 +32,7 @@ class SCXMLIOProcessor : public IOProcessorImpl { public: SCXMLIOProcessor(); virtual ~SCXMLIOProcessor(); - virtual std::shared_ptr create(uscxml::InterpreterImpl* interpreter); + virtual std::shared_ptr create(uscxml::IOProcessorCallbacks* callbacks); virtual std::list getNames() { std::list names; @@ -46,7 +46,7 @@ public: Data getDataModelVariables(); protected: - InterpreterImpl* _interpreter; + IOProcessorCallbacks* _callbacks; }; #ifdef BUILD_AS_PLUGINS @@ -55,4 +55,4 @@ PLUMA_INHERIT_PROVIDER(SCXMLIOProcessor, IOProcessorImpl); } -#endif /* end of include guard: SCXMLIOProcessor_H_2CUY93KU */ \ No newline at end of file +#endif /* end of include guard: SCXMLIOProcessor_H_2CUY93KU */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 658d93c..bc1c85a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,5 @@ set(TEST_TIMEOUT 30) +set(CTEST_TEST_TIMEOUT 30) set(TEST_BENCHMARK_ITERATIONS 1000) find_program(SPIN_BIN spin) @@ -37,6 +38,7 @@ function(USCXML_TEST_COMPILE) if (NOT ${USCXML_TEST_BUILD_ONLY}) add_test(${USCXML_TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${USCXML_TEST_NAME} ${USCXML_TEST_ARGS}) set_property(TEST ${USCXML_TEST_NAME} PROPERTY LABELS ${USCXML_TEST_LABEL}) + set_property(TEST ${USCXML_TEST_NAME} PROPERTY TIMEOUT ${TEST_TIMEOUT}) endif () set_target_properties(${USCXML_TEST_NAME} PROPERTIES FOLDER "Tests") endfunction() @@ -47,7 +49,11 @@ USCXML_TEST_COMPILE(NAME test-url LABEL general/test-url FILES src/test-url.cpp) USCXML_TEST_COMPILE(NAME test-lifecycle LABEL general/test-lifecycle FILES src/test-lifecycle.cpp) USCXML_TEST_COMPILE(NAME test-validating LABEL general/test-validating FILES src/test-validating.cpp) USCXML_TEST_COMPILE(NAME test-snippets LABEL general/test-snippets FILES src/test-snippets.cpp) -USCXML_TEST_COMPILE(NAME test-serialization LABEL general/test-serialization FILES src/test-serialization.cpp ../contrib/src/uscxml/PausableDelayedEventQueue.cpp) +USCXML_TEST_COMPILE( + NAME test-serialization + LABEL general/test-serialization + FILES src/test-serialization.cpp ../contrib/src/uscxml/PausableDelayedEventQueue.cpp + ARGS ${CMAKE_CURRENT_SOURCE_DIR}/w3c/ecma) # USCXML_TEST_COMPILE(NAME test-c89-parser LABEL general/test-c89-parser FILES src/test-c89-parser.cpp) # test-stress is not an automated test @@ -156,7 +162,6 @@ if (NOT BUILD_MINIMAL) # "xpath" "null" "lua" - "c89" "promela" # generated c source @@ -187,6 +192,9 @@ if (NOT BUILD_MINIMAL) # "perf/gen/c/ecma" # "perf/ecma" ) + if (WITH_DM_C89) + LIST(APPEND TEST_CLASSES c89) + endif() # prepare directories for test classes and copy resources over foreach (W3C_RESOURCE ${W3C_RESOURCES}) diff --git a/test/ctest/CTestCustom.ctest.in b/test/ctest/CTestCustom.ctest.in index f63b925..8f30989 100644 --- a/test/ctest/CTestCustom.ctest.in +++ b/test/ctest/CTestCustom.ctest.in @@ -35,33 +35,6 @@ set(CTEST_CUSTOM_TESTS_IGNORE "w3c/ecma/test436.scxml" # Tests NULL datamodel - PASSED - ### Ignore for flattened ECMAScript datamodel - "w3c/fsm/ecma/test178.scxml" # Manual - PASSED - "w3c/fsm/ecma/test230.scxml" # Manual - PASSED - "w3c/fsm/ecma/test250.scxml" # Manual - PASSED - "w3c/fsm/ecma/test307.scxml" # Manual - PASSED - "w3c/fsm/ecma/test313.scxml" # Manual - PASSED - "w3c/fsm/ecma/test314.scxml" # Manual - PASSED - "w3c/fsm/ecma/test415.scxml" # Manual - PASSED - # "w3c/fsm/ecma/test513.txt" # Manual - PASSED - - "w3c/fsm/ecma/test301.scxml" # Invalid script URL - PASSED - "w3c/fsm/ecma/test436.scxml" # Tests NULL datamodel - PASSED - - ### Ignore for flattened, minimized ECMAScript datamodel - "w3c/fsm/minimized/ecma/test178.scxml" # Manual - PASSED - "w3c/fsm/minimized/ecma/test230.scxml" # Manual - PASSED - "w3c/fsm/minimized/ecma/test250.scxml" # Manual - PASSED - "w3c/fsm/minimized/ecma/test307.scxml" # Manual - PASSED - "w3c/fsm/minimized/ecma/test313.scxml" # Manual - PASSED - "w3c/fsm/minimized/ecma/test314.scxml" # Manual - PASSED - "w3c/fsm/minimized/ecma/test415.scxml" # Manual - PASSED - # "w3c/fsm/minimized/ecma/test513.txt" # Manual - PASSED - - "w3c/fsm/minimized/ecma/test301.scxml" # Invalid script URL - PASSED - "w3c/fsm/minimized/ecma/test436.scxml" # Tests NULL datamodel - PASSED - - ### Just ignore the XPath datamodel tests that hang, most of the rest fails as well "w3c/xpath/test178.scxml" # Manual - PASSED "w3c/xpath/test230.scxml" # Manual - PASSED @@ -85,7 +58,6 @@ set(CTEST_CUSTOM_TESTS_IGNORE "w3c/lua/test314.scxml" # Manual - PASSED "w3c/lua/test415.scxml" # Manual - PASSED # "w3c/lua/test513.txt" # Manual - PASSED - "w3c/lua/test301.scxml" # Invalid script URL - PASSED "w3c/lua/test436.scxml" # Tests NULL datamodel - PASSED @@ -97,8 +69,7 @@ set(CTEST_CUSTOM_TESTS_IGNORE "w3c/prolog/test313.scxml" # Manual - PASSED "w3c/prolog/test314.scxml" # Manual - PASSED "w3c/prolog/test415.scxml" # Manual - PASSED - # "w3c/lua/test513.txt" # Manual - PASSED - + # "w3c/prolog/test513.txt" # Manual - PASSED "w3c/prolog/test301.scxml" # Invalid script URL - PASSED "w3c/prolog/test436.scxml" # Tests NULL datamodel - PASSED @@ -119,16 +90,16 @@ set(CTEST_CUSTOM_TESTS_IGNORE # "w3c/promela/test190.scxml" # string concatenation - # "w3c/promela/test224.scxml" # string operation startWith + "w3c/promela/test224.scxml" # string operation startWith # "w3c/promela/test280.scxml" # no runtime checks for undeclared variables # "w3c/promela/test350.scxml" # string concatenation - # "w3c/promela/test509.scxml" # string operation contains - # "w3c/promela/test518.scxml" # string operation contains - # "w3c/promela/test519.scxml" # string operation contains - # "w3c/promela/test520.scxml" # string operation contains + "w3c/promela/test509.scxml" # string operation contains + "w3c/promela/test518.scxml" # string operation contains + "w3c/promela/test519.scxml" # string operation contains + "w3c/promela/test520.scxml" # string operation contains # "w3c/promela/test525.scxml" # assumes unbound arrays # "w3c/promela/test530.scxml" # assigns DOM node to variable - # "w3c/promela/test534.scxml" # string operation contains + "w3c/promela/test534.scxml" # string operation contains ### Ignore for SPIN model checking @@ -195,7 +166,7 @@ set(CTEST_CUSTOM_TESTS_IGNORE "w3c/spin/promela/test553.scxml" # error in namelist "w3c/spin/promela/test554.scxml" # evaluation of 's args causes an error "w3c/spin/promela/test577.scxml" # send without target for basichttp - + ### Ignore for generated C sources @@ -203,6 +174,7 @@ set(CTEST_CUSTOM_TESTS_IGNORE # we do not support io processors yet "w3c/gen/c/ecma/test201.scxml" # basichttp + "w3c/gen/c/ecma/test453.scxml" # functions as first-class objects "w3c/gen/c/ecma/test500.scxml" # _ioprocessors "w3c/gen/c/ecma/test501.scxml" # _ioprocessors "w3c/gen/c/ecma/test509.scxml" # _ioprocessors / basichttp @@ -211,9 +183,11 @@ set(CTEST_CUSTOM_TESTS_IGNORE "w3c/gen/c/ecma/test519.scxml" # _ioprocessors / basichttp "w3c/gen/c/ecma/test520.scxml" # _ioprocessors / basichttp "w3c/gen/c/ecma/test522.scxml" # _ioprocessors / basichttp + "w3c/gen/c/ecma/test528.scxml" # runtime type information "w3c/gen/c/ecma/test531.scxml" # _ioprocessors / basichttp "w3c/gen/c/ecma/test532.scxml" # _ioprocessors / basichttp "w3c/gen/c/ecma/test534.scxml" # _ioprocessors / basichttp + "w3c/gen/c/ecma/test558.scxml" # content per url "w3c/gen/c/ecma/test567.scxml" # _ioprocessors / basichttp "w3c/gen/c/ecma/test569.scxml" # _ioprocessors "w3c/gen/c/ecma/test577.scxml" # basichttp @@ -230,6 +204,50 @@ set(CTEST_CUSTOM_TESTS_IGNORE "w3c/gen/c/ecma/test561.scxml" + "w3c/gen/c/lua/test201.scxml" # basichttp + "w3c/gen/c/lua/test216.scxml" # invoke srcexpr + "w3c/gen/c/lua/test301.scxml" # failing is succeeding + "w3c/gen/c/lua/test453.scxml" # functions as first-class objects + "w3c/gen/c/lua/test500.scxml" # _ioprocessors + "w3c/gen/c/lua/test501.scxml" # _ioprocessors + "w3c/gen/c/lua/test509.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test510.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test518.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test519.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test520.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test522.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test528.scxml" # runtime type information + "w3c/gen/c/lua/test530.scxml" # DOM in data + "w3c/gen/c/lua/test531.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test532.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test534.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test558.scxml" # content per url + "w3c/gen/c/lua/test567.scxml" # _ioprocessors / basichttp + "w3c/gen/c/lua/test569.scxml" # _ioprocessors + "w3c/gen/c/lua/test577.scxml" # basichttp + + # ignore for python bindings + "w3c/binding/python/ecma/test178.scxml" + "w3c/binding/python/ecma/test201.scxml" + "w3c/binding/python/ecma/test230.scxml" + "w3c/binding/python/ecma/test250.scxml" + "w3c/binding/python/ecma/test301.scxml" + "w3c/binding/python/ecma/test326.scxml" + "w3c/binding/python/ecma/test415.scxml" + "w3c/binding/python/ecma/test509.scxml" + "w3c/binding/python/ecma/test510.scxml" + "w3c/binding/python/ecma/test518.scxml" + "w3c/binding/python/ecma/test519.scxml" + "w3c/binding/python/ecma/test520.scxml" + "w3c/binding/python/ecma/test522.scxml" + "w3c/binding/python/ecma/test531.scxml" + "w3c/binding/python/ecma/test532.scxml" + "w3c/binding/python/ecma/test534.scxml" + "w3c/binding/python/ecma/test558.scxml" + "w3c/binding/python/ecma/test567.scxml" + "w3c/binding/python/ecma/test578.scxml" + + ### Ignore for delay with performance # timeouts with benchmarking due to delayed events diff --git a/test/ctest/scripts/run_header_compiles.cmake b/test/ctest/scripts/run_header_compiles.cmake index 8bed4e1..3aac909 100644 --- a/test/ctest/scripts/run_header_compiles.cmake +++ b/test/ctest/scripts/run_header_compiles.cmake @@ -8,6 +8,7 @@ set(COMPILE_CMD_BIN # "-I${PROJECT_BINARY_DIR}/deps/libevent/include" # "-I${PROJECT_BINARY_DIR}/deps/uriparser/include" # "-I${PROJECT_SOURCE_DIR}/contrib/src/evws" +"-std=c++11" "-I${CMAKE_BINARY_DIR}" "-I${PROJECT_BINARY_DIR}" "-I${PROJECT_SOURCE_DIR}/src" diff --git a/test/ctest/scripts/test_generated_java.cmake b/test/ctest/scripts/test_generated_java.cmake index 81317ef..31824b2 100644 --- a/test/ctest/scripts/test_generated_java.cmake +++ b/test/ctest/scripts/test_generated_java.cmake @@ -22,11 +22,11 @@ execute_process(COMMAND ${ANT_BIN} -Dtest.file=${W3C_TEST} -Dgenerated.dir=${OUTDIR} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test/bindings/java + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/contrib/java/bindings RESULT_VARIABLE CMD_RESULT OUTPUT_VARIABLE CMD_OUTPUT ) if (CMD_RESULT) - message(FATAL_ERROR "Error running ${ANT_BIN} : ${CMD_RESULT} ${CMAKE_PROJECT_DIR}/test/bindings/java ${CMD_OUTPUT}") + message(FATAL_ERROR "Error running ${ANT_BIN} : ${CMD_RESULT} ${PROJECT_SOURCE_DIR}/contrib/java/bindings ${CMD_OUTPUT}") endif () diff --git a/test/src/test-extensions.cpp b/test/src/test-extensions.cpp index 7686f9f..da81f3b 100644 --- a/test/src/test-extensions.cpp +++ b/test/src/test-extensions.cpp @@ -75,10 +75,14 @@ bool testPausableEventQueue() { interpreter.addMonitor(&mon); size_t iterations = 10; + int now = time(NULL); + int startedAt = time(NULL); InterpreterState state = InterpreterState::USCXML_UNDEF; - while (state != USCXML_FINISHED) { - state = interpreter.step(); + while (state != USCXML_FINISHED && now - startedAt < 5) { + state = interpreter.step(200); + now = time(NULL); + if (nestedDelayQueue) { /* * As soon as we have the nested event queue instantiated, we pause and resume it diff --git a/test/src/test-gen-c.cpp b/test/src/test-gen-c.cpp index acf1246..3971845 100644 --- a/test/src/test-gen-c.cpp +++ b/test/src/test-gen-c.cpp @@ -17,16 +17,20 @@ #endif #ifndef AUTOINCLUDE_TEST -#include "test-c-machine.scxml.c" -//#include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/ecma/test329.scxml.machine.c" +//#include "test-c-machine.scxml.c" +//#include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/ecma/test562.scxml.machine.c" +//#include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/ecma/test558.scxml.machine.c" +#include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/lua/test530.scxml.machine.c" #endif #include "uscxml/util/URL.h" //#include "uscxml/concurrency/Timer.h" //#include "uscxml/dom/DOMUtils.h" #include "uscxml/plugins/Factory.h" +#include "uscxml/plugins/IOProcessorImpl.h" //#include "uscxml/Interpreter.h" #include "uscxml/util/UUID.h" +//#include "uscxml/server/HTTPServer.h" #include "uscxml/interpreter/InterpreterImpl.h" #include "uscxml/interpreter/BasicEventQueue.h" @@ -40,7 +44,7 @@ using namespace uscxml; -class StateMachine : public DataModelCallbacks, public DelayedEventQueueCallbacks { +class StateMachine : public DataModelCallbacks, public IOProcessorCallbacks, public DelayedEventQueueCallbacks { public: StateMachine(const uscxml_machine* machine) : machine(machine), parentMachine(NULL), topMostMachine(NULL), invocation(NULL) { allMachines[sessionId] = this; @@ -70,6 +74,23 @@ public: return ioProcs; } + void enqueueInternal(const Event& event) { + iq.push_back(event); + } + void enqueueExternal(const Event& event) { + eq.push_back(event); + } + + void enqueueAtInvoker(const std::string& invokeId, const Event& event) { + if (invokers.find(invokeId) != invokers.end()) + invokers[invokeId].eventFromSCXML(event); + } + + void enqueueAtParent(const Event& event) { + if (parentMachine != NULL) + parentMachine->enqueueExternal(event); + } + bool isInState(const std::string& stateId) { for (size_t i = 0; i < ctx.machine->nr_states; i++) { if (ctx.machine->states[i].name && @@ -119,6 +140,16 @@ public: name = machine->name; + // register IO Procs + std::map allIOProcs = Factory::getInstance()->getIOProcessors(); + for (auto ioProcImpl : allIOProcs) { + ioProcs[ioProcImpl.first] = Factory::getInstance()->createIOProcessor(ioProcImpl.first, this); + std::list names = ioProcImpl.second->getNames(); + for (auto name : names) { + ioProcs[name] = ioProcs[ioProcImpl.first]; + } + } + delayQueue = DelayedEventQueue(std::shared_ptr(new BasicDelayedEventQueue(this))); dataModel = Factory::getInstance()->createDataModel(machine->datamodel, this); @@ -310,7 +341,12 @@ public: if (donedata) { if (donedata->content != NULL) { - e.data = Data(donedata->content, Data::VERBATIM); + if (isNumeric(donedata->content, 10)) { + // test 529 + e.data = Data(strTo(donedata->content), Data::INTERPRETED); + } else { + e.data = Data(donedata->content, Data::VERBATIM); + } } else if (donedata->contentexpr != NULL) { try { e.data = USER_DATA(ctx)->dataModel.getAsData(donedata->contentexpr); @@ -369,13 +405,13 @@ public: } if (target.size() > 0 && (target[0] != '#' || target[1] != '_')) { + std::cerr << "Target '" << target << "' is not supported yet" << std::endl; e.name = "error.execution"; execContentRaise(ctx, e); return USCXML_ERR_INVALID_TARGET; } e.origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; -// e.origin = target; std::string type; try { @@ -400,6 +436,7 @@ public: } e.origintype = type; + e.origin = "#_scxml_" + USER_DATA(ctx)->sessionId; e.invokeid = USER_DATA(ctx)->invokeId; if (send->eventexpr != NULL) { @@ -446,11 +483,13 @@ public: } if (send->content != NULL) { - // will it parse as json? - Data d = USER_DATA(ctx)->dataModel.getAsData(send->content); - if (!d.empty()) { - e.data = d; - } else { + try { + // will it parse as json? + Data d = USER_DATA(ctx)->dataModel.getAsData(send->content); + if (!d.empty()) { + e.data = d; + } + } catch (Event err) { e.data = Data(spaceNormalize(send->content), Data::VERBATIM); } } @@ -560,8 +599,9 @@ public: try { // Data d = USER_DATA(ctx)->dataModel.getStringAsData(expr); if (assign->expr != NULL) { - USER_DATA(ctx)->dataModel.assign(key, - USER_DATA(ctx)->dataModel.evalAsData(assign->expr)); +// USER_DATA(ctx)->dataModel.assign(key, +// USER_DATA(ctx)->dataModel.evalAsData(assign->expr)); + USER_DATA(ctx)->dataModel.assign(key, Data(assign->expr, Data::INTERPRETED)); } else if (assign->content != NULL) { Data d = Data(assign->content, Data::INTERPRETED); USER_DATA(ctx)->dataModel.assign(key, d); @@ -628,7 +668,8 @@ public: try { if (data->expr != NULL) { - d = USER_DATA(ctx)->dataModel.evalAsData(data->expr); + d = Data(data->expr, Data::INTERPRETED); +// d = USER_DATA(ctx)->dataModel.evalAsData(data->expr); } else if (data->content != NULL || data->src != NULL) { if (data->content) { @@ -647,7 +688,9 @@ public: * as space normalized string literals if this fails below */ d = USER_DATA(ctx)->dataModel.getAsData(content.str()); - + if (d.empty()) { + d = Data(escape(spaceNormalize(content.str())), Data::VERBATIM); + } } else { // leave d undefined } @@ -895,6 +938,8 @@ NEXT_DESC: std::deque eq; DataModel dataModel; + std::map ioProcs; + std::map invokers; protected: struct scxml_foreach_info { @@ -903,8 +948,6 @@ protected: }; X xmlPrefix; - std::map ioProcs; - std::map invokers; XERCESC_NS::DOMDocument* document; DelayedEventQueue delayQueue; @@ -925,6 +968,9 @@ int main(int argc, char** argv) { benchmarkRuns = strTo(envBenchmarkRuns); } + // start the webserver for the basichttp tests +// HTTPServer::getInstance(3453, 3454, NULL); + size_t remainingRuns = benchmarkRuns; size_t microSteps = 0; diff --git a/test/src/test-http-debugger.pl b/test/src/test-http-debugger.pl index a7a1d0a..fcc675f 100755 --- a/test/src/test-http-debugger.pl +++ b/test/src/test-http-debugger.pl @@ -26,16 +26,19 @@ my @breakpointSeq; my $pid = fork; if (!$pid) { - # exec("$scxmlBin -t4088 -d"); + exec("$scxmlBin -t4088 -d"); exit; } -# my $baseURL = 'http://localhost:4088/debug'; -my $baseURL = 'http://localhost:5080/debug'; +my $baseURL = 'http://localhost:4088/debug'; +# my $baseURL = 'http://localhost:5080/debug'; sub assertSuccess { my $response = shift; my $message = shift; + print "-----\n"; + print $response->content(); + print "-----\n"; from_json($response->content())->{'status'} eq "success" or die($message); } diff --git a/test/w3c/TESTS.md b/test/w3c/TESTS.md index cb50028..43282c6 100644 --- a/test/w3c/TESTS.md +++ b/test/w3c/TESTS.md @@ -1,88 +1,100 @@ - + + + - + + + - - - + - + - + - + + + - - + + + + - + + + - - + + + + - + - + + + @@ -95,23 +107,27 @@ - + + + - + + + @@ -121,50 +137,58 @@ - + + + - + - + + + - + + + - + + + @@ -177,46 +201,54 @@ - + + + - + + + - + + + - + + + @@ -229,7 +261,9 @@ - + + + @@ -242,44 +276,53 @@ - + + + - + + + - + + + + + + @@ -287,14 +330,15 @@ - - + + + @@ -307,7 +351,9 @@ - + + + @@ -320,7 +366,9 @@ - + + + @@ -333,46 +381,54 @@ - + + + - + + + - + + + - + + + @@ -385,7 +441,9 @@ - + + + @@ -398,7 +456,9 @@ - + + + @@ -411,7 +471,9 @@ - + + + @@ -424,7 +486,9 @@ - + + + @@ -434,14 +498,16 @@ - + - + + + @@ -454,41 +520,47 @@ - + + + - + - + + + - + - + + + @@ -501,24 +573,28 @@ - + + + - + - + + + @@ -531,7 +607,9 @@ - + + + @@ -541,14 +619,16 @@ - + - + + + @@ -561,7 +641,9 @@ - + + + @@ -570,18 +652,20 @@ - + - + - + + + @@ -591,96 +675,110 @@ - + - + + + - + + + - + + + - + - + + + - + + + - + + + - + + + @@ -693,7 +791,9 @@ - + + + @@ -706,10 +806,12 @@ - + + + @@ -719,24 +821,28 @@ - + + + - + - + + + @@ -749,27 +855,31 @@ - + + + - + - + - + + + @@ -782,7 +892,9 @@ - + + + @@ -795,49 +907,57 @@ - + + + - + + + - + + + - + + + @@ -847,25 +967,29 @@ + + + - - + - + + + + - @@ -873,20 +997,24 @@ + + + - - + - + + + @@ -899,11 +1027,13 @@ + + + - @@ -912,10 +1042,12 @@ - + + + @@ -925,7 +1057,9 @@ - + + + @@ -938,7 +1072,9 @@ - + + + @@ -951,12 +1087,14 @@ - - + + + + @@ -964,7 +1102,9 @@ - + + + @@ -977,20 +1117,24 @@ - + + + - + + + @@ -1003,63 +1147,73 @@ - + + + - + + + - + - + + + - + + + - + + + @@ -1072,10 +1226,12 @@ - + + + @@ -1085,7 +1241,9 @@ - + + + @@ -1098,7 +1256,9 @@ - + + + @@ -1111,7 +1271,9 @@ - + + + @@ -1121,27 +1283,31 @@ - + - + + + - + + + @@ -1154,7 +1320,9 @@ - + + + @@ -1167,47 +1335,53 @@ - + + + - + - + + + - + - + + + @@ -1217,17 +1391,21 @@ + + - + - + + + @@ -1237,106 +1415,120 @@ - + - + + + - + + + - + + + - + - + + - + + - - + + + + - - + + + + - - + + + + - + @@ -1350,16 +1542,20 @@ + + - + + + @@ -1369,7 +1565,9 @@ - + + + @@ -1382,92 +1580,106 @@ - + + + - + + + - - - + + + + + - - - + + + + + - + + + - + - + - + + + - + + + @@ -1480,7 +1692,9 @@ - + + + @@ -1493,7 +1707,9 @@ - + + + @@ -1506,7 +1722,9 @@ - + + + @@ -1518,6 +1736,9 @@ + + + @@ -1525,14 +1746,15 @@ - - + + + @@ -1545,7 +1767,9 @@ - + + + @@ -1558,7 +1782,9 @@ - + + + @@ -1571,7 +1797,9 @@ - + + + @@ -1584,7 +1812,9 @@ - + + + @@ -1597,20 +1827,24 @@ - + + + - + + + @@ -1623,20 +1857,24 @@ - + + + - + + + @@ -1653,16 +1891,20 @@ - - + + + + - + + + @@ -1675,50 +1917,58 @@ - + + + - + + + - + - + + + - + + + @@ -1731,7 +1981,9 @@ - + + + @@ -1741,20 +1993,22 @@ - + - + + + @@ -1764,9 +2018,11 @@ + + + - @@ -1774,20 +2030,24 @@ - + + + - + + + @@ -1800,12 +2060,14 @@ - - + + + + @@ -1813,7 +2075,9 @@ - + + + @@ -1826,7 +2090,9 @@ - + + + @@ -1839,59 +2105,69 @@ - + + + - + + + + + + - - + - + + + - + + + @@ -1904,7 +2180,9 @@ - + + + @@ -1917,7 +2195,9 @@ - + + + @@ -1930,85 +2210,99 @@ - + + + - + + + - + + + - + + + - + + + - + + + - + + + @@ -2021,7 +2315,9 @@ - + + + @@ -2034,7 +2330,9 @@ - + + + @@ -2047,18 +2345,23 @@ - + + + + + + @@ -2066,33 +2369,36 @@ - - + + + - + + + @@ -2102,9 +2408,11 @@ + + + - @@ -2112,20 +2420,22 @@ - + + + - + - + @@ -2139,17 +2449,21 @@ + + - + - + + + @@ -2163,12 +2477,14 @@ + - + + @@ -2176,12 +2492,14 @@ + - + + @@ -2189,12 +2507,14 @@ + - + + @@ -2202,12 +2522,14 @@ + - + + @@ -2215,12 +2537,14 @@ + - + + @@ -2228,12 +2552,14 @@ + - + + @@ -2241,12 +2567,14 @@ + - + + @@ -2254,11 +2582,13 @@ + + - + @@ -2267,12 +2597,14 @@ + - + + @@ -2280,12 +2612,14 @@ + - + + @@ -2293,12 +2627,14 @@ + - + + @@ -2306,12 +2642,14 @@ + - + + @@ -2319,6 +2657,8 @@ + + @@ -2332,11 +2672,13 @@ + + + + - - @@ -2345,12 +2687,14 @@ + - + + @@ -2358,6 +2702,8 @@ + + @@ -2371,11 +2717,13 @@ + + + - @@ -2384,6 +2732,8 @@ + + @@ -2397,16 +2747,18 @@ + - + + - + @@ -2420,6 +2772,8 @@ + + @@ -2433,6 +2787,8 @@ + + @@ -2446,6 +2802,8 @@ + + @@ -2459,6 +2817,8 @@ + + @@ -2472,6 +2832,8 @@ + + @@ -2485,6 +2847,8 @@ + + @@ -2498,6 +2862,8 @@ + + @@ -2511,6 +2877,8 @@ + + @@ -2524,6 +2892,8 @@ + + @@ -2537,6 +2907,8 @@ + + @@ -2550,6 +2922,8 @@ + + @@ -2563,6 +2937,8 @@ + + @@ -2576,6 +2952,8 @@ + + @@ -2589,6 +2967,8 @@ + + @@ -2602,6 +2982,8 @@ + + @@ -2615,6 +2997,8 @@ + + @@ -2628,6 +3012,8 @@ + + @@ -2641,6 +3027,8 @@ + + @@ -2654,6 +3042,8 @@ + + @@ -2667,6 +3057,8 @@ + + @@ -2680,6 +3072,8 @@ + + @@ -2693,6 +3087,8 @@ + + @@ -2706,6 +3102,8 @@ + + @@ -2719,6 +3117,8 @@ + + @@ -2732,6 +3132,8 @@ + + @@ -2745,6 +3147,8 @@ + + @@ -2758,6 +3162,8 @@ + + @@ -2771,6 +3177,8 @@ + + @@ -2784,6 +3192,8 @@ + + @@ -2797,20 +3207,24 @@ + + - + - + - + + + @@ -2823,20 +3237,24 @@ - + + + - + + + @@ -2849,46 +3267,54 @@ - + + + - + + + - + + + - + + + @@ -2901,23 +3327,27 @@ - - - + + + + + - + + + @@ -2927,20 +3357,24 @@ - + + + - + + + @@ -2953,20 +3387,24 @@ - + + + - + + + @@ -2979,13 +3417,15 @@ - + + + @@ -2996,9 +3436,11 @@ - - + + + + @@ -3009,13 +3451,15 @@ - - + + + + - + @@ -3025,10 +3469,12 @@ + + + - - + @@ -3039,8 +3485,10 @@ - + + + @@ -3055,6 +3503,8 @@ + + @@ -3064,10 +3514,12 @@ + + + - - + @@ -3077,10 +3529,12 @@ + + + - - + @@ -3090,8 +3544,10 @@ + + + - @@ -3104,8 +3560,10 @@ - + + + @@ -3116,9 +3574,11 @@ + + + - @@ -3129,9 +3589,11 @@ + + + - @@ -3142,10 +3604,12 @@ + + + - - + @@ -3156,9 +3620,11 @@ - - + + + + @@ -3168,9 +3634,11 @@ + + + - diff --git a/test/w3c/confLua.xsl b/test/w3c/confLua.xsl index d0a15b1..b261b20 100644 --- a/test/w3c/confLua.xsl +++ b/test/w3c/confLua.xsl @@ -141,7 +141,7 @@ - return + return# diff --git a/test/w3c/create-test-table.pl b/test/w3c/create-test-table.pl index bca8f87..e35f098 100755 --- a/test/w3c/create-test-table.pl +++ b/test/w3c/create-test-table.pl @@ -30,7 +30,8 @@ my %testClasses = ( 'w3c/gen/c/ecma' => 'C (ECMA)', 'w3c/gen/c/lua' => 'C (Lua)', 'w3c/binding/java/jexl' => 'Java (JEXL)', -# 'w3c/spin/promela' => 'Spin' +'w3c/binding/python/ecma' => 'Python (ECMA)', +'w3c/spin/promela' => 'Spin', 'w3c/gen/vhdl/promela' => 'VHDL Promela', # 'w3c/gen/vhdl/ecma' => 'VHDL ECMA', ); diff --git a/test/w3c/lua/test488.scxml b/test/w3c/lua/test488.scxml index db6b062..b5dfcf1 100644 --- a/test/w3c/lua/test488.scxml +++ b/test/w3c/lua/test488.scxml @@ -12,7 +12,7 @@ - + -- cgit v0.12
Test (Req. / Man.)ECMAC (Lua) NSVHDL Promela Java (JEXL)SpinC (ECMA)Python (ECMA) LuaECMA PromelaC (ECMA)C (Lua)VHDL Promela
Core ConstructsCore Constructs
§3.10 The History Element  The History Element 
   387 X OKN/A OK OK OK OK OK OKOKOKFAIL
   388 X OKN/A OK OK OKFAIL OK OKOKOKOKFAIL
   579 X OKN/A OK OK OK OK OK OKOKOKFAIL
   580 X OKN/A OK OK OKFAILOKOKOKOK OK OK
§3.12 SCXML Events  SCXML Events 
   396 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   401 X OKN/A OK OK OKN/AOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
§3.13 Selecting and Executing Transitions  Selecting and Executing Transitions 
   403a X OKN/A OK OK OK OK OK OKOKOKFAIL
   403c X OKN/A OK OK OK OK OK OKOKOKFAIL
   403b X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   405 X OKN/A OK OK OK OK OK OKOKOKFAIL
   406 X OKN/A OK OK OK OK OK OKOKOKFAIL
   407 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   412 X OKN/A OK OK OK OK OK OKOKOKFAIL
   413 X OKN/A OK OK OK OK OK OKOKOKFAIL
   415 X XN/AOKOK OK N/A OKN/A N/A OKOK
   416 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   422 X OKN/A OK OK OK OK OK OKOKOKFAIL
   423 X OKN/A OK OK OK OK OK OKOKOKFAIL
   503 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OK
§3.2 The SCXML Element  The SCXML Element 
   355 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
§3.3 The State Element  The State Element 
   364 X OKN/A OK OK OKFAILOK OK OK OKFAIL
§3.7 The Final Element  The Final Element 
   372 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
§3.8 The Onentry Element  The Onentry Element 
   375 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OK
§3.9 The Onexit Element  The Onexit Element 
   377 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKOK
Executable ContentExecutable Content
§4.2 The Raise Element  The Raise Element 
   144 X OKN/AOKOKOK OK OK OK
§4.3 The If Element  The If Element 
   147 X OKN/A OK OK OK OK OK OKOKOKFAIL
   148 X OKN/A OK OK OK OK OK OKOKOKFAIL
   149 X OKN/A OK OK OK OK OK OKOKOKFAIL
§4.6 The Foreach Element  The Foreach Element 
   150 X OKN/A OK OK OK OK OK OKOKOKFAIL
   151 X OKN/A OK OK OK OK OK OKOKOKFAIL
   152 X OKN/A OK OK OKN/AOK OK OK OKFAIL
   153 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOKOK OK OK OKX OKN/A OK OK OKN/AOKOK OK OK OK
§4.9 Evaluation of Executable Content  Evaluation of Executable Content 
   158 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOKOK OK OK OK
Data Model and ManipulationData Model and Manipulation
§5.10 System Variables  System Variables 
   318 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   322 X OKN/A OK OK OKN/AOK OK OK OKFAIL
   323 X OKN/A OK OK OK OK OK OKOKOKFAIL
   324 X OKN/A OK OK OKN/AOKOK OK OK OKX OKOKOKOK N/A OK OK OK OKFAILFAILOK
   326 X OKN/A OK OK OKN/AOKN/AOK OKFAIL FAIL
X OKOKOKOK N/A OK OK OK OKFAILFAILOK
   330 X OKN/AOKOKOK OK OK OKX OKOKOKOK N/A OK OK OKFAIL OK OK
X OKN/A OK OK OKN/AOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OKFAILOKOKOKOK FAIL
X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   339 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   346 X OKN/A OK OK OKN/A OK OK OKOKFAIL
§5.3 The Data Element  The Data Element 
   276 X OKN/A OK OK OK OK OK OKOKOKFAIL
   277 X OKN/A OK OK OKN/AOK OK OK OKFAIL
   279 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OK
§5.4 The Assign Element  The Assign Element 
   286 X OKN/A OK OK OKN/AOK OK OK OKFAIL
   287 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
§5.5 The Donedata Element  The Donedata Element 
   294 X OKN/A OK OK OKN/AOK OK OK OKFAIL
§5.6 The Content Element  The Content Element 
   527 X OKN/A OK OK OK OK OK OKOKOKFAIL
   528N/A OK OKN/AN/A OK OKFAIL OKFAIL
   529 X OKN/AOKOKOK OK OK OK
§5.7 The Param Element  The Param Element 
   298 X OKN/A OK OK OKN/A OK OK OKOKFAIL
   343 X OKN/A OK OK OKN/AOK OK OK OKFAIL
   488 X OKN/A OK OK OKN/AOK OK OK OKFAIL
§5.8 The Script Element  The Script Element 
   301 X XOK N/AN/AOK OK N/A N/A N/A N/AFAILN/AOK
   302 X OKN/A OK OK OK OK OKFAILOKOKOKOK
   303 X OKN/A OK OK OK OK OKFAILOKOKOKOK
   304 X OKN/A OK OK OK OK OKFAILOKOKOKOK
§5.9 Expressions  Expressions 
   307N/A N/A N/AN/AN/A
   309 X OKN/A OK OK OKN/AOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
   312 X OKN/A OK OK OKN/AOK OK OK OKFAIL
   313 X XOK N/A OKN/AN/AOKOK N/A OK OKN/AN/AFAIL
   314 X XOK N/A OKN/AN/AOKOK N/A OK OKN/AN/AFAIL
   344 X OKN/A OK OK OKN/AOK OK OK OKFAIL
External CommunicationsExternal Communications
§6.2 The Send Element  The Send Element 
   172 X OKN/A OK OK OK OK OK OKOKOKFAIL
   173 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OK   178 X XN/AOKOK OK N/A OKN/A N/A OKOK
   179 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
   198 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
   200 X OKN/AOKOKOK OK OK OKOK OK OKOK N/AFAILN/AOKOKOK
   205 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
   553 X OKN/A OK OK OKN/AOKOK OK OK OK
§6.3 The Cancel Element  The Cancel Element 
   207 X OKN/A OK OK OK OK OK OKOKOKFAIL
   208 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OK
§6.4 The Invoke Element  The Invoke Element 
   215 X OKN/A OK OK OK OK OK OKOKOKFAIL
   216N/A OK OKN/AN/AOK OK OKN/A FAIL
X OKN/A OK OK OK OK OK OKOKOKFAIL
   223 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OKFAILN/AOKOK OKN/A OK
X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   229 X OKN/A OK OK OK OK OK OKOKOKFAIL
   230 X XN/AOKOK OK N/A OK N/A N/A N/AOKOKFAIL
   232 X OKN/A OK OK OK OK OK OKOKOKFAIL
   233 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   237 X OKN/A OK OK OK OK OK OKOKOKFAIL
   239 X OKN/A OK OK OK OK OK OKOKOKFAIL
   240 X OKN/A OK OK OK OK OK OKOKOKFAIL
   241 X OKN/A OK OK OK OK OK OKOKOKFAIL
   242 X OKN/A OK OK OK OK OK OKOKOKFAIL
   243 X OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   250 X XN/AOKOK OK N/A OKN/A N/A OKOK
   252 X OKN/A OK OK OK OK OK OKOKOKFAIL
   253 X OKN/A OK OK OK OK OK OKOKOKFAIL
   530N/A OK OKN/AN/AOK OK OKN/A FAIL
X OKN/A OK OK OKN/A OK OK OKOKFAIL
Data ModelsData Models
§C.1 The Null Data Model  The Null Data Model 
   436N/A N/A N/AN/AN/A
§C.2 The ECMAScript Data Model  The ECMAScript Data Model 
   278 OKN/AOKOKOK OK OK OK OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   445 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   446 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   448 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   449 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   451 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   452 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   453 OK N/AOKN/A N/A N/A OK N/AFAILN/A N/A
OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   457 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   459 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   460 OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   557 OK N/AOKN/A N/A N/A OK OK N/AOKN/AN/AN/A N/A N/AOK N/AOK N/A
OK N/AOK N/A N/A OKN/A OK N/AN/AN/A
   561 OK N/AOKN/A N/A N/A OK OK N/AOK N/A N/A OKOKN/A N/AFAIL N/A
OK N/AOKN/A N/A N/A OK OK N/AOK N/A N/A OK N/AOKN/AN/A N/A
§C.3 The XPath Data Model  The XPath Data Model 
   463N/A N/A N/AN/AN/A
   464N/A N/A N/AN/AN/A
   465N/A N/A N/AN/AN/A
   466N/A N/A N/AN/AN/A
   467N/A N/A N/AN/AN/A
   468N/A N/A N/AN/AN/A
   469N/A N/A N/AN/AN/A
   470N/A N/A N/AN/AN/A
   473N/A N/A N/AN/AN/A
   474N/A N/A N/AN/AN/A
   475N/A N/A N/AN/AN/A
   476N/A N/A N/AN/AN/A
   477N/A N/A N/AN/AN/A
   478N/A N/A N/AN/AN/A
   479N/A N/A N/AN/AN/A
   480N/A N/A N/AN/AN/A
   481N/A N/A N/AN/AN/A
   482N/A N/A N/AN/AN/A
   483N/A N/A N/AN/AN/A
   537N/A N/A N/AN/AN/A
   539N/A N/A N/AN/AN/A
   540N/A N/A N/AN/AN/A
   542N/A N/A N/AN/AN/A
   543N/A N/A N/AN/AN/A
   544N/A N/A N/AN/AN/A
   545N/A N/A N/AN/AN/A
   546N/A N/A N/AN/AN/A
   547N/A N/A N/AN/AN/A
   555N/A N/A N/AN/AN/A
   568N/A N/A N/AN/AN/A
Event I/O ProcessorEvent I/O Processor
§D.1 SCXML Event I/O Processor  SCXML Event I/O Processor 
   189 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   191 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   193 OKN/A OK OK OK OK OK OKOKOKFAIL
   347 X OKN/A OK OK OK OK OK OKOKOKFAIL
   348 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OK OKFAILFAILOKOKOKOKOK
   350 X OKN/A OK OK OKN/AOKOK OK OK OKX OKN/A OK OK OK OK OK OKOKOKFAIL
   352 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
   495 X OKN/AOKOKOK OK OK OKX OKN/A OK OK OKN/AOK OK OK OKFAIL
   500OK OK OKOK N/AFAILOKOKOKOK
   501OK OK OKOK N/AFAILOKOKOKOK
§D.2 Basic HTTP Event I/O Processor  Basic HTTP Event I/O Processor 
   509N/A OK OKN/AN/AN/A OKFAIL N/AFAILOK
   510OK OK OKOK N/AN/AOKOK FAIL
N/A N/A N/AN/AN/A
   518N/A OK OKN/AN/AN/A OKFAIL N/AFAILOK
   519N/A OK OKN/AN/AN/A OKFAIL N/AFAILOK
   520N/A OK OKN/AN/AN/A OKFAIL N/A FAIL
OK OK OKOK N/AN/AOKOK FAIL
N/A OK OKN/AN/AN/A OK OKN/A FAIL
N/A OK OKN/AN/AN/A OK OKN/A FAIL
N/A OK OKN/AN/AN/A OKFAIL N/AFAILOK
   567OK OK OKOK N/AFAILN/AOKOKOK
   577N/A OK OKN/AN/AOK OK OKN/A FAIL