summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <sradomski@mintwerk.de>2016-04-28 07:18:24 (GMT)
committerStefan Radomski <sradomski@mintwerk.de>2016-04-28 07:18:24 (GMT)
commitaf6ec49c899ce26a0e07761b0e42200248808e21 (patch)
treec2c826e5db487de375dd312b3166b02396854aea
parentdfaff1e3e310cb0201a05915de23a893956b0609 (diff)
downloaduscxml-af6ec49c899ce26a0e07761b0e42200248808e21.zip
uscxml-af6ec49c899ce26a0e07761b0e42200248808e21.tar.gz
uscxml-af6ec49c899ce26a0e07761b0e42200248808e21.tar.bz2
Implemented empty finalize (Spec 6.5.2)
-rw-r--r--src/uscxml/Interpreter.cpp25
-rw-r--r--test/src/issues/test-issue67.scxml36
2 files changed, 60 insertions, 1 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 12f1c32..596bf20 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -2695,7 +2695,30 @@ void InterpreterImpl::finalizeAndAutoForwardCurrentEvent() {
Arabica::XPath::NodeSet<std::string> finalizes = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "finalize", invokeIter->second.getElement());
for (size_t k = 0; k < finalizes.size(); k++) {
Element<std::string> finalizeElem = Element<std::string>(finalizes[k]);
- executeContent(finalizeElem);
+
+ bool hasChildElems = false;
+ Node<std::string> child = finalizeElem.getFirstChild();
+ while(child) {
+ if (child.getNodeType() == Node_base::ELEMENT_NODE) {
+ hasChildElems = true;
+ break;
+ }
+ child = child.getNextSibling();
+ }
+
+ if (hasChildElems) {
+ executeContent(finalizeElem);
+ } else {
+ // Specification 6.5.2: http://www.w3.org/TR/scxml/#N110EF
+ if (HAS_ATTR(invokeIter->second.getElement(), "namelist")) {
+ std::list<std::string> names = tokenize(ATTR(invokeIter->second.getElement(), "namelist"));
+ for (std::list<std::string>::iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) {
+ if (_currEvent.data.compound.find(*nameIter) != _currEvent.data.compound.end()) {
+ _dataModel.assign(*nameIter, _currEvent.data.compound[*nameIter]);
+ }
+ }
+ }
+ }
}
}
if (HAS_ATTR(invokeIter->second.getElement(), "autoforward") && stringIsTrue(ATTR(invokeIter->second.getElement(), "autoforward"))) {
diff --git a/test/src/issues/test-issue67.scxml b/test/src/issues/test-issue67.scxml
new file mode 100644
index 0000000..e1fc5fa
--- /dev/null
+++ b/test/src/issues/test-issue67.scxml
@@ -0,0 +1,36 @@
+<scxml datamodel="lua" initial="main" name="root" version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
+ <datamodel>
+ <data expr="1" id="i_GLOBAL_VAR"/>
+ </datamodel>
+ <state id="main" initial="start">
+ <transition event="error.*" target="Fail"/>
+ <transition cond="i_GLOBAL_VAR==2" event="completed" target="Pass"/>
+ <transition event="completed" target="Fail"/>
+ <state id="start">
+ <invoke id="test_invoke" namelist="i_GLOBAL_VAR" type="scxml">
+ <content>
+ <scxml datamodel="lua" initial="InvokeStart" name="scxml_invoke" version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
+ <datamodel>
+ <data expr="0" id="i_GLOBAL_VAR"/>
+ </datamodel>
+ <final id="InvokeEnd">
+ <onentry>
+ <send event="completed" namelist="i_GLOBAL_VAR" target="#_parent"/>
+ </onentry>
+ </final>
+ <state id="InvokeStart">
+ <onentry>
+ <assign expr="i_GLOBAL_VAR*2" location="i_GLOBAL_VAR"/>
+ <log expr="i_GLOBAL_VAR" label="INVOKE-i_GLOBAL_VAR"/>
+ </onentry>
+ <transition target="InvokeEnd"/>
+ </state>
+ </scxml>
+ </content>
+ <finalize/>
+ </invoke>
+ </state>
+ </state>
+ <final id="Fail"/>
+ <final id="Pass"/>
+</scxml>