summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Radomski <sradomski@mintwerk.de>2016-01-19 22:08:38 (GMT)
committerStefan Radomski <sradomski@mintwerk.de>2016-01-19 22:08:38 (GMT)
commitb5abd34bfcc07588c7220d094a04dbc5708d344b (patch)
treea4a352a332ace04e5ce66fb29c4f8c9efd351af5 /src
parent024d82815dc6f2e2298fc8661424c25dd4c79d85 (diff)
downloaduscxml-b5abd34bfcc07588c7220d094a04dbc5708d344b.zip
uscxml-b5abd34bfcc07588c7220d094a04dbc5708d344b.tar.gz
uscxml-b5abd34bfcc07588c7220d094a04dbc5708d344b.tar.bz2
Fixed a bug in generated C with deep initial states
Diffstat (limited to 'src')
-rw-r--r--src/uscxml/DOMUtils.cpp5
-rw-r--r--src/uscxml/transform/ChartToC.cpp48
-rw-r--r--src/uscxml/transform/ChartToC.h2
3 files changed, 48 insertions, 7 deletions
diff --git a/src/uscxml/DOMUtils.cpp b/src/uscxml/DOMUtils.cpp
index 7e834f8..50548c3 100644
--- a/src/uscxml/DOMUtils.cpp
+++ b/src/uscxml/DOMUtils.cpp
@@ -39,7 +39,10 @@ std::string DOMUtils::idForNode(const Arabica::DOM::Node<std::string>& node) {
case Arabica::DOM::Node_base::ELEMENT_NODE: {
Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(curr);
if (HAS_ATTR(elem, "id") && !UUID::isUUID(ATTR(elem, "id"))) {
- nodeId.insert(0, ATTR(elem, "id") + seperator);
+ std::string elementId = ATTR(elem, "id");
+ boost::replace_all(elementId, ".", "_");
+ boost::replace_all(elementId, ",", "_");
+ nodeId.insert(0, elementId + seperator);
seperator = "_";
return nodeId;
} else {
diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp
index 94473f9..ec5c017 100644
--- a/src/uscxml/transform/ChartToC.cpp
+++ b/src/uscxml/transform/ChartToC.cpp
@@ -46,10 +46,46 @@ ChartToC::ChartToC(const Interpreter& other) : TransformerImpl() {
cloneFrom(other.getImpl());
}
+void ChartToC::resortStates(Arabica::DOM::Node<std::string>& node) {
+ if (node.getNodeType() != Node_base::ELEMENT_NODE)
+ return;
+
+ // move history states to top
+ Element<std::string> element(node);
+ Node<std::string> child = element.getFirstChild();
+ while(child) {
+ resortStates(child);
+ if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == _nsInfo.xmlNSPrefix + "history") {
+ Node<std::string> tmp = child.getNextSibling();
+ element.insertBefore(child, element.getFirstChild());
+ child = tmp;
+ } else {
+ child = child.getNextSibling();
+ }
+ }
+
+ // move initial states on top of histories even
+ child = element.getFirstChild();
+ while(child) {
+ resortStates(child);
+ if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == _nsInfo.xmlNSPrefix + "initial") {
+ Node<std::string> tmp = child.getNextSibling();
+ element.insertBefore(child, element.getFirstChild());
+ child = tmp;
+ } else {
+ child = child.getNextSibling();
+ }
+ }
+
+}
+
void ChartToC::writeTo(std::ostream& stream) {
_binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY);
_name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : "");
+ // make sure initial and history elements always precede propoer states
+
+
std::set<std::string> elements;
elements.insert(_nsInfo.xmlNSPrefix + "scxml");
elements.insert(_nsInfo.xmlNSPrefix + "state");
@@ -1496,16 +1532,16 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " break;" << std::endl;
stream << " }" << std::endl;
stream << " case SCXML_STATE_COMPOUND: { // we need to check whether one child is already in entry_set" << std::endl;
- stream << " if (!bit_has_and(entry_set, scxml_states[i].children, 1) &&" << std::endl;
- stream << " (!bit_has_and(ctx->config, scxml_states[i].children, 1) ||" << std::endl;
- stream << " bit_has_and(exit_set, scxml_states[i].children, 1)))" << std::endl;
+ stream << " if (!bit_has_and(entry_set, scxml_states[i].children, " << _stateCharArraySize << ") &&" << std::endl;
+ stream << " (!bit_has_and(ctx->config, scxml_states[i].children, " << _stateCharArraySize << ") ||" << std::endl;
+ stream << " bit_has_and(exit_set, scxml_states[i].children, " << _stateCharArraySize << ")))" << std::endl;
stream << " {" << std::endl;
- stream << " bit_or(entry_set, scxml_states[i].completion, 1);" << std::endl;
- stream << " if (!bit_has_and(scxml_states[i].completion, scxml_states[i].children, 1)) {" << std::endl;
+ stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
+ stream << " if (!bit_has_and(scxml_states[i].completion, scxml_states[i].children, " << _stateCharArraySize << ")) {" << std::endl;
stream << " // deep completion" << std::endl;
stream << " for (size_t j = 0; j < SCXML_NUMBER_STATES; j++) {" << std::endl;
stream << " if (IS_SET(j, scxml_states[i].completion)) {" << std::endl;
- stream << " bit_or(entry_set, scxml_states[j].ancestors, 1);" << std::endl;
+ stream << " bit_or(entry_set, scxml_states[j].ancestors, " << _stateCharArraySize << ");" << std::endl;
stream << " break; // completion of compound is single state" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h
index 1513235..7de6e00 100644
--- a/src/uscxml/transform/ChartToC.h
+++ b/src/uscxml/transform/ChartToC.h
@@ -71,6 +71,8 @@ protected:
Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::DOM::Element<std::string>& transition);
+ void resortStates(Arabica::DOM::Node<std::string>& node);
+
Interpreter interpreter;
Arabica::XPath::NodeSet<std::string> _states;