summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <sradomski@mintwerk.de>2016-01-26 08:32:56 (GMT)
committerStefan Radomski <sradomski@mintwerk.de>2016-01-26 08:32:56 (GMT)
commit18bca76b4f4d81db962e97cfe79611461a8b7e61 (patch)
tree5131964dc562082fc3274cea8de3aa25ec0d455e
parent762eb95910cd4dfad6a84f97332b7549b2fdbd69 (diff)
downloaduscxml-18bca76b4f4d81db962e97cfe79611461a8b7e61.zip
uscxml-18bca76b4f4d81db962e97cfe79611461a8b7e61.tar.gz
uscxml-18bca76b4f4d81db962e97cfe79611461a8b7e61.tar.bz2
Some code beautifications
-rw-r--r--README.md6
-rw-r--r--src/uscxml/DOMUtils.cpp6
-rw-r--r--src/uscxml/debug/InterpreterIssue.cpp6
-rw-r--r--src/uscxml/transform/ChartToC.cpp478
-rw-r--r--src/uscxml/transform/ChartToC.h4
-rw-r--r--test/src/test-c-machine.cpp16
-rw-r--r--test/src/test-c-machine.machine.c398
-rw-r--r--test/uscxml/automated/ecma/uncompleted-history.scxml11
8 files changed, 387 insertions, 538 deletions
diff --git a/README.md b/README.md
index 4dd1388..6e29edd 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
#### Related Documents
-- [Building form Source](docs/BUILDING.md)
+- [Building from Source](docs/BUILDING.md)
- [Open Issues](docs/ISSUES.md)
- [Getting Started](docs/GETTING_STARTED.md)
@@ -111,7 +111,7 @@ upon](https://github.com/tklab-tud/uscxml/blob/master/docs/BUILDING.md#build-dep
We did some performance measurements in the scope of the C transformation. As
you can see in the figure below, for most IRP tests we average to a duration of
-5-20us per microstep on an early 2015 MacBook Pro 13" with 3.1Ghz in the case
+5-20us per microstep on an early 2015 MacBook Pro 13" with 3.1GHz in the case
of [generated/compiled C](https://github.com/tklab-tud/uscxml/blob/master/test/src/test-c-machine.machine.c). For interpretation at runtime, we average at around 70-130us per
microstep. The generated C is rather optimized while the focus of the
interpreter is more on correctness, feature completeness and extensibility.
@@ -121,7 +121,7 @@ interpreter.
<img src="https://raw.github.com/tklab-tud/uscxml/master/docs/Performance_Microstep.png" width="500px" />
For the tests, we took the [highest precision timer](https://github.com/tklab-tud/uscxml/blob/master/src/uscxml/concurrency/Timer.cpp)
-we could attain and measured how long the execution of a given SCXML IRP tests took while
+we could attain and measured how long the execution of a given SCXML IRP test took while
subtracting initialization, tear-down and the time spent in the data-model's routines. Time is
averaged over 1.000 iterations.
diff --git a/src/uscxml/DOMUtils.cpp b/src/uscxml/DOMUtils.cpp
index 50548c3..9703432 100644
--- a/src/uscxml/DOMUtils.cpp
+++ b/src/uscxml/DOMUtils.cpp
@@ -39,9 +39,9 @@ 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"))) {
- std::string elementId = ATTR(elem, "id");
- boost::replace_all(elementId, ".", "_");
- boost::replace_all(elementId, ",", "_");
+ std::string elementId = ATTR(elem, "id");
+ boost::replace_all(elementId, ".", "_");
+ boost::replace_all(elementId, ",", "_");
nodeId.insert(0, elementId + seperator);
seperator = "_";
return nodeId;
diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp
index 5fb3965..6b97182 100644
--- a/src/uscxml/debug/InterpreterIssue.cpp
+++ b/src/uscxml/debug/InterpreterIssue.cpp
@@ -302,9 +302,9 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
NodeSet<std::string> transitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", state, false);
if (transitions.size() > 1) {
issues.push_back(InterpreterIssue("History pseudo-state with id '" + stateId + "' has multiple transitions", state, InterpreterIssue::USCXML_ISSUE_FATAL));
- } else if (transitions.size() == 0) {
- issues.push_back(InterpreterIssue("History pseudo-state with id '" + stateId + "' has no default transition", state, InterpreterIssue::USCXML_ISSUE_FATAL));
- } else {
+ } else if (transitions.size() == 0) {
+ issues.push_back(InterpreterIssue("History pseudo-state with id '" + stateId + "' has no default transition", state, InterpreterIssue::USCXML_ISSUE_FATAL));
+ } else {
Element<std::string> transition = Element<std::string>(transitions[0]);
if (HAS_ATTR(transition, "cond")) {
issues.push_back(InterpreterIssue("Transition in history pseudo-state '" + stateId + "' must not have a condition", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp
index e726d7f..2fc392a 100644
--- a/src/uscxml/transform/ChartToC.cpp
+++ b/src/uscxml/transform/ChartToC.cpp
@@ -36,6 +36,8 @@ namespace uscxml {
using namespace Arabica::DOM;
using namespace Arabica::XPath;
+// many more tricks: https://graphics.stanford.edu/~seander/bithacks.html
+
Transformer ChartToC::transform(const Interpreter& other) {
ChartToC* c2c = new ChartToC(other);
@@ -47,137 +49,137 @@ ChartToC::ChartToC(const Interpreter& other) : TransformerImpl() {
}
void ChartToC::setHistoryResponsibility(Arabica::DOM::Node<std::string>& node) {
- std::set<std::string> elements;
- elements.insert(_nsInfo.xmlNSPrefix + "history");
- Arabica::XPath::NodeSet<std::string> histories = inPostFixOrder(elements, _scxml);
-
- NodeSet<std::string> covered;
- NodeSet<std::string> perParentcovered;
- Node<std::string> parent;
-
- for (size_t i = 0; i < histories.size(); i++) {
- Element<std::string> history(histories[i]);
- NodeSet<std::string> completion;
-
- if (parent != history.getParentNode()) {
- covered.push_back(perParentcovered);
- perParentcovered = NodeSet<std::string>();
- parent = history.getParentNode();
- }
-
- bool deep = (HAS_ATTR(history, "type") && iequals(ATTR(history, "type"), "deep"));
- for (size_t j = 0; j < _states.size(); j++) {
- if (_states[j] == history)
- continue;
-
- if (isDescendant(_states[j], history.getParentNode()) && isHistory(Element<std::string>(_states[j]))) {
- history.setAttribute("hasNestedHistory", "true");
- }
-
- if (isMember(_states[j], covered))
- continue;
-
- if (deep) {
- if (isDescendant(_states[j], history.getParentNode()) && !isHistory(Element<std::string>(_states[j]))) {
- completion.push_back(_states[j]);
- }
- } else {
- if (_states[j].getParentNode() == history.getParentNode() && !isHistory(Element<std::string>(_states[j]))) {
- completion.push_back(_states[j]);
- }
- }
- }
- perParentcovered.push_back(completion);
-
- std::string respBools;
- std::string respBoolsIdx;
- for (size_t j = 0; j < _states.size(); j++) {
- if (isMember(_states[j], completion)) {
- respBools += "1";
- respBoolsIdx += " " + toStr(j);
- } else {
- respBools += "0";
- }
- }
- history.setAttribute("respBools", respBools);
- history.setAttribute("respBoolsIdx", respBoolsIdx);
- }
+ std::set<std::string> elements;
+ elements.insert(_nsInfo.xmlNSPrefix + "history");
+ Arabica::XPath::NodeSet<std::string> histories = inPostFixOrder(elements, _scxml);
+
+ NodeSet<std::string> covered;
+ NodeSet<std::string> perParentcovered;
+ Node<std::string> parent;
+
+ for (size_t i = 0; i < histories.size(); i++) {
+ Element<std::string> history(histories[i]);
+ NodeSet<std::string> completion;
+
+ if (parent != history.getParentNode()) {
+ covered.push_back(perParentcovered);
+ perParentcovered = NodeSet<std::string>();
+ parent = history.getParentNode();
+ }
+
+ bool deep = (HAS_ATTR(history, "type") && iequals(ATTR(history, "type"), "deep"));
+ for (size_t j = 0; j < _states.size(); j++) {
+ if (_states[j] == history)
+ continue;
+
+ if (isDescendant(_states[j], history.getParentNode()) && isHistory(Element<std::string>(_states[j]))) {
+ history.setAttribute("hasNestedHistory", "true");
+ }
+
+ if (isMember(_states[j], covered))
+ continue;
+
+ if (deep) {
+ if (isDescendant(_states[j], history.getParentNode()) && !isHistory(Element<std::string>(_states[j]))) {
+ completion.push_back(_states[j]);
+ }
+ } else {
+ if (_states[j].getParentNode() == history.getParentNode() && !isHistory(Element<std::string>(_states[j]))) {
+ completion.push_back(_states[j]);
+ }
+ }
+ }
+ perParentcovered.push_back(completion);
+
+ std::string respBools;
+ std::string respBoolsIdx;
+ for (size_t j = 0; j < _states.size(); j++) {
+ if (isMember(_states[j], completion)) {
+ respBools += "1";
+ respBoolsIdx += " " + toStr(j);
+ } else {
+ respBools += "0";
+ }
+ }
+ history.setAttribute("respBools", respBools);
+ history.setAttribute("respBoolsIdx", respBoolsIdx);
+ }
}
-
+
void ChartToC::resortStates(Arabica::DOM::Node<std::string>& node) {
- if (node.getNodeType() != Node_base::ELEMENT_NODE)
- return;
-
- /**
- initials
- deep histories
- shallow histories
- everything else
- */
-
- Element<std::string> element(node);
-
- // shallow history states to top
- Node<std::string> child = element.getFirstChild();
- while(child) {
- resortStates(child);
- if (child.getNodeType() == Node_base::ELEMENT_NODE &&
- TAGNAME_CAST(child) == _nsInfo.xmlNSPrefix + "history" &&
- (!HAS_ATTR(element, "type") || iequals(ATTR(element, "type"), "shallow"))) {
- Node<std::string> tmp = child.getNextSibling();
- if (child != element.getFirstChild()) {
- element.insertBefore(child, element.getFirstChild());
- }
- child = tmp;
- } else {
- child = child.getNextSibling();
- }
- }
-
- // deep history states to top
- child = element.getFirstChild();
- while(child) {
- resortStates(child);
- if (child.getNodeType() == Node_base::ELEMENT_NODE &&
- TAGNAME_CAST(child) == _nsInfo.xmlNSPrefix + "history" &&
- HAS_ATTR(element, "type") &&
- iequals(ATTR(element, "type"), "deep")) {
-
- Node<std::string> tmp = child.getNextSibling();
- if (child != element.getFirstChild()) {
- element.insertBefore(child, element.getFirstChild());
- }
- child = tmp;
- } else {
- child = child.getNextSibling();
- }
- }
-
- // 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();
- if (child != element.getFirstChild()) {
- element.insertBefore(child, element.getFirstChild());
- }
- child = tmp;
- } else {
- child = child.getNextSibling();
- }
- }
+ if (node.getNodeType() != Node_base::ELEMENT_NODE)
+ return;
+
+ /**
+ initials
+ deep histories
+ shallow histories
+ everything else
+ */
+
+ Element<std::string> element(node);
+
+ // shallow history states to top
+ Node<std::string> child = element.getFirstChild();
+ while(child) {
+ resortStates(child);
+ if (child.getNodeType() == Node_base::ELEMENT_NODE &&
+ TAGNAME_CAST(child) == _nsInfo.xmlNSPrefix + "history" &&
+ (!HAS_ATTR(element, "type") || iequals(ATTR(element, "type"), "shallow"))) {
+ Node<std::string> tmp = child.getNextSibling();
+ if (child != element.getFirstChild()) {
+ element.insertBefore(child, element.getFirstChild());
+ }
+ child = tmp;
+ } else {
+ child = child.getNextSibling();
+ }
+ }
+
+ // deep history states to top
+ child = element.getFirstChild();
+ while(child) {
+ resortStates(child);
+ if (child.getNodeType() == Node_base::ELEMENT_NODE &&
+ TAGNAME_CAST(child) == _nsInfo.xmlNSPrefix + "history" &&
+ HAS_ATTR(element, "type") &&
+ iequals(ATTR(element, "type"), "deep")) {
+
+ Node<std::string> tmp = child.getNextSibling();
+ if (child != element.getFirstChild()) {
+ element.insertBefore(child, element.getFirstChild());
+ }
+ child = tmp;
+ } else {
+ child = child.getNextSibling();
+ }
+ }
+
+ // 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();
+ if (child != element.getFirstChild()) {
+ 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
- resortStates(_scxml);
-
+ // make sure initial and history elements always precede propoer states
+ resortStates(_scxml);
+
std::set<std::string> elements;
elements.insert(_nsInfo.xmlNSPrefix + "scxml");
elements.insert(_nsInfo.xmlNSPrefix + "state");
@@ -246,8 +248,8 @@ void ChartToC::writeTo(std::ostream& stream) {
_transDataType = "uint64_t";
}
- // set the responsibility of history elements
- setHistoryResponsibility(_scxml);
+ // set the responsibility of history elements
+ setHistoryResponsibility(_scxml);
writeIncludes(stream);
writeMacros(stream);
@@ -270,9 +272,9 @@ void ChartToC::writeIncludes(std::ostream& stream) {
}
void ChartToC::writeMacros(std::ostream& stream) {
- stream << "#define IS_SET(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl;
- stream << "#define SET_BIT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl;
- stream << "#define CLEARBIT(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl;
+ stream << "#define BIT_HAS(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl;
+ stream << "#define BIT_SET_AT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl;
+ stream << "#define BIT_CLEAR(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl;
stream << std::endl;
stream << "#ifdef __GNUC__" << std::endl;
@@ -316,8 +318,8 @@ void ChartToC::writeMacros(std::ostream& stream) {
stream << "#define SCXML_STATE_HISTORY_SHALLOW 0x06" << std::endl;
stream << "#define SCXML_STATE_INITIAL 0x07" << std::endl;
stream << "#define SCXML_STATE_HAS_HISTORY 0x80 // highest bit" << std::endl;
- stream << "#define SCXML_STATE_MASK(t) (t & 0x7F) // mask highest bit" << std::endl;
-
+ stream << "#define SCXML_STATE_MASK(t) (t & 0x7F) // mask highest bit" << std::endl;
+
stream << "" << std::endl;
stream << "#define SCXML_CTX_PRISTINE 0x00" << std::endl;
stream << "#define SCXML_CTX_SPONTANEOUS 0x01" << std::endl;
@@ -498,7 +500,7 @@ void ChartToC::writeHelpers(std::ostream& stream) {
stream << "static void printStateNames(const char* a) {" << std::endl;
stream << " const char* seperator = \"\";" << std::endl;
stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl;
- stream << " if (IS_SET(i, a)) {" << std::endl;
+ stream << " if (BIT_HAS(i, a)) {" << std::endl;
stream << " printf(\"%s%s\", seperator, (scxml_states[i].name != NULL ? scxml_states[i].name : \"UNK\"));" << std::endl;
stream << " seperator = \", \";" << std::endl;
stream << " }" << std::endl;
@@ -510,7 +512,7 @@ void ChartToC::writeHelpers(std::ostream& stream) {
stream << "static void printBitsetIndices(const char* a, size_t length) {" << std::endl;
stream << " const char* seperator = \"\";" << std::endl;
stream << " for (size_t i = 0; i < length; i++) {" << std::endl;
- stream << " if (IS_SET(i, a)) {" << std::endl;
+ stream << " if (BIT_HAS(i, a)) {" << std::endl;
stream << " printf(\"%s%lu\", seperator, i);" << std::endl;
stream << " seperator = \", \";" << std::endl;
stream << " }" << std::endl;
@@ -521,49 +523,49 @@ void ChartToC::writeHelpers(std::ostream& stream) {
stream << "#endif" << std::endl;
stream << std::endl;
- stream << "static void bit_or(char* dest, const char* mask, size_t i) {" << std::endl;
+ stream << "static int bit_has_and(const char* a, const char* b, size_t i) {" << std::endl;
stream << " do {" << std::endl;
- stream << " dest[i - 1] |= mask[i - 1];" << std::endl;
+ stream << " if (a[i - 1] & b[i - 1])" << std::endl;
+ stream << " return true;" << std::endl;
stream << " } while(--i);" << std::endl;
+ stream << " return false;" << std::endl;
stream << "}" << std::endl;
stream << std::endl;
- stream << "static void bit_copy(char* dest, const char* source, size_t i) {" << std::endl;
+ stream << "static int bit_has_any(const char* a, size_t i) {" << std::endl;
stream << " do {" << std::endl;
- stream << " dest[i - 1] = source[i - 1];" << std::endl;
+ stream << " if (a[i - 1] > 0)" << std::endl;
+ stream << " return true;" << std::endl;
stream << " } while(--i);" << std::endl;
+ stream << " return false;" << std::endl;
stream << "}" << std::endl;
stream << std::endl;
- stream << "static int bit_has_and(const char* a, const char* b, size_t i) {" << std::endl;
+ stream << "static void bit_or(char* dest, const char* mask, size_t i) {" << std::endl;
stream << " do {" << std::endl;
- stream << " if (a[i - 1] & b[i - 1])" << std::endl;
- stream << " return true;" << std::endl;
+ stream << " dest[i - 1] |= mask[i - 1];" << std::endl;
stream << " } while(--i);" << std::endl;
- stream << " return false;" << std::endl;
stream << "}" << std::endl;
stream << std::endl;
- stream << "static void bit_and_not(char* dest, const char* mask, size_t i) {" << std::endl;
+ stream << "static void bit_copy(char* dest, const char* source, size_t i) {" << std::endl;
stream << " do {" << std::endl;
- stream << " dest[i - 1] &= ~mask[i - 1];" << std::endl;
+ stream << " dest[i - 1] = source[i - 1];" << std::endl;
stream << " } while(--i);" << std::endl;
stream << "}" << std::endl;
stream << std::endl;
- stream << "static void bit_and(char* dest, const char* mask, size_t i) {" << std::endl;
+ stream << "static void bit_and_not(char* dest, const char* mask, size_t i) {" << std::endl;
stream << " do {" << std::endl;
- stream << " dest[i - 1] &= mask[i - 1];" << std::endl;
+ stream << " dest[i - 1] &= ~mask[i - 1];" << std::endl;
stream << " } while(--i);" << std::endl;
stream << "}" << std::endl;
stream << std::endl;
- stream << "static int bit_any_set(const char* a, size_t i) {" << std::endl;
+ stream << "static void bit_and(char* dest, const char* mask, size_t i) {" << std::endl;
stream << " do {" << std::endl;
- stream << " if (a[i - 1] > 0)" << std::endl;
- stream << " return true;" << std::endl;
+ stream << " dest[i - 1] &= mask[i - 1];" << std::endl;
stream << " } while(--i);" << std::endl;
- stream << " return false;" << std::endl;
stream << "}" << std::endl;
stream << std::endl;
@@ -624,12 +626,12 @@ void ChartToC::writeExecContent(std::ostream& stream) {
stream << std::endl;
}
- /*
- gen/c/ecma/test412.scxml (Failed)
- gen/c/ecma/test579.scxml (Failed)
- */
+ /*
+ gen/c/ecma/test412.scxml (Failed)
+ gen/c/ecma/test579.scxml (Failed)
+ */
#if 0
- bool hasInitialState = false;
+ bool hasInitialState = false;
NodeSet<std::string> initial = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state);
if (initial.size() > 0) {
NodeSet<std::string> initialTransition = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial);
@@ -1098,15 +1100,15 @@ void ChartToC::writeStates(std::ostream& stream) {
stream << "," << std::endl;
// children
- bool hasHistoryChild = false;
+ bool hasHistoryChild = false;
std::string childBools;
std::string childBoolsIdx;
for (size_t j = 0; j < _states.size(); j++) {
if (_states[j].getParentNode() == state) {
- if (isHistory(Element<std::string>(_states[j]))) {
- hasHistoryChild = true;
- }
- childBools += "1";
+ if (isHistory(Element<std::string>(_states[j]))) {
+ hasHistoryChild = true;
+ }
+ childBools += "1";
childBoolsIdx += " " + toStr(j);
} else {
childBools += "0";
@@ -1118,16 +1120,16 @@ void ChartToC::writeStates(std::ostream& stream) {
stream << " }," << std::endl;
// default completion
- std::string descBools;
- std::string descBoolsIdx;
+ std::string descBools;
+ std::string descBoolsIdx;
NodeSet<std::string> completion;
if (isHistory(state)) {
- // we already precalculated everything
- descBools = ATTR(state, "respBools");
- descBoolsIdx = ATTR(state, "respBoolsIdx");
- hasHistoryChild = HAS_ATTR(state, "hasNestedHistory");
- goto WRITE_COMPLETION;
+ // we already precalculated everything
+ descBools = ATTR(state, "respBools");
+ descBoolsIdx = ATTR(state, "respBoolsIdx");
+ hasHistoryChild = HAS_ATTR(state, "hasNestedHistory");
+ goto WRITE_COMPLETION;
}
if (isParallel(state)) {
completion = getChildStates(state);
@@ -1161,8 +1163,8 @@ void ChartToC::writeStates(std::ostream& stream) {
descBools += "0";
}
}
- WRITE_COMPLETION:
-
+WRITE_COMPLETION:
+
stream << " /* completion */ { ";
writeCharArrayInitList(stream, descBools);
stream << " /* " << descBools << "," << descBoolsIdx << " */";
@@ -1209,10 +1211,10 @@ void ChartToC::writeStates(std::ostream& stream) {
} else { // <scxml>
stream << "SCXML_STATE_COMPOUND";
}
- if (hasHistoryChild) {
- stream << " | SCXML_STATE_HAS_HISTORY";
- }
-
+ if (hasHistoryChild) {
+ stream << " | SCXML_STATE_HAS_HISTORY";
+ }
+
stream << "," << std::endl;
stream << " }" << (i + 1 < _states.size() ? ",": "") << std::endl;
@@ -1229,7 +1231,7 @@ void ChartToC::writeTransitions(std::ostream& stream) {
elements.insert(_nsInfo.xmlNSPrefix + "transition");
NodeSet<std::string> transDocOrder = inDocumentOrder(elements, _scxml);
- std::stringstream transDocOrderSS;
+ std::stringstream transDocOrderSS;
std::string seperator = "";
for (size_t i = 0; i < transDocOrder.size(); i++) {
Element<std::string> transition(_transitions[i]);
@@ -1239,18 +1241,18 @@ void ChartToC::writeTransitions(std::ostream& stream) {
}
#if 0
- stream << "static const " << _transDataType << " scxml_transitions_doc_order[" << toStr(_transitions.size()) << "] = {" << std::endl;
- stream << " " << transDocOrderSS;
- stream << std::endl << "};" << std::endl;
- stream << std::endl;
+ stream << "static const " << _transDataType << " scxml_transitions_doc_order[" << toStr(_transitions.size()) << "] = {" << std::endl;
+ stream << " " << transDocOrderSS;
+ stream << std::endl << "};" << std::endl;
+ stream << std::endl;
#endif
stream << "static const scxml_transition scxml_transitions[" << toStr(_transitions.size()) << "] = {" << std::endl;
for (size_t i = 0; i < _transitions.size(); i++) {
Element<std::string> transition(_transitions[i]);
- stream << " { /* transition number " << ATTR(transition, "documentOrder") << " with priority " << toStr(i) << std::endl;
- stream << " target: " << ATTR(transition, "target") << std::endl;
- stream << " */" << std::endl;
+ stream << " { /* transition number " << ATTR(transition, "documentOrder") << " with priority " << toStr(i) << std::endl;
+ stream << " target: " << ATTR(transition, "target") << std::endl;
+ stream << " */" << std::endl;
/**
uint16_t source;
@@ -1264,7 +1266,7 @@ void ChartToC::writeTransitions(std::ostream& stream) {
*/
// source
- stream << " /* name */ ";
+ stream << " /* source */ ";
stream << ATTR_CAST(transition.getParentNode(), "documentOrder");
stream << "," << std::endl;
@@ -1461,7 +1463,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << std::endl;
stream << "// MACRO_STEP:" << std::endl;
- stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl;
+// stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl;
stream << std::endl;
stream << " if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL) " << std::endl;
@@ -1474,6 +1476,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " char exit_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
stream << " char trans_set[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl;
stream << " char entry_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
+ stream << " char tmp_states[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
stream << std::endl;
stream << " if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {" << std::endl;
@@ -1503,9 +1506,9 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " continue;" << std::endl;
stream << std::endl;
stream << " // is the transition active?" << std::endl;
- stream << " if (IS_SET(scxml_transitions[i].source, ctx->config)) {" << std::endl;
+ stream << " if (BIT_HAS(scxml_transitions[i].source, ctx->config)) {" << std::endl;
stream << " // is it non-conflicting?" << std::endl;
- stream << " if (!IS_SET(i, conflicts)) {" << std::endl;
+ stream << " if (!BIT_HAS(i, conflicts)) {" << std::endl;
stream << " // is it enabled?" << std::endl;
stream << " if (ctx->is_enabled(ctx, &scxml_transitions[i], ctx->event) > 0) {" << std::endl;
stream << " // remember that we found a transition" << std::endl;
@@ -1521,7 +1524,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " // states that will be left" << std::endl;
stream << " bit_or(exit_set, scxml_transitions[i].exit_set, " << _stateCharArraySize << ");" << std::endl;
stream << std::endl;
- stream << " SET_BIT(i, trans_set);" << std::endl;
+ stream << " BIT_SET_AT(i, trans_set);" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
@@ -1531,6 +1534,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) {" << std::endl;
stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS;" << std::endl;
+ stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl;
stream << " } else {" << std::endl;
stream << " ctx->flags &= ~SCXML_CTX_SPONTANEOUS;" << std::endl;
// stream << " return SCXML_ERR_OK;" << std::endl;
@@ -1558,20 +1562,19 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << "// REMEMBER_HISTORY:" << std::endl;
stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl;
stream << " if unlikely(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl;
- stream << " SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP) {" << std::endl;
+ stream << " SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP) {" << std::endl;
stream << " // a history state whose parent is about to be exited" << std::endl;
- stream << " if unlikely(IS_SET(scxml_states[i].parent, exit_set)) {" << std::endl;
- stream << " char history[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
- stream << " bit_copy(history, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
+ stream << " if unlikely(BIT_HAS(scxml_states[i].parent, exit_set)) {" << std::endl;
+ stream << " bit_copy(tmp_states, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
stream << std::endl;
stream << " // set those states who were enabled" << std::endl;
- stream << " bit_and(history, ctx->config, " << _stateCharArraySize << ");" << std::endl;
+ stream << " bit_and(tmp_states, ctx->config, " << _stateCharArraySize << ");" << std::endl;
stream << std::endl;
- stream << " // clear current history with completion mask - TODO: errornously clears nested history" << std::endl;
+ stream << " // clear current history with completion mask" << std::endl;
stream << " bit_and_not(ctx->history, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
stream << std::endl;
stream << " // set history" << std::endl;
- stream << " bit_or(ctx->history, history, " << _stateCharArraySize << ");" << std::endl;
+ stream << " bit_or(ctx->history, tmp_states, " << _stateCharArraySize << ");" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
@@ -1583,7 +1586,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << std::endl;
stream << " // iterate for ancestors" << std::endl;
stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl;
- stream << " if (IS_SET(i, entry_set)) {" << std::endl;
+ stream << " if (BIT_HAS(i, entry_set)) {" << std::endl;
stream << " bit_or(entry_set, scxml_states[i].ancestors, " << _stateCharArraySize << ");" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
@@ -1591,7 +1594,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " // iterate for descendants" << std::endl;
stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl;
- stream << " if (IS_SET(i, entry_set)) {" << std::endl;
+ stream << " if (BIT_HAS(i, entry_set)) {" << std::endl;
stream << " switch (SCXML_STATE_MASK(scxml_states[i].type)) {" << std::endl;
stream << " case SCXML_STATE_PARALLEL: {" << std::endl;
stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
@@ -1599,35 +1602,43 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " }" << std::endl;
stream << " case SCXML_STATE_HISTORY_SHALLOW:" << std::endl;
stream << " case SCXML_STATE_HISTORY_DEEP: {" << std::endl;
- stream << " char history_targets[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
stream << " if (!bit_has_and(scxml_states[i].completion, ctx->history, " << _stateCharArraySize << ") &&" << std::endl;
- stream << " !IS_SET(scxml_states[i].parent, ctx->config)) {" << std::endl;
- stream << " // nothing set for history, look for a default transition or enter parents completion" << std::endl;
+ stream << " !BIT_HAS(scxml_states[i].parent, ctx->config)) {" << std::endl;
+ stream << " // nothing set for history, look for a default transition" << std::endl;
stream << " for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl;
stream << " if unlikely(scxml_transitions[j].source == i) {" << std::endl;
stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl;
- stream << " SET_BIT(j, trans_set);" << std::endl;
+ stream << " if(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP &&" << std::endl;
+ stream << " !bit_has_and(scxml_transitions[j].target, scxml_states[i].children, " << _stateCharArraySize << ")) {" << std::endl;
+ stream << " for (size_t k = i + 1; k < SCXML_NUMBER_STATES; k++) {" << std::endl;
+ stream << " if (BIT_HAS(k, scxml_transitions[j].target)) {" << std::endl;
+ stream << " bit_or(entry_set, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " BIT_SET_AT(j, trans_set);" << std::endl;
stream << " break;" << std::endl;
stream << " }" << std::endl;
- stream << " // Note: SCXML mandates every history to have a transition!" << std::endl;
+ stream << " // Note: SCXML mandates every history to have a transition!" << std::endl;
stream << " }" << std::endl;
stream << " } else {" << std::endl;
- stream << " bit_copy(history_targets, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
- stream << " bit_and(history_targets, ctx->history, " << _stateCharArraySize << ");" << std::endl;
- stream << " bit_or(entry_set, history_targets, " << _stateCharArraySize << ");" << std::endl;
- stream << " if (scxml_states[i].type == (SCXML_STATE_HAS_HISTORY | SCXML_STATE_HISTORY_DEEP)) {" << std::endl;
+ stream << " bit_copy(tmp_states, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
+ stream << " bit_and(tmp_states, ctx->history, " << _stateCharArraySize << ");" << std::endl;
+ stream << " bit_or(entry_set, tmp_states, " << _stateCharArraySize << ");" << std::endl;
+ stream << " if (scxml_states[i].type == (SCXML_STATE_HAS_HISTORY | SCXML_STATE_HISTORY_DEEP)) {" << std::endl;
stream << " // a deep history state with nested histories -> more completion" << std::endl;
stream << " for (size_t j = i + 1; j < SCXML_NUMBER_STATES; j++) {" << std::endl;
- stream << " if (IS_SET(j, scxml_states[i].completion) &&" << std::endl;
- stream << " IS_SET(j, entry_set) &&" << std::endl;
+ stream << " if (BIT_HAS(j, scxml_states[i].completion) &&" << std::endl;
+ stream << " BIT_HAS(j, entry_set) &&" << std::endl;
stream << " (scxml_states[j].type & SCXML_STATE_HAS_HISTORY)) {" << std::endl;
stream << " for (size_t k = j + 1; k < SCXML_NUMBER_STATES; k++) {" << std::endl;
stream << " // add nested history to entry_set" << std::endl;
stream << " if ((SCXML_STATE_MASK(scxml_states[k].type) == SCXML_STATE_HISTORY_DEEP ||" << std::endl;
stream << " SCXML_STATE_MASK(scxml_states[k].type) == SCXML_STATE_HISTORY_SHALLOW) &&" << std::endl;
- stream << " IS_SET(k, scxml_states[j].children)) {" << std::endl;
+ stream << " BIT_HAS(k, scxml_states[j].children)) {" << std::endl;
stream << " // a nested history state" << std::endl;
- stream << " SET_BIT(k, entry_set);" << std::endl;
+ stream << " BIT_SET_AT(k, entry_set);" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
@@ -1639,15 +1650,15 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " case SCXML_STATE_INITIAL: {" << std::endl;
stream << " for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl;
stream << " if (scxml_transitions[j].source == i) {" << std::endl;
- stream << " SET_BIT(j, trans_set);" << std::endl;
- stream << " CLEARBIT(i, entry_set);" << std::endl;
+ stream << " BIT_SET_AT(j, trans_set);" << std::endl;
+ stream << " BIT_CLEAR(i, entry_set);" << std::endl;
stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl;
stream << " for (size_t k = i + 1; k < SCXML_NUMBER_STATES; k++) {" << std::endl;
- stream << " if (IS_SET(k, scxml_transitions[j].target)) {" << std::endl;
+ stream << " if (BIT_HAS(k, scxml_transitions[j].target)) {" << std::endl;
stream << " bit_or(entry_set, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
- stream << " }" << std::endl;
+ stream << " }" << std::endl;
stream << " }" << std::endl;
stream << " break;" << std::endl;
stream << " }" << std::endl;
@@ -1660,7 +1671,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
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 = i + 1; j < SCXML_NUMBER_STATES; j++) {" << std::endl;
- stream << " if (IS_SET(j, scxml_states[i].completion)) {" << std::endl;
+ stream << " if (BIT_HAS(j, scxml_states[i].completion)) {" << 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;
@@ -1683,20 +1694,20 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << "// EXIT_STATES:" << std::endl;
stream << " size_t i = SCXML_NUMBER_STATES;" << std::endl;
stream << " while(i-- > 0) {" << std::endl;
- stream << " if (IS_SET(i, exit_set) && IS_SET(i, ctx->config)) {" << std::endl;
+ stream << " if (BIT_HAS(i, exit_set) && BIT_HAS(i, ctx->config)) {" << std::endl;
stream << " // call all on exit handlers" << std::endl;
stream << " if (scxml_states[i].on_exit != NULL) {" << std::endl;
stream << " if unlikely((err = scxml_states[i].on_exit(ctx, &scxml_states[i], ctx->event)) != SCXML_ERR_OK)" << std::endl;
stream << " return err;" << std::endl;
stream << " }" << std::endl;
- stream << " CLEARBIT(i, ctx->config);" << std::endl;
+ stream << " BIT_CLEAR(i, ctx->config);" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
stream << std::endl;
stream << "// TAKE_TRANSITIONS:" << std::endl;
stream << " for (size_t i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl;
- stream << " if (IS_SET(i, trans_set) && (scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) == 0) {" << std::endl;
+ stream << " if (BIT_HAS(i, trans_set) && (scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) == 0) {" << std::endl;
stream << " // call executable content in transition" << std::endl;
stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl;
stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl;
@@ -1716,7 +1727,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << "// ENTER_STATES:" << std::endl;
stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl;
- stream << " if (IS_SET(i, entry_set) && !IS_SET(i, ctx->config)) {" << std::endl;
+ stream << " if (BIT_HAS(i, entry_set) && !BIT_HAS(i, ctx->config)) {" << std::endl;
stream << " // these are no proper states" << std::endl;
stream << " if unlikely(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP ||" << std::endl;
stream << " SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl;
@@ -1724,15 +1735,15 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " continue;" << std::endl;
stream << std::endl;
- stream << " SET_BIT(i, ctx->config);" << std::endl;
+ stream << " BIT_SET_AT(i, ctx->config);" << std::endl;
stream << std::endl;
stream << " // initialize data" << std::endl;
- stream << " if (!IS_SET(i, ctx->initialized_data)) {" << std::endl;
+ stream << " if (!BIT_HAS(i, ctx->initialized_data)) {" << std::endl;
stream << " if unlikely(scxml_states[i].data != NULL && ctx->exec_content_init != NULL) {" << std::endl;
stream << " ctx->exec_content_init(ctx, scxml_states[i].data);" << std::endl;
stream << " }" << std::endl;
- stream << " SET_BIT(i, ctx->initialized_data);" << std::endl;
+ stream << " BIT_SET_AT(i, ctx->initialized_data);" << std::endl;
stream << " }" << std::endl;
stream << std::endl;
@@ -1744,7 +1755,7 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " // take history and initial transitions" << std::endl;
stream << " for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl;
- stream << " if unlikely(IS_SET(j, trans_set) &&" << std::endl;
+ stream << " if unlikely(BIT_HAS(j, trans_set) &&" << std::endl;
stream << " (scxml_transitions[j].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) &&" << std::endl;
stream << " scxml_states[scxml_transitions[j].source].parent == i) {" << std::endl;
stream << " // call executable content in transition" << std::endl;
@@ -1782,20 +1793,20 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " * 4. If a state remains, not all children of a parallel are final" << std::endl;
stream << " */" << std::endl;
stream << " for (size_t j = 0; j < SCXML_NUMBER_STATES; j++) {" << std::endl;
- stream << " if unlikely(SCXML_STATE_MASK(scxml_states[j].type) == SCXML_STATE_PARALLEL) {" << std::endl;
- stream << " char parallel_children[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
- stream << " size_t parallel = j;" << std::endl;
+ stream << " if unlikely(SCXML_STATE_MASK(scxml_states[j].type) == SCXML_STATE_PARALLEL &&" << std::endl;
+ stream << " BIT_HAS(j, scxml_states[i].ancestors)) {" << std::endl;
+ stream << " bit_and_not(tmp_states, tmp_states, " << _stateCharArraySize << ");" << std::endl;
stream << " for (size_t k = 0; k < SCXML_NUMBER_STATES; k++) {" << std::endl;
- stream << " if unlikely(IS_SET(parallel, scxml_states[k].ancestors) && IS_SET(k, ctx->config)) {" << std::endl;
+ stream << " if unlikely(BIT_HAS(j, scxml_states[k].ancestors) && BIT_HAS(k, ctx->config)) {" << std::endl;
stream << " if (SCXML_STATE_MASK(scxml_states[k].type) == SCXML_STATE_FINAL) {" << std::endl;
- stream << " bit_and_not(parallel_children, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl;
+ stream << " bit_and_not(tmp_states, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl;
stream << " } else {" << std::endl;
- stream << " SET_BIT(k, parallel_children);" << std::endl;
+ stream << " BIT_SET_AT(k, tmp_states);" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
- stream << " if unlikely(!bit_any_set(parallel_children, " << _stateCharArraySize << ")) {" << std::endl;
- stream << " ctx->raise_done_event(ctx, &scxml_states[parallel], NULL);" << std::endl;
+ stream << " if unlikely(!bit_has_any(tmp_states, " << _stateCharArraySize << ")) {" << std::endl;
+ stream << " ctx->raise_done_event(ctx, &scxml_states[j], NULL);" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
stream << " }" << std::endl;
@@ -1808,21 +1819,6 @@ void ChartToC::writeFSM(std::ostream& stream) {
stream << " }" << std::endl;
stream << std::endl;
-// stream << "// HISTORY_TRANSITIONS:" << std::endl;
-// stream << " for (size_t i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl;
-// stream << " if unlikely(IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY)) {" << std::endl;
-// stream << " // call executable content in transition" << std::endl;
-// stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl;
-// stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl;
-// stream << " &scxml_states[scxml_transitions[i].source]," << std::endl;
-// stream << " ctx->event)) != SCXML_ERR_OK)" << std::endl;
-// stream << " return err;" << std::endl;
-// stream << " }" << std::endl;
-// stream << " }" << std::endl;
-// stream << " }" << std::endl;
-// stream << std::endl;
-
-
stream << " return SCXML_ERR_OK;" << std::endl;
stream << "}" << std::endl;
stream << std::endl;
diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h
index 74363dd..954aa63 100644
--- a/src/uscxml/transform/ChartToC.h
+++ b/src/uscxml/transform/ChartToC.h
@@ -71,8 +71,8 @@ protected:
Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::DOM::Element<std::string>& transition);
- void resortStates(Arabica::DOM::Node<std::string>& node);
- void setHistoryResponsibility(Arabica::DOM::Node<std::string>& node);
+ void resortStates(Arabica::DOM::Node<std::string>& node);
+ void setHistoryResponsibility(Arabica::DOM::Node<std::string>& node);
Interpreter interpreter;
diff --git a/test/src/test-c-machine.cpp b/test/src/test-c-machine.cpp
index 33c149a..11bb1c7 100644
--- a/test/src/test-c-machine.cpp
+++ b/test/src/test-c-machine.cpp
@@ -60,7 +60,7 @@ public:
}
bool isInState(const std::string& stateId) {
for (int i = 0 ; i < SCXML_NUMBER_STATES; i++) {
- if (scxml_states[i].name != NULL && IS_SET(i, ctx->config) && stateId == scxml_states[i].name)
+ if (scxml_states[i].name != NULL && BIT_HAS(i, ctx->config) && stateId == scxml_states[i].name)
return true;
}
return false;
@@ -217,9 +217,9 @@ void delayedSend(void* ctx, std::string eventName) {
tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex);
SendRequest* sr = USER_DATA(ctx)->sendIds[eventName];
- Event* e = new Event(*sr);
-
- if (sr->target == "#_internal") {
+ Event* e = new Event(*sr);
+
+ if (sr->target == "#_internal") {
e->eventType = Event::INTERNAL;
#ifdef SCXML_VERBOSE
printf("Pushing Internal Event: %s\n", e->name.c_str());
@@ -233,7 +233,7 @@ void delayedSend(void* ctx, std::string eventName) {
USER_DATA(ctx)->eq.push_back(e);
}
USER_DATA(ctx)->monitor.notify_all();
- delete sr;
+ delete sr;
}
int exec_content_cancel(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr) {
@@ -305,7 +305,7 @@ int exec_content_send(const scxml_ctx* ctx, const scxml_elem_send* send) {
}
} catch (Event exc) {
exec_content_raise(ctx, exc.name.c_str());
- delete e;
+ delete e;
return SCXML_ERR_EXEC_CONTENT;
}
@@ -371,7 +371,7 @@ int exec_content_send(const scxml_ctx* ctx, const scxml_elem_send* send) {
}
}
- std::string sendid;
+ std::string sendid;
if (send->id != NULL) {
sendid = send->id;
e->sendid = sendid;
@@ -661,7 +661,7 @@ int main(int argc, char** argv) {
}
}
- if(!IS_SET(passIdx, ctx.config)) {
+ if(!BIT_HAS(passIdx, ctx.config)) {
std::cerr << "Interpreter did not end in pass" << std::endl;
exit(EXIT_FAILURE);
}
diff --git a/test/src/test-c-machine.machine.c b/test/src/test-c-machine.machine.c
index 09e7703..2b991ff 100644
--- a/test/src/test-c-machine.machine.c
+++ b/test/src/test-c-machine.machine.c
@@ -1,9 +1,9 @@
#include <stdint.h> // explicit types
#include <stddef.h> // NULL
-#define IS_SET(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)
-#define SET_BIT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));
-#define CLEARBIT(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;
+#define BIT_HAS(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)
+#define BIT_SET_AT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));
+#define BIT_CLEAR(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;
#ifdef __GNUC__
#define likely(x) (__builtin_expect(!!(x), 1))
@@ -25,8 +25,8 @@
#define SCXML_ERR_UNSUPPORTED 8
#define SCXML_MACHINE_NAME ""
-#define SCXML_NUMBER_STATES 10
-#define SCXML_NUMBER_TRANSITIONS 5
+#define SCXML_NUMBER_STATES 5
+#define SCXML_NUMBER_TRANSITIONS 1
#define SCXML_TRANS_SPONTANEOUS 0x01
#define SCXML_TRANS_TARGETLESS 0x02
@@ -99,22 +99,22 @@ struct scxml_state {
const exec_content_t on_entry; // on entry handlers
const exec_content_t on_exit; // on exit handlers
const invoke_t invoke; // invocations
- const char children[2]; // all children
- const char completion[2]; // default completion
- const char ancestors[2]; // all ancestors
+ const char children[1]; // all children
+ const char completion[1]; // default completion
+ const char ancestors[1]; // all ancestors
const scxml_elem_data* data;
const uint8_t type; // atomic, parallel, compound, final, history
};
struct scxml_transition {
const uint8_t source;
- const char target[2];
+ const char target[1];
const char* event;
const char* condition;
const exec_content_t on_transition;
const uint8_t type;
const char conflicts[1];
- const char exit_set[2];
+ const char exit_set[1];
};
struct scxml_elem_foreach {
@@ -171,10 +171,10 @@ struct scxml_elem_send {
struct scxml_ctx {
uint8_t flags;
- char config[2];
- char history[2];
- char pending_invokes[2];
- char initialized_data[2];
+ char config[1];
+ char history[1];
+ char pending_invokes[1];
+ char initialized_data[1];
void* user_data;
void* event;
@@ -198,12 +198,6 @@ struct scxml_ctx {
invoke_t invoke;
};
-static const scxml_elem_data scxml_elem_datas[2] = {
- /* id, src, expr, content */
- { "Var1", NULL, "0", NULL },
- { NULL, NULL, NULL, NULL }
-};
-
static const scxml_elem_donedata scxml_elem_donedatas[1] = {
/* source, content, contentexpr, params */
{ 0, NULL, NULL, NULL }
@@ -213,47 +207,17 @@ static int global_script(const scxml_ctx* ctx, const scxml_state* state, const v
return SCXML_ERR_OK;
}
-static int s0_0_0_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) {
- int err = SCXML_ERR_OK;
- if likely(ctx->exec_content_assign != NULL) {
- if ((ctx->exec_content_assign(ctx, "Var1", "Var1 + 1")) != SCXML_ERR_OK) return err;
- } else {
- return SCXML_ERR_MISSING_CALLBACK;
- }
- return SCXML_ERR_OK;
-}
-
-static int s0_0_0_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) {
- s0_0_0_on_entry_0(ctx, state, event);
- return SCXML_ERR_OK;
-}
-
-static int s1_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) {
- int err = SCXML_ERR_OK;
- if likely(ctx->exec_content_assign != NULL) {
- if ((ctx->exec_content_assign(ctx, "Var1", "Var1 + 1")) != SCXML_ERR_OK) return err;
- } else {
- return SCXML_ERR_MISSING_CALLBACK;
- }
- return SCXML_ERR_OK;
-}
-
-static int s1_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) {
- s1_on_entry_0(ctx, state, event);
- return SCXML_ERR_OK;
-}
-
-static const scxml_state scxml_states[10] = {
+static const scxml_state scxml_states[5] = {
{ /* state number 0 */
/* name */ NULL,
/* parent */ 0,
/* onentry */ NULL,
/* onexit */ NULL,
/* invoke */ NULL,
- /* children */ { 0x82, 0x03 /* 0100000111, 1 7 8 9 */ },
- /* completion */ { 0x02, 0x00 /* 0100000000, 1 */ },
- /* ancestors */ { 0x00, 0x00 /* 0000000000, */ },
- /* data */ &scxml_elem_datas[0],
+ /* children */ { 0x1a /* 01011, 1 3 4 */ },
+ /* completion */ { 0x02 /* 01000, 1 */ },
+ /* ancestors */ { 0x00 /* 00000, */ },
+ /* data */ NULL,
/* type */ SCXML_STATE_COMPOUND,
},
{ /* state number 1 */
@@ -262,170 +226,62 @@ static const scxml_state scxml_states[10] = {
/* onentry */ NULL,
/* onexit */ NULL,
/* invoke */ NULL,
- /* children */ { 0x0c, 0x00 /* 0011000000, 2 3 */ },
- /* completion */ { 0x08, 0x00 /* 0001000000, 3 */ },
- /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ },
+ /* children */ { 0x04 /* 00100, 2 */ },
+ /* completion */ { 0x04 /* 00100, 2 */ },
+ /* ancestors */ { 0x01 /* 10000, 0 */ },
/* data */ NULL,
- /* type */ SCXML_STATE_COMPOUND | SCXML_STATE_HAS_HISTORY,
+ /* type */ SCXML_STATE_COMPOUND,
},
{ /* state number 2 */
- /* name */ "h0",
- /* parent */ 1,
- /* onentry */ NULL,
- /* onexit */ NULL,
- /* invoke */ NULL,
- /* children */ { 0x00, 0x00 /* 0000000000, */ },
- /* completion */ { 0x08, 0x00 /* 0001000000, 3 */ },
- /* ancestors */ { 0x03, 0x00 /* 1100000000, 0 1 */ },
- /* data */ NULL,
- /* type */ SCXML_STATE_HISTORY_DEEP | SCXML_STATE_HAS_HISTORY,
- },
- { /* state number 3 */
/* name */ "s0.0",
/* parent */ 1,
/* onentry */ NULL,
/* onexit */ NULL,
/* invoke */ NULL,
- /* children */ { 0x70, 0x00 /* 0000111000, 4 5 6 */ },
- /* completion */ { 0x20, 0x00 /* 0000010000, 5 */ },
- /* ancestors */ { 0x03, 0x00 /* 1100000000, 0 1 */ },
- /* data */ NULL,
- /* type */ SCXML_STATE_COMPOUND | SCXML_STATE_HAS_HISTORY,
- },
- { /* state number 4 */
- /* name */ "h1",
- /* parent */ 3,
- /* onentry */ NULL,
- /* onexit */ NULL,
- /* invoke */ NULL,
- /* children */ { 0x00, 0x00 /* 0000000000, */ },
- /* completion */ { 0x60, 0x00 /* 0000011000, 5 6 */ },
- /* ancestors */ { 0x0b, 0x00 /* 1101000000, 0 1 3 */ },
- /* data */ NULL,
- /* type */ SCXML_STATE_HISTORY_DEEP,
- },
- { /* state number 5 */
- /* name */ "s0.0.0",
- /* parent */ 3,
- /* onentry */ s0_0_0_on_entry,
- /* onexit */ NULL,
- /* invoke */ NULL,
- /* children */ { 0x00, 0x00 /* 0000000000, */ },
- /* completion */ { 0x00, 0x00 /* 0000000000, */ },
- /* ancestors */ { 0x0b, 0x00 /* 1101000000, 0 1 3 */ },
- /* data */ NULL,
- /* type */ SCXML_STATE_ATOMIC,
- },
- { /* state number 6 */
- /* name */ "s0.0.1",
- /* parent */ 3,
- /* onentry */ NULL,
- /* onexit */ NULL,
- /* invoke */ NULL,
- /* children */ { 0x00, 0x00 /* 0000000000, */ },
- /* completion */ { 0x00, 0x00 /* 0000000000, */ },
- /* ancestors */ { 0x0b, 0x00 /* 1101000000, 0 1 3 */ },
- /* data */ NULL,
- /* type */ SCXML_STATE_ATOMIC,
- },
- { /* state number 7 */
- /* name */ "s1",
- /* parent */ 0,
- /* onentry */ s1_on_entry,
- /* onexit */ NULL,
- /* invoke */ NULL,
- /* children */ { 0x00, 0x00 /* 0000000000, */ },
- /* completion */ { 0x00, 0x00 /* 0000000000, */ },
- /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ },
+ /* children */ { 0x00 /* 00000, */ },
+ /* completion */ { 0x00 /* 00000, */ },
+ /* ancestors */ { 0x03 /* 11000, 0 1 */ },
/* data */ NULL,
/* type */ SCXML_STATE_ATOMIC,
},
- { /* state number 8 */
+ { /* state number 3 */
/* name */ "pass",
/* parent */ 0,
/* onentry */ NULL,
/* onexit */ NULL,
/* invoke */ NULL,
- /* children */ { 0x00, 0x00 /* 0000000000, */ },
- /* completion */ { 0x00, 0x00 /* 0000000000, */ },
- /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ },
+ /* children */ { 0x00 /* 00000, */ },
+ /* completion */ { 0x00 /* 00000, */ },
+ /* ancestors */ { 0x01 /* 10000, 0 */ },
/* data */ NULL,
/* type */ SCXML_STATE_FINAL,
},
- { /* state number 9 */
+ { /* state number 4 */
/* name */ "fail",
/* parent */ 0,
/* onentry */ NULL,
/* onexit */ NULL,
/* invoke */ NULL,
- /* children */ { 0x00, 0x00 /* 0000000000, */ },
- /* completion */ { 0x00, 0x00 /* 0000000000, */ },
- /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ },
+ /* children */ { 0x00 /* 00000, */ },
+ /* completion */ { 0x00 /* 00000, */ },
+ /* ancestors */ { 0x01 /* 10000, 0 */ },
/* data */ NULL,
/* type */ SCXML_STATE_FINAL,
}
};
-static const scxml_transition scxml_transitions[5] = {
+static const scxml_transition scxml_transitions[1] = {
{ /* transition number 0 with priority 0
- target: s0.0.1
- */
- /* name */ 5,
- /* target */ { 0x40, 0x00 /* 0000001000, 6 */ },
- /* event */ NULL,
- /* condition */ "Var1 == 1",
- /* ontrans */ NULL,
- /* type */ SCXML_TRANS_SPONTANEOUS,
- /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ },
- /* exit set */ { 0x70, 0x00 /* 0000111000, 4 5 6 */ }
- },
- { /* transition number 1 with priority 1
- target: s1
- */
- /* name */ 6,
- /* target */ { 0x80, 0x00 /* 0000000100, 7 */ },
- /* event */ NULL,
- /* condition */ "Var1 == 1",
- /* ontrans */ NULL,
- /* type */ SCXML_TRANS_SPONTANEOUS,
- /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ },
- /* exit set */ { 0xfe, 0x03 /* 0111111111, 1 2 3 4 5 6 7 8 9 */ }
- },
- { /* transition number 2 with priority 2
- target: pass
- */
- /* name */ 1,
- /* target */ { 0x00, 0x01 /* 0000000010, 8 */ },
- /* event */ NULL,
- /* condition */ "Var1 == 2",
- /* ontrans */ NULL,
- /* type */ SCXML_TRANS_SPONTANEOUS,
- /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ },
- /* exit set */ { 0xfe, 0x03 /* 0111111111, 1 2 3 4 5 6 7 8 9 */ }
- },
- { /* transition number 3 with priority 3
- target: fail
+ target:
*/
- /* name */ 1,
- /* target */ { 0x00, 0x02 /* 0000000001, 9 */ },
+ /* source */ 2,
+ /* target */ { NULL },
/* event */ NULL,
/* condition */ NULL,
/* ontrans */ NULL,
- /* type */ SCXML_TRANS_SPONTANEOUS,
- /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ },
- /* exit set */ { 0xfe, 0x03 /* 0111111111, 1 2 3 4 5 6 7 8 9 */ }
- },
- { /* transition number 4 with priority 4
- target: h0
- */
- /* name */ 7,
- /* target */ { 0x04, 0x00 /* 0010000000, 2 */ },
- /* event */ NULL,
- /* condition */ "Var1 == 2",
- /* ontrans */ NULL,
- /* type */ SCXML_TRANS_SPONTANEOUS,
- /* conflicts */ { 0x10 /* 00001, 4 */ },
- /* exit set */ { 0x00, 0x00 /* 0000000000, */ }
+ /* type */ SCXML_TRANS_TARGETLESS | SCXML_TRANS_SPONTANEOUS,
+ /* conflicts */ { 0x01 /* 1, 0 */ },
+ /* exit set */ { 0x00 /* 00000, */ }
}
};
@@ -433,7 +289,7 @@ static const scxml_transition scxml_transitions[5] = {
static void printStateNames(const char* a) {
const char* seperator = "";
for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {
- if (IS_SET(i, a)) {
+ if (BIT_HAS(i, a)) {
printf("%s%s", seperator, (scxml_states[i].name != NULL ? scxml_states[i].name : "UNK"));
seperator = ", ";
}
@@ -444,7 +300,7 @@ static void printStateNames(const char* a) {
static void printBitsetIndices(const char* a, size_t length) {
const char* seperator = "";
for (size_t i = 0; i < length; i++) {
- if (IS_SET(i, a)) {
+ if (BIT_HAS(i, a)) {
printf("%s%lu", seperator, i);
seperator = ", ";
}
@@ -453,44 +309,44 @@ static void printBitsetIndices(const char* a, size_t length) {
}
#endif
-static void bit_or(char* dest, const char* mask, size_t i) {
+static int bit_has_and(const char* a, const char* b, size_t i) {
do {
- dest[i - 1] |= mask[i - 1];
+ if (a[i - 1] & b[i - 1])
+ return true;
} while(--i);
+ return false;
}
-static void bit_copy(char* dest, const char* source, size_t i) {
+static int bit_has_any(const char* a, size_t i) {
do {
- dest[i - 1] = source[i - 1];
+ if (a[i - 1] > 0)
+ return true;
} while(--i);
+ return false;
}
-static int bit_has_and(const char* a, const char* b, size_t i) {
+static void bit_or(char* dest, const char* mask, size_t i) {
do {
- if (a[i - 1] & b[i - 1])
- return true;
+ dest[i - 1] |= mask[i - 1];
} while(--i);
- return false;
}
-static void bit_and_not(char* dest, const char* mask, size_t i) {
+static void bit_copy(char* dest, const char* source, size_t i) {
do {
- dest[i - 1] &= ~mask[i - 1];
+ dest[i - 1] = source[i - 1];
} while(--i);
}
-static void bit_and(char* dest, const char* mask, size_t i) {
+static void bit_and_not(char* dest, const char* mask, size_t i) {
do {
- dest[i - 1] &= mask[i - 1];
+ dest[i - 1] &= ~mask[i - 1];
} while(--i);
}
-static int bit_any_set(const char* a, size_t i) {
+static void bit_and(char* dest, const char* mask, size_t i) {
do {
- if (a[i - 1] > 0)
- return true;
+ dest[i - 1] &= mask[i - 1];
} while(--i);
- return false;
}
int scxml_step(scxml_ctx* ctx) {
@@ -501,21 +357,21 @@ int scxml_step(scxml_ctx* ctx) {
#endif
// MACRO_STEP:
- ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;
if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL)
return SCXML_ERR_DONE;
int err = SCXML_ERR_OK;
char conflicts[1] = {0};
- char target_set[2] = {0, 0};
- char exit_set[2] = {0, 0};
+ char target_set[1] = {0};
+ char exit_set[1] = {0};
char trans_set[1] = {0};
- char entry_set[2] = {0, 0};
+ char entry_set[1] = {0};
+ char tmp_states[1] = {0};
if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {
global_script(ctx, &scxml_states[0], NULL);
- bit_or(target_set, scxml_states[0].completion, 2);
+ bit_or(target_set, scxml_states[0].completion, 1);
ctx->flags |= SCXML_CTX_SPONTANEOUS | SCXML_CTX_INITIALIZED;
goto ESTABLISH_ENTRY_SET;
}
@@ -538,9 +394,9 @@ SELECT_TRANSITIONS:
continue;
// is the transition active?
- if (IS_SET(scxml_transitions[i].source, ctx->config)) {
+ if (BIT_HAS(scxml_transitions[i].source, ctx->config)) {
// is it non-conflicting?
- if (!IS_SET(i, conflicts)) {
+ if (!BIT_HAS(i, conflicts)) {
// is it enabled?
if (ctx->is_enabled(ctx, &scxml_transitions[i], ctx->event) > 0) {
// remember that we found a transition
@@ -550,20 +406,21 @@ SELECT_TRANSITIONS:
bit_or(conflicts, scxml_transitions[i].conflicts, 1);
// states that are directly targeted (resolve as entry-set later)
- bit_or(target_set, scxml_transitions[i].target, 2);
+ bit_or(target_set, scxml_transitions[i].target, 1);
// states that will be left
- bit_or(exit_set, scxml_transitions[i].exit_set, 2);
+ bit_or(exit_set, scxml_transitions[i].exit_set, 1);
- SET_BIT(i, trans_set);
+ BIT_SET_AT(i, trans_set);
}
}
}
}
- bit_and(exit_set, ctx->config, 2);
+ bit_and(exit_set, ctx->config, 1);
if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) {
ctx->flags |= SCXML_CTX_SPONTANEOUS;
+ ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;
} else {
ctx->flags &= ~SCXML_CTX_SPONTANEOUS;
}
@@ -588,72 +445,79 @@ SELECT_TRANSITIONS:
if unlikely(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_SHALLOW ||
SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP) {
// a history state whose parent is about to be exited
- if unlikely(IS_SET(scxml_states[i].parent, exit_set)) {
- char history[2] = {0, 0};
- bit_copy(history, scxml_states[i].completion, 2);
+ if unlikely(BIT_HAS(scxml_states[i].parent, exit_set)) {
+ bit_copy(tmp_states, scxml_states[i].completion, 1);
// set those states who were enabled
- bit_and(history, ctx->config, 2);
+ bit_and(tmp_states, ctx->config, 1);
- // clear current history with completion mask - TODO: errornously clears nested history
- bit_and_not(ctx->history, scxml_states[i].completion, 2);
+ // clear current history with completion mask
+ bit_and_not(ctx->history, scxml_states[i].completion, 1);
// set history
- bit_or(ctx->history, history, 2);
+ bit_or(ctx->history, tmp_states, 1);
}
}
}
ESTABLISH_ENTRY_SET:
// calculate new entry set
- bit_copy(entry_set, target_set, 2);
+ bit_copy(entry_set, target_set, 1);
// iterate for ancestors
for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {
- if (IS_SET(i, entry_set)) {
- bit_or(entry_set, scxml_states[i].ancestors, 2);
+ if (BIT_HAS(i, entry_set)) {
+ bit_or(entry_set, scxml_states[i].ancestors, 1);
}
}
// iterate for descendants
for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {
- if (IS_SET(i, entry_set)) {
+ if (BIT_HAS(i, entry_set)) {
switch (SCXML_STATE_MASK(scxml_states[i].type)) {
case SCXML_STATE_PARALLEL: {
- bit_or(entry_set, scxml_states[i].completion, 2);
+ bit_or(entry_set, scxml_states[i].completion, 1);
break;
}
case SCXML_STATE_HISTORY_SHALLOW:
case SCXML_STATE_HISTORY_DEEP: {
- char history_targets[2] = {0, 0};
- if (!bit_has_and(scxml_states[i].completion, ctx->history, 2) &&
- !IS_SET(scxml_states[i].parent, ctx->config)) {
- // nothing set for history, look for a default transition or enter parents completion
+ if (!bit_has_and(scxml_states[i].completion, ctx->history, 1) &&
+ !BIT_HAS(scxml_states[i].parent, ctx->config)) {
+ // nothing set for history, look for a default transition
for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {
if unlikely(scxml_transitions[j].source == i) {
- bit_or(entry_set, scxml_transitions[j].target, 2);
- SET_BIT(j, trans_set);
+ bit_or(entry_set, scxml_transitions[j].target, 1);
+ if(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP &&
+ !bit_has_and(scxml_transitions[j].target, scxml_states[i].children, 1)) {
+ for (size_t k = i + 1; k < SCXML_NUMBER_STATES; k++) {
+ if (BIT_HAS(k, scxml_transitions[j].target)) {
+ bit_or(entry_set, scxml_states[k].ancestors, 1);
+ break;
+ }
+ }
+ }
+ BIT_SET_AT(j, trans_set);
break;
}
// Note: SCXML mandates every history to have a transition!
}
} else {
- bit_copy(history_targets, scxml_states[i].completion, 2);
- bit_and(history_targets, ctx->history, 2);
- bit_or(entry_set, history_targets, 2);
+ bit_copy(tmp_states, scxml_states[i].completion, 1);
+ bit_and(tmp_states, ctx->history, 1);
+ bit_or(entry_set, tmp_states, 1);
if (scxml_states[i].type == (SCXML_STATE_HAS_HISTORY | SCXML_STATE_HISTORY_DEEP)) {
// a deep history state with nested histories -> more completion
for (size_t j = i + 1; j < SCXML_NUMBER_STATES; j++) {
- if (IS_SET(j, scxml_states[i].completion) &&
- IS_SET(j, entry_set) &&
+ if (BIT_HAS(j, scxml_states[i].completion) &&
+ BIT_HAS(j, entry_set) &&
(scxml_states[j].type & SCXML_STATE_HAS_HISTORY)) {
for (size_t k = j + 1; k < SCXML_NUMBER_STATES; k++) {
// add nested history to entry_set
if ((SCXML_STATE_MASK(scxml_states[k].type) == SCXML_STATE_HISTORY_DEEP ||
SCXML_STATE_MASK(scxml_states[k].type) == SCXML_STATE_HISTORY_SHALLOW) &&
- IS_SET(k, scxml_states[j].children)) {
+ BIT_HAS(k, scxml_states[j].children)) {
// a nested history state
- SET_BIT(k, entry_set);
+ BIT_SET_AT(k, entry_set);
}
}
}
@@ -665,12 +529,12 @@ ESTABLISH_ENTRY_SET:
case SCXML_STATE_INITIAL: {
for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {
if (scxml_transitions[j].source == i) {
- SET_BIT(j, trans_set);
- CLEARBIT(i, entry_set);
- bit_or(entry_set, scxml_transitions[j].target, 2);
+ BIT_SET_AT(j, trans_set);
+ BIT_CLEAR(i, entry_set);
+ bit_or(entry_set, scxml_transitions[j].target, 1);
for (size_t k = i + 1; k < SCXML_NUMBER_STATES; k++) {
- if (IS_SET(k, scxml_transitions[j].target)) {
- bit_or(entry_set, scxml_states[k].ancestors, 2);
+ if (BIT_HAS(k, scxml_transitions[j].target)) {
+ bit_or(entry_set, scxml_states[k].ancestors, 1);
}
}
}
@@ -678,16 +542,16 @@ ESTABLISH_ENTRY_SET:
break;
}
case SCXML_STATE_COMPOUND: { // we need to check whether one child is already in entry_set
- if (!bit_has_and(entry_set, scxml_states[i].children, 2) &&
- (!bit_has_and(ctx->config, scxml_states[i].children, 2) ||
- bit_has_and(exit_set, scxml_states[i].children, 2)))
+ if (!bit_has_and(entry_set, scxml_states[i].children, 1) &&
+ (!bit_has_and(ctx->config, scxml_states[i].children, 1) ||
+ bit_has_and(exit_set, scxml_states[i].children, 1)))
{
- bit_or(entry_set, scxml_states[i].completion, 2);
- if (!bit_has_and(scxml_states[i].completion, scxml_states[i].children, 2)) {
+ bit_or(entry_set, scxml_states[i].completion, 1);
+ if (!bit_has_and(scxml_states[i].completion, scxml_states[i].children, 1)) {
// deep completion
for (size_t j = i + 1; j < SCXML_NUMBER_STATES; j++) {
- if (IS_SET(j, scxml_states[i].completion)) {
- bit_or(entry_set, scxml_states[j].ancestors, 2);
+ if (BIT_HAS(j, scxml_states[i].completion)) {
+ bit_or(entry_set, scxml_states[j].ancestors, 1);
break; // completion of compound is single state
}
}
@@ -707,19 +571,19 @@ ESTABLISH_ENTRY_SET:
// EXIT_STATES:
size_t i = SCXML_NUMBER_STATES;
while(i-- > 0) {
- if (IS_SET(i, exit_set) && IS_SET(i, ctx->config)) {
+ if (BIT_HAS(i, exit_set) && BIT_HAS(i, ctx->config)) {
// call all on exit handlers
if (scxml_states[i].on_exit != NULL) {
if unlikely((err = scxml_states[i].on_exit(ctx, &scxml_states[i], ctx->event)) != SCXML_ERR_OK)
return err;
}
- CLEARBIT(i, ctx->config);
+ BIT_CLEAR(i, ctx->config);
}
}
// TAKE_TRANSITIONS:
for (size_t i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {
- if (IS_SET(i, trans_set) && (scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) == 0) {
+ if (BIT_HAS(i, trans_set) && (scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) == 0) {
// call executable content in transition
if (scxml_transitions[i].on_transition != NULL) {
if unlikely((err = scxml_transitions[i].on_transition(ctx,
@@ -737,21 +601,21 @@ ESTABLISH_ENTRY_SET:
// ENTER_STATES:
for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {
- if (IS_SET(i, entry_set) && !IS_SET(i, ctx->config)) {
+ if (BIT_HAS(i, entry_set) && !BIT_HAS(i, ctx->config)) {
// these are no proper states
if unlikely(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP ||
SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_SHALLOW ||
SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_INITIAL)
continue;
- SET_BIT(i, ctx->config);
+ BIT_SET_AT(i, ctx->config);
// initialize data
- if (!IS_SET(i, ctx->initialized_data)) {
+ if (!BIT_HAS(i, ctx->initialized_data)) {
if unlikely(scxml_states[i].data != NULL && ctx->exec_content_init != NULL) {
ctx->exec_content_init(ctx, scxml_states[i].data);
}
- SET_BIT(i, ctx->initialized_data);
+ BIT_SET_AT(i, ctx->initialized_data);
}
if (scxml_states[i].on_entry != NULL) {
@@ -761,7 +625,7 @@ ESTABLISH_ENTRY_SET:
// take history and initial transitions
for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {
- if unlikely(IS_SET(j, trans_set) &&
+ if unlikely(BIT_HAS(j, trans_set) &&
(scxml_transitions[j].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) &&
scxml_states[scxml_transitions[j].source].parent == i) {
// call executable content in transition
@@ -797,20 +661,20 @@ ESTABLISH_ENTRY_SET:
* 4. If a state remains, not all children of a parallel are final
*/
for (size_t j = 0; j < SCXML_NUMBER_STATES; j++) {
- if unlikely(SCXML_STATE_MASK(scxml_states[j].type) == SCXML_STATE_PARALLEL) {
- char parallel_children[2] = {0, 0};
- size_t parallel = j;
+ if unlikely(SCXML_STATE_MASK(scxml_states[j].type) == SCXML_STATE_PARALLEL &&
+ BIT_HAS(j, scxml_states[i].ancestors)) {
+ bit_and_not(tmp_states, tmp_states, 1);
for (size_t k = 0; k < SCXML_NUMBER_STATES; k++) {
- if unlikely(IS_SET(parallel, scxml_states[k].ancestors) && IS_SET(k, ctx->config)) {
+ if unlikely(BIT_HAS(j, scxml_states[k].ancestors) && BIT_HAS(k, ctx->config)) {
if (SCXML_STATE_MASK(scxml_states[k].type) == SCXML_STATE_FINAL) {
- bit_and_not(parallel_children, scxml_states[k].ancestors, 2);
+ bit_and_not(tmp_states, scxml_states[k].ancestors, 1);
} else {
- SET_BIT(k, parallel_children);
+ BIT_SET_AT(k, tmp_states);
}
}
}
- if unlikely(!bit_any_set(parallel_children, 2)) {
- ctx->raise_done_event(ctx, &scxml_states[parallel], NULL);
+ if unlikely(!bit_has_any(tmp_states, 1)) {
+ ctx->raise_done_event(ctx, &scxml_states[j], NULL);
}
}
}
diff --git a/test/uscxml/automated/ecma/uncompleted-history.scxml b/test/uscxml/automated/ecma/uncompleted-history.scxml
deleted file mode 100644
index f6c3c04..0000000
--- a/test/uscxml/automated/ecma/uncompleted-history.scxml
+++ /dev/null
@@ -1,11 +0,0 @@
-<scxml datamodel="ecmascript" initial="s0.h0">
- <state id="s0">
- <transition target="fail" />
- <history id="s0.h0" type="deep" />
- <state id="s0.0">
- <transition target="pass" />
- </state>
- </state>
- <final id="pass" />
- <final id="fail" />
-</scxml> \ No newline at end of file