From a5a139f46438148901ea6627b73d1bf6ae39b346 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Fri, 5 Dec 2014 12:06:09 +0100 Subject: Support for initial attribute with nested scxml invokers --- src/bindings/swig/uscxml_ignores.i | 1 + src/uscxml/Interpreter.cpp | 1 + src/uscxml/messages/InvokeRequest.h | 3 +- src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp | 5 +++ src/uscxml/transform/ChartToPromela.cpp | 21 +++++++---- src/uscxml/transform/ChartToPromela.h | 2 +- test/ctest/CTestCustom.ctest.in | 15 +++----- test/uscxml/test-initial-configuration.scxml | 41 ++++++++++++++++++++++ test/w3c/confPromela.xsl | 4 +++ test/w3c/promela/test510.scxml | 2 +- test/w3c/promela/test522.scxml | 2 +- 11 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 test/uscxml/test-initial-configuration.scxml diff --git a/src/bindings/swig/uscxml_ignores.i b/src/bindings/swig/uscxml_ignores.i index 7f7f7a3..e6b7e88 100644 --- a/src/bindings/swig/uscxml_ignores.i +++ b/src/bindings/swig/uscxml_ignores.i @@ -192,6 +192,7 @@ %ignore uscxml::SendRequest::fromXML; %ignore uscxml::InvokeRequest::fromXML; +%ignore uscxml::InvokeRequest::elem; // HTTPServer diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 6aca93c..4dabcb9 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -1805,6 +1805,7 @@ void InterpreterImpl::delayedSend(void* userdata, std::string eventName) { void InterpreterImpl::invoke(const Arabica::DOM::Element& element) { InvokeRequest invokeReq; + invokeReq.elem = element; invokeReq.Event::eventType = Event::EXTERNAL; try { // type diff --git a/src/uscxml/messages/InvokeRequest.h b/src/uscxml/messages/InvokeRequest.h index ac5f6f7..7cecf8d 100644 --- a/src/uscxml/messages/InvokeRequest.h +++ b/src/uscxml/messages/InvokeRequest.h @@ -60,7 +60,8 @@ protected: std::string type; std::string src; bool autoForward; - + Arabica::DOM::Element elem; + friend USCXML_API std::ostream& operator<< (std::ostream& os, const InvokeRequest& sendReq); }; diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index 9506867..5a447c4 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -19,6 +19,7 @@ #include "USCXMLInvoker.h" #include +#include "uscxml/DOMUtils.h" #ifdef BUILD_AS_PLUGINS #include @@ -88,6 +89,10 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) { LOG(ERROR) << "Cannot invoke nested SCXML interpreter, neither src attribute nor content nor DOM is given"; } if (_invokedInterpreter) { + if (req.elem && HAS_ATTR(req.elem, "initial")) { + _invokedInterpreter.setInitalConfiguration(InterpreterImpl::tokenize(ATTR(req.elem, "initial"))); + } + DataModel dataModel(_invokedInterpreter.getImpl()->getDataModel()); _invokedInterpreter.getImpl()->setParentQueue(&_parentQueue); diff --git a/src/uscxml/transform/ChartToPromela.cpp b/src/uscxml/transform/ChartToPromela.cpp index 092a284..9d297ad 100644 --- a/src/uscxml/transform/ChartToPromela.cpp +++ b/src/uscxml/transform/ChartToPromela.cpp @@ -1566,7 +1566,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: } else if(TAGNAME(nodeElem) == "log") { std::string label = (HAS_ATTR(nodeElem, "label") ? ATTR(nodeElem, "label") : ""); - std::string expr = (HAS_ATTR(nodeElem, "expr") ? ATTR(nodeElem, "expr") : ""); + std::string expr = (HAS_ATTR(nodeElem, "expr") ? ADAPT_SRC(ATTR(nodeElem, "expr")) : ""); std::string trimmedExpr = boost::trim_copy(expr); bool isStringLiteral = (boost::starts_with(trimmedExpr, "\"") || boost::starts_with(trimmedExpr, "'")); @@ -2034,7 +2034,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { } stream << "hidden int " << _prefix << "_index; /* helper for indexless foreach loops */" << std::endl; - stream << "hidden int " << _prefix << "_pid; /* the process id running this machine */" << std::endl; + stream << "hidden int " << _prefix << "procid; /* the process id running this machine */" << std::endl; stream << "bool " << _prefix << "spontaneous; /* whether to take spontaneous transitions */" << std::endl; stream << "bool " << _prefix << "done; /* is the state machine stopped? */" << std::endl; stream << "bool " << _prefix << "canceled; /* is the state machine canceled? */" << std::endl; @@ -2078,6 +2078,11 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { std::string identifier = (HAS_ATTR_CAST(data, "id") ? ATTR_CAST(data, "id") : ""); std::string expression = (HAS_ATTR_CAST(data, "expr") ? ATTR_CAST(data, "expr") : ""); + if (expression.size() == 0 && HAS_ATTR_CAST(data, "src")) { + URL dataSrc(ATTR_CAST(data, "src")); + dataSrc.toAbsolute(_baseURI); + expression = dataSrc.getInContent(); + } std::string type = boost::trim_copy(HAS_ATTR_CAST(data, "type") ? ATTR_CAST(data, "type") : ""); _dataModelVars.insert(identifier); @@ -2220,11 +2225,11 @@ void ChartToPromela::writeStartInvoker(std::ostream& stream, const Arabica::DOM: void ChartToPromela::writeFSM(std::ostream& stream) { NodeSet transitions; - stream << "proctype " << _prefix << "run() {" << std::endl; + stream << "proctype " << (_prefix.size() == 0 ? "machine_" : _prefix) << "run() {" << std::endl; stream << " " << _prefix << "done = false;" << std::endl; stream << " " << _prefix << "canceled = false;" << std::endl; stream << " " << _prefix << "spontaneous = true;" << std::endl; - stream << " " << _prefix << "_pid = _pid;" << std::endl; + stream << " " << _prefix << "procid = _pid;" << std::endl; // write initial transition // transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _startState); // assert(transitions.size() == 1); @@ -2301,7 +2306,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { stream << " if" << std::endl; stream << " :: (tmpE.delay < lowestDelay || lowestDelay == 0) -> {" << std::endl; stream << " lowestDelay = tmpE.delay;" << std::endl; - stream << " nextPid = " << queueIter->second->_prefix << "_pid;" << std::endl; + stream << " nextPid = " << queueIter->second->_prefix << "procid;" << std::endl; stream << " }" << std::endl; stream << " :: else -> skip;" << std::endl; stream << " fi;" << std::endl; @@ -2627,7 +2632,7 @@ void ChartToPromela::writeMain(std::ostream& stream) { } if (_globalEventSource) _globalEventSource.writeStart(stream, 1); - stream << " run " << _prefix << "run() priority 10;" << std::endl; + stream << " run " << (_prefix.size() == 0 ? "machine_" : _prefix) << "run() priority 10;" << std::endl; stream << "}" << std::endl; } @@ -2717,6 +2722,10 @@ void ChartToPromela::initNodes() { // std::cout << invokes[i] << std::endl; + // we found machines but have no prefix + if (_prefix.length() == 0) + _prefix = "MAIN_"; + _machines[invokes[i]] = new ChartToPromela(nested); _machines[invokes[i]]->_analyzer = _analyzer; _machines[invokes[i]]->_parent = this; diff --git a/src/uscxml/transform/ChartToPromela.h b/src/uscxml/transform/ChartToPromela.h index e322eaf..2523bf6 100644 --- a/src/uscxml/transform/ChartToPromela.h +++ b/src/uscxml/transform/ChartToPromela.h @@ -280,7 +280,7 @@ public: void writeTo(std::ostream& stream); protected: - ChartToPromela(const Interpreter& other) : TransformerImpl(), ChartToFSM(other), _analyzer(NULL), _machinesAll(NULL), _parent(NULL), _parentTopMost(NULL), _machinesAllPerId(NULL), _prefix("MAIN_") {} + ChartToPromela(const Interpreter& other) : TransformerImpl(), ChartToFSM(other), _analyzer(NULL), _machinesAll(NULL), _parent(NULL), _parentTopMost(NULL), _machinesAllPerId(NULL) {} void initNodes(); diff --git a/test/ctest/CTestCustom.ctest.in b/test/ctest/CTestCustom.ctest.in index 484dcb2..1362ea5 100644 --- a/test/ctest/CTestCustom.ctest.in +++ b/test/ctest/CTestCustom.ctest.in @@ -63,8 +63,6 @@ set(CTEST_CUSTOM_TESTS_IGNORE "spin/promela/test151.scxml" # test that foreach causes a new variable to be declared "spin/promela/test152.scxml" # test that an illegal array or item value causes error.execution "spin/promela/test156.scxml" # test that an error causes the foreach to stop execution - # "spin/promela/test172.scxml" # targetexpr _internal - can we support? - "spin/promela/test224.scxml" # string operation startWith "spin/promela/test224.scxml" # string operation startWith "spin/promela/test277.scxml" # platform creates unbound variable if we assign an illegal value to it "spin/promela/test280.scxml" # late data binding / undeclared variable @@ -84,7 +82,6 @@ set(CTEST_CUSTOM_TESTS_IGNORE "spin/promela/test325.scxml" # assignment from _ioprocessor "spin/promela/test326.scxml" # assignment from _ioprocessor "spin/promela/test329.scxml" # test that none of the system variables can be modified - "spin/promela/test331.scxml" # assigment to a non-declared var "spin/promela/test344.scxml" # 'return' as a cond "spin/promela/test346.scxml" # assignment to system variables "spin/promela/test350.scxml" # string concatenation @@ -101,33 +98,29 @@ set(CTEST_CUSTOM_TESTS_IGNORE "spin/promela/test525.scxml" # assumes unbound arrays "spin/promela/test530.scxml" # assigns DOM node to variable "spin/promela/test534.scxml" # string operation contains - + # fail for semantics "spin/promela/test159.scxml" # error raised causes all subsequent elements to be skipped "spin/promela/test178.scxml" # manual test with two identical params - failed "spin/promela/test194.scxml" # illegal target for send "spin/promela/test199.scxml" # invalid send type - "spin/promela/test207.scxml" # delay / cancel / nested SCXML "spin/promela/test215.scxml" # nested SCXML document with typeexpr at invoke "spin/promela/test216.scxml" # nested SCXML document with srcexpr at invoke "spin/promela/test230.scxml" # nested SCXML document with manual test "spin/promela/test298.scxml" # non-existent data model location - "spin/promela/test332.scxml" # sendid is present in error events - "spin/promela/test338.scxml" # test that invokeid is set correctly + "spin/promela/test331.scxml" # tests _error.type via 'error.execution' + "spin/promela/test332.scxml" # tests _error.sendid via 'error.execution' "spin/promela/test343.scxml" # test that illegal produces error.execution "spin/promela/test488.scxml" # illegal expr in produces error.execution "spin/promela/test496.scxml" # tests error.communication with illegal target "spin/promela/test500.scxml" # uses _ioprocessors.scxml.location - "spin/promela/test510.scxml" # uses _ioprocessors.basichttp.location + "spin/promela/test513.txt" # pure manual wget "spin/promela/test521.scxml" # tests error.communication with illegal target - "spin/promela/test522.scxml" # uses _ioprocessors.basichttp.location "spin/promela/test528.scxml" # illegal 'expr' produces error.execution "spin/promela/test531.scxml" # uses _ioprocessors.basichttp.location "spin/promela/test532.scxml" # uses _ioprocessors.basichttp.location - "spin/promela/test552.scxml" # initialize data from file "spin/promela/test553.scxml" # error in namelist "spin/promela/test554.scxml" # evaluation of 's args causes an error - "spin/promela/test567.scxml" # uses _ioprocessors.basichttp.location "spin/promela/test577.scxml" # send without target for basichttp diff --git a/test/uscxml/test-initial-configuration.scxml b/test/uscxml/test-initial-configuration.scxml new file mode 100644 index 0000000..87c5796 --- /dev/null +++ b/test/uscxml/test-initial-configuration.scxml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/w3c/confPromela.xsl b/test/w3c/confPromela.xsl index e9094d8..ee67755 100644 --- a/test/w3c/confPromela.xsl +++ b/test/w3c/confPromela.xsl @@ -136,6 +136,10 @@ + + + + diff --git a/test/w3c/promela/test510.scxml b/test/w3c/promela/test510.scxml index fbb2f25..3ddda76 100644 --- a/test/w3c/promela/test510.scxml +++ b/test/w3c/promela/test510.scxml @@ -3,7 +3,7 @@ - + diff --git a/test/w3c/promela/test522.scxml b/test/w3c/promela/test522.scxml index e31c289..d56f257 100644 --- a/test/w3c/promela/test522.scxml +++ b/test/w3c/promela/test522.scxml @@ -4,7 +4,7 @@ to send a message to the processor --> - +