From 81799f6f7d667e11ba0a30875046ca3dc0c63fe7 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Thu, 28 Jan 2016 23:13:18 +0100 Subject: Actually generate ANSI C code in uscxml-transform --- apps/uscxml-transform.cpp | 4 +- src/uscxml/Interpreter.cpp | 3 +- src/uscxml/transform/ChartToC.cpp | 218 ++++++++------- src/uscxml/transform/ChartToC.h | 8 +- src/uscxml/transform/ChartToVHDL.cpp | 287 ++++++-------------- src/uscxml/transform/ChartToVHDL.h | 40 +-- test/CMakeLists.txt | 18 +- test/src/test-c-machine.machine.c | 512 +++++++++++++++++++++++++++++------ test/w3c/run_generated_test.cmake | 64 ++--- test/w3c/run_promela_test.cmake | 6 +- 10 files changed, 700 insertions(+), 460 deletions(-) diff --git a/apps/uscxml-transform.cpp b/apps/uscxml-transform.cpp index 9395f76..69e0c97 100644 --- a/apps/uscxml-transform.cpp +++ b/apps/uscxml-transform.cpp @@ -372,7 +372,9 @@ int main(int argc, char** argv) { } catch (Event e) { std::cout << e << std::endl; - } + } catch (const std::exception &e) { + std::cout << e.what() << std::endl; + } return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index d8bd1ec..f1490d4 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -72,7 +72,8 @@ #define VALID_FROM_INITIALIZED(newState) ( \ newState == USCXML_MICROSTEPPED || \ - newState == USCXML_FINISHED \ + newState == USCXML_FINISHED || \ + newState == USCXML_DESTROYED \ ) #define VALID_FROM_MICROSTEPPED(newState) ( \ diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp index 2fc392a..eb462a1 100644 --- a/src/uscxml/transform/ChartToC.cpp +++ b/src/uscxml/transform/ChartToC.cpp @@ -47,8 +47,8 @@ Transformer ChartToC::transform(const Interpreter& other) { ChartToC::ChartToC(const Interpreter& other) : TransformerImpl() { cloneFrom(other.getImpl()); } - -void ChartToC::setHistoryResponsibility(Arabica::DOM::Node& node) { + +void ChartToC::setHistoryResponsibility() { std::set elements; elements.insert(_nsInfo.xmlNSPrefix + "history"); Arabica::XPath::NodeSet histories = inPostFixOrder(elements, _scxml); @@ -106,7 +106,6 @@ void ChartToC::setHistoryResponsibility(Arabica::DOM::Node& node) { } } - void ChartToC::resortStates(Arabica::DOM::Node& node) { if (node.getNodeType() != Node_base::ELEMENT_NODE) return; @@ -173,83 +172,91 @@ void ChartToC::resortStates(Arabica::DOM::Node& node) { } -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); - - std::set elements; - elements.insert(_nsInfo.xmlNSPrefix + "scxml"); - elements.insert(_nsInfo.xmlNSPrefix + "state"); - elements.insert(_nsInfo.xmlNSPrefix + "final"); - elements.insert(_nsInfo.xmlNSPrefix + "parallel"); - elements.insert(_nsInfo.xmlNSPrefix + "history"); - elements.insert(_nsInfo.xmlNSPrefix + "initial"); - elements.insert(_nsInfo.xmlNSPrefix + "parallel"); - _states = inDocumentOrder(elements, _scxml); - - for (size_t i = 0; i < _states.size(); i++) { - Element state(_states[i]); - state.setAttribute("documentOrder", toStr(i)); - if (HAS_ATTR(state, "id")) { - _stateNames[ATTR(state, "id")] = state; - } - } - - elements.clear(); - elements.insert(_nsInfo.xmlNSPrefix + "transition"); - _transitions = inPostFixOrder(elements, _scxml); - - for (size_t i = 0; i < _transitions.size(); i++) { - Element transition(_transitions[i]); - transition.setAttribute("postFixOrder", toStr(i)); - } - - // how many bits do we need to represent the state array? - std::string seperator; - _stateCharArraySize = ceil((float)_states.size() / (float)8); - _stateCharArrayInit = "{"; - for (size_t i = 0; i < _stateCharArraySize; i++) { - _stateCharArrayInit += seperator + "0"; - seperator = ", "; - } - _stateCharArrayInit += "}"; - - if (false) { - } else if (_states.size() < (1UL << 8)) { - _stateDataType = "uint8_t"; - } else if (_states.size() < (1UL << 16)) { - _stateDataType = "uint16_t"; - } else if (_states.size() < (1UL << 32)) { - _stateDataType = "uint32_t"; - } else { - _stateDataType = "uint64_t"; - } - - seperator = ""; - _transCharArraySize = ceil((float)_transitions.size() / (float)8); - _transCharArrayInit = "{"; - for (size_t i = 0; i < _transCharArraySize; i++) { - _transCharArrayInit += seperator + "0"; - seperator = ", "; - } - _transCharArrayInit += "}"; - - if (false) { - } else if (_transitions.size() < (1UL << 8)) { - _transDataType = "uint8_t"; - } else if (_transitions.size() < (1UL << 16)) { - _transDataType = "uint16_t"; - } else if (_transitions.size() < (1UL << 32)) { - _transDataType = "uint32_t"; - } else { - _transDataType = "uint64_t"; - } +void ChartToC::prepare() { + _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); + + std::set elements; + elements.insert(_nsInfo.xmlNSPrefix + "scxml"); + elements.insert(_nsInfo.xmlNSPrefix + "state"); + elements.insert(_nsInfo.xmlNSPrefix + "final"); + elements.insert(_nsInfo.xmlNSPrefix + "parallel"); + elements.insert(_nsInfo.xmlNSPrefix + "history"); + elements.insert(_nsInfo.xmlNSPrefix + "initial"); + elements.insert(_nsInfo.xmlNSPrefix + "parallel"); + _states = inDocumentOrder(elements, _scxml); + + for (size_t i = 0; i < _states.size(); i++) { + Element state(_states[i]); + state.setAttribute("documentOrder", toStr(i)); + } + + elements.clear(); + elements.insert(_nsInfo.xmlNSPrefix + "transition"); + _transitions = inDocumentOrder(elements, _scxml); + for (size_t i = 0; i < _transitions.size(); i++) { + Element transition(_transitions[i]); + transition.setAttribute("documentOrder", toStr(i)); + } + + _transitions = inPostFixOrder(elements, _scxml); + for (size_t i = 0; i < _transitions.size(); i++) { + Element transition(_transitions[i]); + transition.setAttribute("postFixOrder", toStr(i)); + } + // leave transitions in postfix order + + // set the responsibility of history elements + setHistoryResponsibility(); + + // how many bits do we need to represent the state array? + std::string seperator; + _stateCharArraySize = ceil((float)_states.size() / (float)8); + _stateCharArrayInit = "{"; + for (size_t i = 0; i < _stateCharArraySize; i++) { + _stateCharArrayInit += seperator + "0"; + seperator = ", "; + } + _stateCharArrayInit += "}"; + + if (false) { + } else if (_states.size() < (1UL << 8)) { + _stateDataType = "uint8_t"; + } else if (_states.size() < (1UL << 16)) { + _stateDataType = "uint16_t"; + } else if (_states.size() < (1UL << 32)) { + _stateDataType = "uint32_t"; + } else { + _stateDataType = "uint64_t"; + } + + seperator = ""; + _transCharArraySize = ceil((float)_transitions.size() / (float)8); + _transCharArrayInit = "{"; + for (size_t i = 0; i < _transCharArraySize; i++) { + _transCharArrayInit += seperator + "0"; + seperator = ", "; + } + _transCharArrayInit += "}"; + + if (false) { + } else if (_transitions.size() < (1UL << 8)) { + _transDataType = "uint8_t"; + } else if (_transitions.size() < (1UL << 16)) { + _transDataType = "uint16_t"; + } else if (_transitions.size() < (1UL << 32)) { + _transDataType = "uint32_t"; + } else { + _transDataType = "uint64_t"; + } + +} - // set the responsibility of history elements - setHistoryResponsibility(_scxml); +void ChartToC::writeTo(std::ostream& stream) { + prepare(); writeIncludes(stream); writeMacros(stream); @@ -498,8 +505,9 @@ void ChartToC::writeTypes(std::ostream& stream) { void ChartToC::writeHelpers(std::ostream& stream) { stream << "#ifdef SCXML_VERBOSE" << std::endl; 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 << " size_t i;" << std::endl; + stream << " const char* seperator = \"\";" << std::endl; + stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << 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; @@ -510,8 +518,9 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << std::endl; stream << "static void printBitsetIndices(const char* a, size_t length) {" << std::endl; + stream << " size_t i;" << std::endl; stream << " const char* seperator = \"\";" << std::endl; - stream << " for (size_t i = 0; i < length; i++) {" << std::endl; + stream << " for (i = 0; i < length; i++) {" << std::endl; stream << " if (BIT_HAS(i, a)) {" << std::endl; stream << " printf(\"%s%lu\", seperator, i);" << std::endl; stream << " seperator = \", \";" << std::endl; @@ -526,18 +535,18 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "static int bit_has_and(const char* a, const char* b, 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 << " return 1;" << std::endl; stream << " } while(--i);" << std::endl; - stream << " return false;" << std::endl; + stream << " return 0;" << std::endl; stream << "}" << std::endl; stream << std::endl; stream << "static int bit_has_any(const char* a, size_t i) {" << std::endl; stream << " do {" << std::endl; stream << " if (a[i - 1] > 0)" << std::endl; - stream << " return true;" << std::endl; + stream << " return 1;" << std::endl; stream << " } while(--i);" << std::endl; - stream << " return false;" << std::endl; + stream << " return 0;" << std::endl; stream << "}" << std::endl; stream << std::endl; @@ -1470,7 +1479,8 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " return SCXML_ERR_DONE; " << std::endl; stream << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; + stream << " size_t i, j, k;" << std::endl; + stream << " int err = SCXML_ERR_OK;" << std::endl; stream << " char conflicts[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl; stream << " char target_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; stream << " char exit_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; @@ -1500,7 +1510,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "SELECT_TRANSITIONS:" << std::endl; - stream << " for (size_t i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; + stream << " for (i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; stream << " // never select history or initial transitions automatically" << std::endl; stream << " if unlikely(scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL))" << std::endl; stream << " continue;" << std::endl; @@ -1560,7 +1570,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "// REMEMBER_HISTORY:" << std::endl; - stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " for (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 << " // a history state whose parent is about to be exited" << std::endl; @@ -1585,7 +1595,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " bit_copy(entry_set, target_set, " << _stateCharArraySize << ");" << std::endl; stream << std::endl; stream << " // iterate for ancestors" << std::endl; - stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << 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; @@ -1593,7 +1603,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << " // iterate for descendants" << std::endl; - stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << 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; @@ -1605,12 +1615,12 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " if (!bit_has_and(scxml_states[i].completion, ctx->history, " << _stateCharArraySize << ") &&" << 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 << " for (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 << " 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 << " for (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; @@ -1628,11 +1638,11 @@ void ChartToC::writeFSM(std::ostream& stream) { 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 << " for (j = i + 1; j < SCXML_NUMBER_STATES; j++) {" << 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 << " for (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; @@ -1648,12 +1658,12 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " break;" << std::endl; stream << " }" << std::endl; stream << " case SCXML_STATE_INITIAL: {" << std::endl; - stream << " for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl; + stream << " for (j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl; stream << " if (scxml_transitions[j].source == i) {" << 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 << " for (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 << " }" << std::endl; @@ -1670,7 +1680,7 @@ void ChartToC::writeFSM(std::ostream& stream) { 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 = i + 1; j < SCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " for (j = i + 1; j < SCXML_NUMBER_STATES; j++) {" << 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; @@ -1692,7 +1702,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "// EXIT_STATES:" << std::endl; - stream << " size_t i = SCXML_NUMBER_STATES;" << std::endl; + stream << " i = SCXML_NUMBER_STATES;" << std::endl; stream << " while(i-- > 0) {" << std::endl; stream << " if (BIT_HAS(i, exit_set) && BIT_HAS(i, ctx->config)) {" << std::endl; stream << " // call all on exit handlers" << std::endl; @@ -1706,7 +1716,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "// TAKE_TRANSITIONS:" << std::endl; - stream << " for (size_t i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; + stream << " for (i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << 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; @@ -1726,7 +1736,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "// ENTER_STATES:" << std::endl; - stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << 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; @@ -1754,7 +1764,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << " // take history and initial transitions" << std::endl; - stream << " for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl; + stream << " for (j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << 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; @@ -1792,11 +1802,11 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " * 3. Iterate all active final states and remove their ancestors" << std::endl; 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 << " for (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 << " 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 << " for (k = 0; k < SCXML_NUMBER_STATES; k++) {" << 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(tmp_states, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl; diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h index 954aa63..20713ca 100644 --- a/src/uscxml/transform/ChartToC.h +++ b/src/uscxml/transform/ChartToC.h @@ -54,7 +54,7 @@ protected: static void inDocumentOrder(const std::set& elements, const Arabica::DOM::Element& root, Arabica::XPath::NodeSet& nodes); - + void writeIncludes(std::ostream& stream); void writeMacros(std::ostream& stream); void writeTypes(std::ostream& stream); @@ -72,12 +72,12 @@ protected: Arabica::XPath::NodeSet computeExitSet(const Arabica::DOM::Element& transition); void resortStates(Arabica::DOM::Node& node); - void setHistoryResponsibility(Arabica::DOM::Node& node); - + void setHistoryResponsibility(); + void prepare(); + Interpreter interpreter; Arabica::XPath::NodeSet _states; - std::map > _stateNames; Arabica::XPath::NodeSet _transitions; bool _hasGlobalScripts; diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index e9dc60d..bcff51f 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -17,7 +17,6 @@ * @endcond */ -#include "uscxml/transform/ChartToFSM.h" #include "uscxml/transform/ChartToVHDL.h" #include "uscxml/debug/Complexity.h" #include @@ -47,209 +46,103 @@ Transformer ChartToVHDL::transform(const Interpreter& other) { return boost::shared_ptr(c2c); } -ChartToVHDL::ChartToVHDL(const Interpreter& other) : TransformerImpl() { - cloneFrom(other.getImpl()); +ChartToVHDL::ChartToVHDL(const Interpreter& other) : ChartToC(other), _eventTrie(".") { } ChartToVHDL::~ChartToVHDL() { } -NodeSet ChartToVHDL::inPostFixOrder(const std::set& elements, const Element& root) { - NodeSet nodes; - inPostFixOrder(elements, root, nodes); - return nodes; -} - -void ChartToVHDL::inPostFixOrder(const std::set& elements, const Element& root, NodeSet& nodes) { - NodeList children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - Arabica::DOM::Element childElem(children.item(i)); - inPostFixOrder(elements, childElem, nodes); - - } - for (int i = 0; i < children.getLength(); i++) { - if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - Arabica::DOM::Element childElem(children.item(i)); +void ChartToVHDL::checkDocument() { + // filter unsupported stuff + Arabica::XPath::NodeSet unsupported; + + std::set elements; + elements.insert(_nsInfo.xmlNSPrefix + "datamodel"); + elements.insert(_nsInfo.xmlNSPrefix + "data"); + elements.insert(_nsInfo.xmlNSPrefix + "assign"); + elements.insert(_nsInfo.xmlNSPrefix + "donedata"); + elements.insert(_nsInfo.xmlNSPrefix + "content"); + elements.insert(_nsInfo.xmlNSPrefix + "param"); + elements.insert(_nsInfo.xmlNSPrefix + "script"); + + elements.insert(_nsInfo.xmlNSPrefix + "parallel"); + elements.insert(_nsInfo.xmlNSPrefix + "history"); + + elements.insert(_nsInfo.xmlNSPrefix + "if"); // implicit elseif und else + elements.insert(_nsInfo.xmlNSPrefix + "foreach"); + elements.insert(_nsInfo.xmlNSPrefix + "send"); + elements.insert(_nsInfo.xmlNSPrefix + "cancel"); + elements.insert(_nsInfo.xmlNSPrefix + "invoke"); + elements.insert(_nsInfo.xmlNSPrefix + "finalize"); + unsupported = ChartToC::inDocumentOrder(elements, _scxml); + + std::stringstream ss; + if (unsupported.size() > 0) { + for (int i = 0; i < unsupported.size(); i++) { + ss << " " << DOMUtils::xPathForNode(unsupported[i]) << " unsupported" << std::endl; + } + throw std::runtime_error("Unsupported elements found:\n" + ss.str()); + } + + elements.clear(); + elements.insert(_nsInfo.xmlNSPrefix + "transition"); + unsupported = inDocumentOrder(elements, _scxml); + + for (int i = 0; i < unsupported.size(); i++) { + Element transition(unsupported[i]); + if (HAS_ATTR(transition, "cond")) { + ERROR_PLATFORM_THROW("transition with conditions not supported!"); + } + if (!HAS_ATTR(transition, "target")) { + ERROR_PLATFORM_THROW("targetless transition not supported!"); + } + } - if (elements.find(TAGNAME(childElem)) != elements.end()) { - nodes.push_back(childElem); - } - } -} - -void ChartToVHDL::inDocumentOrder(const std::set& elements, const Element& root, NodeSet& nodes) { - if (elements.find(TAGNAME(root)) != elements.end()) { - nodes.push_back(root); - } - - NodeList children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - Arabica::DOM::Element childElem(children.item(i)); - inDocumentOrder(elements, childElem, nodes); - } } -NodeSet ChartToVHDL::inDocumentOrder(const std::set& elements, const Element& root) { - NodeSet nodes; - inDocumentOrder(elements, root, nodes); - return nodes; +void ChartToVHDL::findEvents() { + // elements with an event attribute + NodeSet withEvent; + withEvent.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "raise", _scxml, true)); + withEvent.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "send", _scxml, true)); + withEvent.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true)); + + for (size_t i = 0; i < withEvent.size(); i++) { + if (HAS_ATTR_CAST(withEvent[i], "event")) { + _eventTrie.addWord(ATTR_CAST(withEvent[i], "event")); + } + } } - - -// ASK Where does _scxml,_nsInfo come from - + void ChartToVHDL::writeTo(std::ostream& stream) { - // ASK What is this ? - _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); - // ASK Name for whole state machine? Important ? - _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : "no_name_machine"); - - // filter unsupported stuff - std::set elements; - elements.insert(_nsInfo.xmlNSPrefix + "datamodel"); - elements.insert(_nsInfo.xmlNSPrefix + "data"); - elements.insert(_nsInfo.xmlNSPrefix + "assign"); - elements.insert(_nsInfo.xmlNSPrefix + "donedata"); - elements.insert(_nsInfo.xmlNSPrefix + "content"); - elements.insert(_nsInfo.xmlNSPrefix + "param"); - elements.insert(_nsInfo.xmlNSPrefix + "script"); - - elements.insert(_nsInfo.xmlNSPrefix + "parallel"); - elements.insert(_nsInfo.xmlNSPrefix + "history"); - - elements.insert(_nsInfo.xmlNSPrefix + "if"); //implizit elseif und else - elements.insert(_nsInfo.xmlNSPrefix + "foreach"); - elements.insert(_nsInfo.xmlNSPrefix + "send"); - elements.insert(_nsInfo.xmlNSPrefix + "cancel"); - elements.insert(_nsInfo.xmlNSPrefix + "invoke"); - elements.insert(_nsInfo.xmlNSPrefix + "finalize"); - Arabica::XPath::NodeSet unsupported = inDocumentOrder(elements, _scxml); - - if (unsupported.size() > 0) { - stream << "contains unsupported elements:" << std::endl; - for (int i = 0; i < unsupported.size(); i++) { - Element uElement(unsupported[i]); - stream << TAGNAME(uElement) << std::endl; - } - stream << "ERROR" << std::endl; - return; - } - - elements.clear(); - elements.insert(_nsInfo.xmlNSPrefix + "transition"); - unsupported = inPostFixOrder(elements, _scxml); - - for (int i = 0; i < unsupported.size(); i++) { - Element transition(unsupported[i]); - if (HAS_ATTR(transition, "cond")) { - stream << transition << std::endl; - stream << "transition has conditions (not supported)!" << std::endl; - stream << "ERROR" << std::endl; - return; - } - if (!HAS_ATTR(transition, "target")) { - stream << transition << std::endl; - stream << "transition has no target (not supported)!" << std::endl; - stream << "ERROR" << std::endl; - return; - } - if (!HAS_ATTR(transition, "event")) { - stream << transition << std::endl; - stream << "transition is spntaneous (not supported)!" << std::endl; - stream << "ERROR" << std::endl; - return; - } - if (transition.getChildNodes().getLength() > 0) { - stream << transition << std::endl; - stream << "transition executable code (not supported)!" << std::endl; - stream << "ERROR" << std::endl; - return; - } - } - - // create states array - elements.clear(); - // elements.insert(_nsInfo.xmlNSPrefix + "scxml"); - elements.insert(_nsInfo.xmlNSPrefix + "state"); - elements.insert(_nsInfo.xmlNSPrefix + "final"); - elements.insert(_nsInfo.xmlNSPrefix + "parallel"); - elements.insert(_nsInfo.xmlNSPrefix + "history"); - elements.insert(_nsInfo.xmlNSPrefix + "initial"); - // elements.insert(_nsInfo.xmlNSPrefix + "parallel"); - _states = inDocumentOrder(elements, _scxml); - - for (int i = 0; i < _states.size(); i++) { - Element state(_states[i]); - state.setAttribute("documentOrder", toStr(i)); - if (!HAS_ATTR(state, "id")) { - std::stringstream ss; - ss << "HWS_" << toStr(i); - state.setAttribute("id", ss.str()); - } - _stateNames[ATTR(state, "id")] = state; - } - _initState = ATTR(_scxml, "initial"); + // same preparations as the C transformation +// annotateElementSets(); + + +// checkDocument(); + findEvents(); + _eventTrie.dump(); + + writeTypes(stream); + writeFiFo(stream); + writeTransitionSet(stream); + writeExitSet(stream); + writeEntrySet(stream); + writeFSM(stream); +} - // create transitions array & event array - elements.clear(); - elements.insert(_nsInfo.xmlNSPrefix + "transition"); - _transitions = inPostFixOrder(elements, _scxml); +void ChartToVHDL::writeTransitionSet(std::ostream & stream) { + for (size_t i = 0; i < _transitions.size(); i++) { + Element transition(_transitions[i]); + std::string name = DOMUtils::idForNode(transition); + + } +} - for (int i = 0; i < _transitions.size(); i++) { - Element transition(_transitions[i]); - transition.setAttribute("postFixOrder", toStr(i)); - if (!HAS_ATTR(transition, "event")) { - // spontanious transition - transition.setAttribute("event", CONST_TRANS_SPONTANIOUS); - } - std::stringstream ss; - ss << "HWT" << toStr(i) << "_to_" << ATTR(transition, "target"); - transition.setAttribute("id", ss.str()); - _transitionNames[ss.str()] = transition; - - std::string event = ATTR(transition, "event"); - if (event == "*") { - event = CONST_EVENT_ANY; - transition.setAttribute("event", CONST_EVENT_ANY); - } - if (!(std::find(_events.begin(), _events.end(), event) != _events.end())) { - // if eventname does not exist - _events.push_back(event); - } - } +void ChartToVHDL::writeExitSet(std::ostream & stream) { +} - // debug - // stream << _scxml; - // return; - - // how many bits do we need to represent the state array? - // std::string seperator; - // _stateCharArraySize = ceil((float) _states.size() / (float) 8); - // _stateCharArrayInit = "{"; - // for (int i = 0; i < _stateCharArraySize; i++) { - // _stateCharArrayInit += seperator + "0"; - // seperator = ", "; - // } - // _stateCharArrayInit += "}"; - // - // seperator = ""; - // _transCharArraySize = ceil((float) _transitions.size() / (float) 8); - // _transCharArrayInit = "{"; - // for (int i = 0; i < _transCharArraySize; i++) { - // _transCharArrayInit += seperator + "0"; - // seperator = ", "; - // } - // _transCharArrayInit += "}"; - - // writeTopDown(stream); - writeTypes(stream); - writeFiFo(stream); - writeFSM(stream); +void ChartToVHDL::writeEntrySet(std::ostream & stream) { } void ChartToVHDL::writeFSM(std::ostream & stream) { @@ -350,11 +243,11 @@ void ChartToVHDL::writeTypes(std::ostream & stream) { // create event type stream << " type event_type is ("; seperator = ""; - for (int i = 0; i < _events.size(); i++) { - stream << seperator; - stream << _events[i]; - seperator = ", "; - } +// for (int i = 0; i < _events.size(); i++) { +// stream << seperator; +// stream << _events[i]; +// seperator = ", "; +// } if (seperator.size() == 0) { stream << "NO_EVENTS"; } @@ -701,7 +594,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) { stream << "begin" << std::endl; stream << " if rst = '1' then" << std::endl; stream << " current_state <= (others => '0');" << std::endl; - stream << " " << _initState << "_curr <= '1';" << std::endl; +// stream << " " << _initState << "_curr <= '1';" << std::endl; stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; stream << " current_state <= next_state;" << std::endl; stream << " end if;" << std::endl; diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index ec649f4..a2cbac7 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -24,6 +24,7 @@ #include "uscxml/DOMUtils.h" #include "uscxml/util/Trie.h" #include "Transformer.h" +#include "ChartToC.h" #include #include @@ -32,7 +33,7 @@ namespace uscxml { -class USCXML_API ChartToVHDL : public InterpreterRC, public TransformerImpl { +class USCXML_API ChartToVHDL : public ChartToC { public: virtual ~ChartToVHDL(); @@ -40,22 +41,12 @@ public: void writeTo(std::ostream& stream); - static Arabica::XPath::NodeSet inPostFixOrder(const std::set& elements, - const Arabica::DOM::Element& root); - static Arabica::XPath::NodeSet inDocumentOrder(const std::set& elements, - const Arabica::DOM::Element& root); - protected: ChartToVHDL(const Interpreter& other); - static void inPostFixOrder(const std::set& elements, - const Arabica::DOM::Element& root, - Arabica::XPath::NodeSet& nodes); - - static void inDocumentOrder(const std::set& elements, - const Arabica::DOM::Element& root, - Arabica::XPath::NodeSet& nodes); - + void checkDocument(); + void findEvents(); + void writeIncludes(std::ostream& stream); void writeTopDown(std::ostream& stream); @@ -68,25 +59,12 @@ protected: void writeErrorHandler(std::ostream& stream); void writeFSM(std::ostream& stream); + void writeTransitionSet(std::ostream & stream); + void writeExitSet(std::ostream & stream); + void writeEntrySet(std::ostream & stream); + Trie _eventTrie; - Interpreter interpreter; - - std::string _initState; - Arabica::XPath::NodeSet _states; - std::map > _stateNames; - Arabica::XPath::NodeSet _transitions; - std::map > _transitionNames; - std::vector _events; - - bool _hasGlobalScripts; - bool _hasDoneData; - - size_t _transCharArraySize; - std::string _transCharArrayInit; - - size_t _stateCharArraySize; - std::string _stateCharArrayInit; }; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a47368f..42e518b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -81,8 +81,8 @@ add_test(test-done-data ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-browser ${CMAKE # declare W#C tests find_program(SPIN spin) -find_program(GCC gcc) -find_program(GPP g++) +find_program(CC gcc) +find_program(CXX g++) if (NOT BUILD_MINIMAL) # compile and add all reported issues tests @@ -199,8 +199,8 @@ if (NOT BUILD_MINIMAL) -DTARGETLANG=${TEST_TARGET} -DJSC_LIBRARY:FILEPATH=${JSC_LIBRARY} -DUSCXML_TRANSFORM_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-transform - -DGCC_BIN:FILEPATH=${GCC} - -DGPP_BIN:FILEPATH=${GPP} + -DCC_BIN:FILEPATH=${CC} + -DCXX_BIN:FILEPATH=${CXX} -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DUSCXML_PLATFORM_ID=${USCXML_PLATFORM_ID} -DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR} @@ -234,7 +234,7 @@ if (NOT BUILD_MINIMAL) -DTESTFILE:FILEPATH=${W3C_TEST} -DUSCXML_TRANSFORM_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-transform -DSPIN_BIN:FILEPATH=${SPIN} - -DGCC_BIN:FILEPATH=${GCC} + -DCC_BIN:FILEPATH=${CC} -P ${CMAKE_CURRENT_SOURCE_DIR}/w3c/run_promela_test.cmake) set_tests_properties("${TEST_NAME}" PROPERTIES PASS_REGULAR_EXPRESSION "depth reached [0-9]+, errors: 0") set_tests_properties("${TEST_NAME}" PROPERTIES FAIL_REGULAR_EXPRESSION "depth reached [0-9]+, errors: [1-9]+") @@ -290,8 +290,8 @@ if (NOT BUILD_MINIMAL) # -DTESTFILE:FILEPATH=${W3C_TEST} # -DJSC_LIBRARY:FILEPATH=${JSC_LIBRARY} # -DUSCXML_TRANSFORM_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-transform - # -DGCC_BIN:FILEPATH=${GCC} - # -DGPP_BIN:FILEPATH=${GPP} + # -DCC_BIN:FILEPATH=${CC} + # -DCXX_BIN:FILEPATH=${CXX} # -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} # -DUSCXML_PLATFORM_ID=${USCXML_PLATFORM_ID} # -DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR} @@ -387,7 +387,7 @@ if (NOT BUILD_MINIMAL) # endif() # endif() # - # if (GCC AND SPIN AND BUILD_DM_PROMELA AND BUILD_TESTS_W3C_PROMELA AND TEST_NAME MATCHES "^promela\\/.*") + # if (CC AND SPIN AND BUILD_DM_PROMELA AND BUILD_TESTS_W3C_PROMELA AND TEST_NAME MATCHES "^promela\\/.*") # # add_test(NAME "spin/${TEST_NAME}" # COMMAND ${CMAKE_COMMAND} @@ -395,7 +395,7 @@ if (NOT BUILD_MINIMAL) # -DTESTFILE:FILEPATH=${W3C_TEST} # -DUSCXML_TRANSFORM_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-transform # -DSPIN_BIN:FILEPATH=${SPIN} - # -DGCC_BIN:FILEPATH=${GCC} + # -DCC_BIN:FILEPATH=${CC} # -P ${CMAKE_CURRENT_SOURCE_DIR}/w3c/run_promela_test.cmake) # set_property(TEST "spin/${TEST_NAME}" PROPERTY LABELS "spin/${TEST_NAME}") # set_tests_properties("spin/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT}) diff --git a/test/src/test-c-machine.machine.c b/test/src/test-c-machine.machine.c index 2b991ff..cb3cf34 100644 --- a/test/src/test-c-machine.machine.c +++ b/test/src/test-c-machine.machine.c @@ -25,8 +25,8 @@ #define SCXML_ERR_UNSUPPORTED 8 #define SCXML_MACHINE_NAME "" -#define SCXML_NUMBER_STATES 5 -#define SCXML_NUMBER_TRANSITIONS 1 +#define SCXML_NUMBER_STATES 14 +#define SCXML_NUMBER_TRANSITIONS 10 #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[1]; // all children - const char completion[1]; // default completion - const char ancestors[1]; // all ancestors + const char children[2]; // all children + const char completion[2]; // default completion + const char ancestors[2]; // 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[1]; + const char target[2]; const char* event; const char* condition; const exec_content_t on_transition; const uint8_t type; - const char conflicts[1]; - const char exit_set[1]; + const char conflicts[2]; + const char exit_set[2]; }; struct scxml_elem_foreach { @@ -171,10 +171,10 @@ struct scxml_elem_send { struct scxml_ctx { uint8_t flags; - char config[1]; - char history[1]; - char pending_invokes[1]; - char initialized_data[1]; + char config[2]; + char history[2]; + char pending_invokes[2]; + char initialized_data[2]; void* user_data; void* event; @@ -198,6 +198,31 @@ 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_send scxml_elem_sends[1] = { + { + /* event */ "timeout", + /* eventexpr */ NULL, + /* target */ NULL, + /* targetexpr */ NULL, + /* type */ NULL, + /* typeexpr */ NULL, + /* id */ NULL, + /* idlocation */ NULL, + /* delay */ "2s", + /* delayexpr */ NULL, + /* namelist */ NULL, + /* content */ NULL, + /* contentexpr */ NULL, + /* params */ NULL + } +}; + static const scxml_elem_donedata scxml_elem_donedatas[1] = { /* source, content, contentexpr, params */ { 0, NULL, NULL, NULL } @@ -207,81 +232,412 @@ static int global_script(const scxml_ctx* ctx, const scxml_state* state, const v return SCXML_ERR_OK; } -static const scxml_state scxml_states[5] = { +static int s0_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_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + s0_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static int s011_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + int err = SCXML_ERR_OK; + if likely(ctx->exec_content_raise != NULL) { + if unlikely((ctx->exec_content_raise(ctx, "entering.s011")) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static int s011_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + s011_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static int s012_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + int err = SCXML_ERR_OK; + if likely(ctx->exec_content_raise != NULL) { + if unlikely((ctx->exec_content_raise(ctx, "entering.s012")) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static int s012_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + s012_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static int s021_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + int err = SCXML_ERR_OK; + if likely(ctx->exec_content_raise != NULL) { + if unlikely((ctx->exec_content_raise(ctx, "entering.s021")) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static int s021_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + s021_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static int s022_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + int err = SCXML_ERR_OK; + if likely(ctx->exec_content_raise != NULL) { + if unlikely((ctx->exec_content_raise(ctx, "entering.s022")) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static int s022_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + s022_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static int pass_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + int err = SCXML_ERR_OK; + if likely(ctx->exec_content_log != NULL) { + if unlikely((ctx->exec_content_log(ctx, "Outcome", "'pass'")) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static int pass_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + pass_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static int fail_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + int err = SCXML_ERR_OK; + if likely(ctx->exec_content_log != NULL) { + if unlikely((ctx->exec_content_log(ctx, "Outcome", "'fail'")) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static int fail_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + fail_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static int s0_transition0_on_trans(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + int err = SCXML_ERR_OK; + if likely(ctx->exec_content_send != NULL) { + if ((ctx->exec_content_send(ctx, &scxml_elem_sends[0])) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static const scxml_state scxml_states[14] = { { /* state number 0 */ /* name */ NULL, /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x1a /* 01011, 1 3 4 */ }, - /* completion */ { 0x02 /* 01000, 1 */ }, - /* ancestors */ { 0x00 /* 00000, */ }, - /* data */ NULL, + /* children */ { 0x02, 0x3c /* 01000000001111, 1 10 11 12 13 */ }, + /* completion */ { 0x40, 0x00 /* 00000010000000, 6 */ }, + /* ancestors */ { 0x00, 0x00 /* 00000000000000, */ }, + /* data */ &scxml_elem_datas[0], /* type */ SCXML_STATE_COMPOUND, }, { /* state number 1 */ /* name */ "s0", /* parent */ 0, + /* onentry */ s0_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x9c, 0x00 /* 00111001000000, 2 3 4 7 */ }, + /* completion */ { 0x10, 0x00 /* 00001000000000, 4 */ }, + /* ancestors */ { 0x01, 0x00 /* 10000000000000, 0 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_COMPOUND | SCXML_STATE_HAS_HISTORY, + }, + { /* state number 2 */ + /* name */ "s0HistDeep", + /* parent */ 1, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x04 /* 00100, 2 */ }, - /* completion */ { 0x04 /* 00100, 2 */ }, - /* ancestors */ { 0x01 /* 10000, 0 */ }, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0xf0, 0x03 /* 00001111110000, 4 5 6 7 8 9 */ }, + /* ancestors */ { 0x03, 0x00 /* 11000000000000, 0 1 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_HISTORY_DEEP | SCXML_STATE_HAS_HISTORY, + }, + { /* state number 3 */ + /* name */ "s0HistShallow", + /* parent */ 1, + /* onentry */ NULL, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x90, 0x00 /* 00001001000000, 4 7 */ }, + /* ancestors */ { 0x03, 0x00 /* 11000000000000, 0 1 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_HISTORY_SHALLOW | SCXML_STATE_HAS_HISTORY, + }, + { /* state number 4 */ + /* name */ "s01", + /* parent */ 1, + /* onentry */ NULL, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x60, 0x00 /* 00000110000000, 5 6 */ }, + /* completion */ { 0x20, 0x00 /* 00000100000000, 5 */ }, + /* ancestors */ { 0x03, 0x00 /* 11000000000000, 0 1 */ }, /* data */ NULL, /* type */ SCXML_STATE_COMPOUND, }, - { /* state number 2 */ - /* name */ "s0.0", + { /* state number 5 */ + /* name */ "s011", + /* parent */ 4, + /* onentry */ s011_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x13, 0x00 /* 11001000000000, 0 1 4 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_ATOMIC, + }, + { /* state number 6 */ + /* name */ "s012", + /* parent */ 4, + /* onentry */ s012_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x13, 0x00 /* 11001000000000, 0 1 4 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_ATOMIC, + }, + { /* state number 7 */ + /* name */ "s02", /* parent */ 1, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 00000, */ }, - /* completion */ { 0x00 /* 00000, */ }, - /* ancestors */ { 0x03 /* 11000, 0 1 */ }, + /* children */ { 0x00, 0x03 /* 00000000110000, 8 9 */ }, + /* completion */ { 0x00, 0x01 /* 00000000100000, 8 */ }, + /* ancestors */ { 0x03, 0x00 /* 11000000000000, 0 1 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_COMPOUND, + }, + { /* state number 8 */ + /* name */ "s021", + /* parent */ 7, + /* onentry */ s021_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x83, 0x00 /* 11000001000000, 0 1 7 */ }, /* data */ NULL, /* type */ SCXML_STATE_ATOMIC, }, - { /* state number 3 */ - /* name */ "pass", + { /* state number 9 */ + /* name */ "s022", + /* parent */ 7, + /* onentry */ s022_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x83, 0x00 /* 11000001000000, 0 1 7 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_ATOMIC, + }, + { /* state number 10 */ + /* name */ "s1", + /* parent */ 0, + /* onentry */ NULL, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x01, 0x00 /* 10000000000000, 0 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_ATOMIC, + }, + { /* state number 11 */ + /* name */ "s2", /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 00000, */ }, - /* completion */ { 0x00 /* 00000, */ }, - /* ancestors */ { 0x01 /* 10000, 0 */ }, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x01, 0x00 /* 10000000000000, 0 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_ATOMIC, + }, + { /* state number 12 */ + /* name */ "pass", + /* parent */ 0, + /* onentry */ pass_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x01, 0x00 /* 10000000000000, 0 */ }, /* data */ NULL, /* type */ SCXML_STATE_FINAL, }, - { /* state number 4 */ + { /* state number 13 */ /* name */ "fail", /* parent */ 0, - /* onentry */ NULL, + /* onentry */ fail_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 00000, */ }, - /* completion */ { 0x00 /* 00000, */ }, - /* ancestors */ { 0x01 /* 10000, 0 */ }, + /* children */ { 0x00, 0x00 /* 00000000000000, */ }, + /* completion */ { 0x00, 0x00 /* 00000000000000, */ }, + /* ancestors */ { 0x01, 0x00 /* 10000000000000, 0 */ }, /* data */ NULL, /* type */ SCXML_STATE_FINAL, } }; -static const scxml_transition scxml_transitions[1] = { +static const scxml_transition scxml_transitions[10] = { { /* transition number 0 with priority 0 - target: + target: s022 */ /* source */ 2, - /* target */ { NULL }, + /* target */ { 0x00, 0x02 /* 00000000010000, 9 */ }, + /* event */ NULL, + /* condition */ NULL, + /* ontrans */ NULL, + /* type */ SCXML_TRANS_SPONTANEOUS | SCXML_TRANS_HISTORY, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 1 with priority 1 + target: s02 + */ + /* source */ 3, + /* target */ { 0x80, 0x00 /* 00000001000000, 7 */ }, + /* event */ NULL, + /* condition */ NULL, + /* ontrans */ NULL, + /* type */ SCXML_TRANS_SPONTANEOUS | SCXML_TRANS_HISTORY, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 2 with priority 2 + target: s1 + */ + /* source */ 1, + /* target */ { 0x00, 0x04 /* 00000000001000, 10 */ }, + /* event */ "entering.s012", + /* condition */ "Var1==1", + /* ontrans */ s0_transition0_on_trans, + /* type */ 0, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 3 with priority 3 + target: s2 + */ + /* source */ 1, + /* target */ { 0x00, 0x08 /* 00000000000100, 11 */ }, + /* event */ "entering.s012", + /* condition */ "Var1==2", + /* ontrans */ NULL, + /* type */ 0, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 4 with priority 4 + target: fail + */ + /* source */ 1, + /* target */ { 0x00, 0x20 /* 00000000000001, 13 */ }, + /* event */ "entering", + /* condition */ "Var1==2", + /* ontrans */ NULL, + /* type */ 0, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 5 with priority 5 + target: pass + */ + /* source */ 1, + /* target */ { 0x00, 0x10 /* 00000000000010, 12 */ }, + /* event */ "entering.s011", + /* condition */ "Var1==3", + /* ontrans */ NULL, + /* type */ 0, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 6 with priority 6 + target: fail + */ + /* source */ 1, + /* target */ { 0x00, 0x20 /* 00000000000001, 13 */ }, + /* event */ "entering", + /* condition */ "Var1==3", + /* ontrans */ NULL, + /* type */ 0, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 7 with priority 7 + target: fail + */ + /* source */ 1, + /* target */ { 0x00, 0x20 /* 00000000000001, 13 */ }, + /* event */ "timeout", + /* condition */ NULL, + /* ontrans */ NULL, + /* type */ 0, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 8 with priority 8 + target: s0HistDeep + */ + /* source */ 10, + /* target */ { 0x04, 0x00 /* 00100000000000, 2 */ }, + /* event */ NULL, + /* condition */ NULL, + /* ontrans */ NULL, + /* type */ SCXML_TRANS_SPONTANEOUS, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } + }, + { /* transition number 9 with priority 9 + target: s0HistShallow + */ + /* source */ 11, + /* target */ { 0x08, 0x00 /* 00010000000000, 3 */ }, /* event */ NULL, /* condition */ NULL, /* ontrans */ NULL, - /* type */ SCXML_TRANS_TARGETLESS | SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x01 /* 1, 0 */ }, - /* exit set */ { 0x00 /* 00000, */ } + /* type */ SCXML_TRANS_SPONTANEOUS, + /* conflicts */ { 0xff, 0x03 /* 1111111111, 0 1 2 3 4 5 6 7 8 9 */ }, + /* exit set */ { 0xfe, 0x3f /* 01111111111111, 1 2 3 4 5 6 7 8 9 10 11 12 13 */ } } }; @@ -362,16 +718,16 @@ int scxml_step(scxml_ctx* ctx) { return SCXML_ERR_DONE; int err = SCXML_ERR_OK; - char conflicts[1] = {0}; - char target_set[1] = {0}; - char exit_set[1] = {0}; - char trans_set[1] = {0}; - char entry_set[1] = {0}; - char tmp_states[1] = {0}; + char conflicts[2] = {0, 0}; + char target_set[2] = {0, 0}; + char exit_set[2] = {0, 0}; + char trans_set[2] = {0, 0}; + char entry_set[2] = {0, 0}; + char tmp_states[2] = {0, 0}; if unlikely(ctx->flags == SCXML_CTX_PRISTINE) { global_script(ctx, &scxml_states[0], NULL); - bit_or(target_set, scxml_states[0].completion, 1); + bit_or(target_set, scxml_states[0].completion, 2); ctx->flags |= SCXML_CTX_SPONTANEOUS | SCXML_CTX_INITIALIZED; goto ESTABLISH_ENTRY_SET; } @@ -403,20 +759,20 @@ SELECT_TRANSITIONS: ctx->flags |= SCXML_CTX_TRANSITION_FOUND; // transitions that are pre-empted - bit_or(conflicts, scxml_transitions[i].conflicts, 1); + bit_or(conflicts, scxml_transitions[i].conflicts, 2); // states that are directly targeted (resolve as entry-set later) - bit_or(target_set, scxml_transitions[i].target, 1); + bit_or(target_set, scxml_transitions[i].target, 2); // states that will be left - bit_or(exit_set, scxml_transitions[i].exit_set, 1); + bit_or(exit_set, scxml_transitions[i].exit_set, 2); BIT_SET_AT(i, trans_set); } } } } - bit_and(exit_set, ctx->config, 1); + bit_and(exit_set, ctx->config, 2); if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) { ctx->flags |= SCXML_CTX_SPONTANEOUS; @@ -446,28 +802,28 @@ SELECT_TRANSITIONS: SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP) { // a history state whose parent is about to be exited if unlikely(BIT_HAS(scxml_states[i].parent, exit_set)) { - bit_copy(tmp_states, scxml_states[i].completion, 1); + bit_copy(tmp_states, scxml_states[i].completion, 2); // set those states who were enabled - bit_and(tmp_states, ctx->config, 1); + bit_and(tmp_states, ctx->config, 2); // clear current history with completion mask - bit_and_not(ctx->history, scxml_states[i].completion, 1); + bit_and_not(ctx->history, scxml_states[i].completion, 2); // set history - bit_or(ctx->history, tmp_states, 1); + bit_or(ctx->history, tmp_states, 2); } } } ESTABLISH_ENTRY_SET: // calculate new entry set - bit_copy(entry_set, target_set, 1); + bit_copy(entry_set, target_set, 2); // iterate for ancestors for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { if (BIT_HAS(i, entry_set)) { - bit_or(entry_set, scxml_states[i].ancestors, 1); + bit_or(entry_set, scxml_states[i].ancestors, 2); } } @@ -476,22 +832,22 @@ ESTABLISH_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, 1); + bit_or(entry_set, scxml_states[i].completion, 2); break; } case SCXML_STATE_HISTORY_SHALLOW: case SCXML_STATE_HISTORY_DEEP: { - if (!bit_has_and(scxml_states[i].completion, ctx->history, 1) && + if (!bit_has_and(scxml_states[i].completion, ctx->history, 2) && !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, 1); + bit_or(entry_set, scxml_transitions[j].target, 2); if(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP && - !bit_has_and(scxml_transitions[j].target, scxml_states[i].children, 1)) { + !bit_has_and(scxml_transitions[j].target, scxml_states[i].children, 2)) { 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); + bit_or(entry_set, scxml_states[k].ancestors, 2); break; } } @@ -502,9 +858,9 @@ ESTABLISH_ENTRY_SET: // Note: SCXML mandates every history to have a transition! } } else { - bit_copy(tmp_states, scxml_states[i].completion, 1); - bit_and(tmp_states, ctx->history, 1); - bit_or(entry_set, tmp_states, 1); + bit_copy(tmp_states, scxml_states[i].completion, 2); + bit_and(tmp_states, ctx->history, 2); + bit_or(entry_set, tmp_states, 2); 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++) { @@ -531,10 +887,10 @@ ESTABLISH_ENTRY_SET: if (scxml_transitions[j].source == i) { BIT_SET_AT(j, trans_set); BIT_CLEAR(i, entry_set); - bit_or(entry_set, scxml_transitions[j].target, 1); + bit_or(entry_set, scxml_transitions[j].target, 2); 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); + bit_or(entry_set, scxml_states[k].ancestors, 2); } } } @@ -542,16 +898,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, 1) && - (!bit_has_and(ctx->config, scxml_states[i].children, 1) || - bit_has_and(exit_set, scxml_states[i].children, 1))) + 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))) { - bit_or(entry_set, scxml_states[i].completion, 1); - if (!bit_has_and(scxml_states[i].completion, 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)) { // deep completion for (size_t j = i + 1; j < SCXML_NUMBER_STATES; j++) { if (BIT_HAS(j, scxml_states[i].completion)) { - bit_or(entry_set, scxml_states[j].ancestors, 1); + bit_or(entry_set, scxml_states[j].ancestors, 2); break; // completion of compound is single state } } @@ -565,7 +921,7 @@ ESTABLISH_ENTRY_SET: #ifdef SCXML_VERBOSE printf("Transitions: "); - printBitsetIndices(trans_set, sizeof(char) * 8 * 1); + printBitsetIndices(trans_set, sizeof(char) * 8 * 2); #endif // EXIT_STATES: @@ -663,17 +1019,17 @@ ESTABLISH_ENTRY_SET: for (size_t j = 0; j < SCXML_NUMBER_STATES; 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); + bit_and_not(tmp_states, tmp_states, 2); for (size_t k = 0; k < SCXML_NUMBER_STATES; k++) { 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(tmp_states, scxml_states[k].ancestors, 1); + bit_and_not(tmp_states, scxml_states[k].ancestors, 2); } else { BIT_SET_AT(k, tmp_states); } } } - if unlikely(!bit_has_any(tmp_states, 1)) { + if unlikely(!bit_has_any(tmp_states, 2)) { ctx->raise_done_event(ctx, &scxml_states[j], NULL); } } diff --git a/test/w3c/run_generated_test.cmake b/test/w3c/run_generated_test.cmake index 3051306..868e111 100644 --- a/test/w3c/run_generated_test.cmake +++ b/test/w3c/run_generated_test.cmake @@ -22,35 +22,35 @@ if (${TARGETLANG} STREQUAL "vhdl") elseif (${TARGETLANG} STREQUAL "c") - # set(COMPILE_CMD_OBJ - # "-c" "${OUTDIR}/${TEST_FILE_NAME}.machine.c" - # "-o" "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" - # "-Ofast") - # - # message(STATUS "${GPP_BIN} ${COMPILE_CMD_OBJ}") - # execute_process( - # COMMAND time -p ${GPP_BIN} ${COMPILE_CMD_OBJ} - # WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) - # if(CMD_RESULT) - # message(FATAL_ERROR "Error running g++ ${GPP_BIN}: ${CMD_RESULT}") - # endif() - # file (SIZE "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" BINARY_SIZE) - # message("Size of compiled unit optimized for speed: ${BINARY_SIZE}") - # - # set(COMPILE_CMD_OBJ - # "-c" "${OUTDIR}/${TEST_FILE_NAME}.machine.c" - # "-o" "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" - # "-Os") - # - # message(STATUS "${GPP_BIN} ${COMPILE_CMD_OBJ}") - # execute_process( - # COMMAND time -p ${GPP_BIN} ${COMPILE_CMD_OBJ} - # WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) - # if(CMD_RESULT) - # message(FATAL_ERROR "Error running g++ ${GPP_BIN}: ${CMD_RESULT}") - # endif() - # file (SIZE "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" BINARY_SIZE) - # message("Size of compiled unit optimized for size: ${BINARY_SIZE}") + set(COMPILE_CMD_OBJ + "-c" "${OUTDIR}/${TEST_FILE_NAME}.machine.c" + "-o" "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" + "-Ofast" "-ansi" "-m16") + + message(STATUS "${CC_BIN} ${COMPILE_CMD_OBJ}") + execute_process( + COMMAND time -p ${CC_BIN} ${COMPILE_CMD_OBJ} + WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) + if(CMD_RESULT) + message(FATAL_ERROR "Error running gcc ${CC_BIN}: ${CMD_RESULT}") + endif() + file (SIZE "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" BINARY_SIZE) + message("Size of compiled unit optimized for speed: ${BINARY_SIZE}") + + set(COMPILE_CMD_OBJ + "-c" "${OUTDIR}/${TEST_FILE_NAME}.machine.c" + "-o" "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" + "-Os" "-ansi" "-m16") + + message(STATUS "${CC_BIN} ${COMPILE_CMD_OBJ}") + execute_process( + COMMAND time -p ${CC_BIN} ${COMPILE_CMD_OBJ} + WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) + if(CMD_RESULT) + message(FATAL_ERROR "Error running gcc ${CC_BIN}: ${CMD_RESULT}") + endif() + file (SIZE "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" BINARY_SIZE) + message("Size of compiled unit optimized for size: ${BINARY_SIZE}") set(COMPILE_CMD_BIN "-o" "${OUTDIR}/${TEST_FILE_NAME}" @@ -68,12 +68,12 @@ elseif (${TARGETLANG} STREQUAL "c") "-DAUTOINCLUDE_TEST=ON" "${SCAFFOLDING_FOR_GENERATED_C}") - message(STATUS "${GPP_BIN} ${COMPILE_CMD_BIN}") + message(STATUS "${CXX_BIN} ${COMPILE_CMD_BIN}") execute_process( - COMMAND time -p ${GPP_BIN} ${COMPILE_CMD_BIN} + COMMAND time -p ${CXX_BIN} ${COMPILE_CMD_BIN} WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) if(CMD_RESULT) - message(FATAL_ERROR "Error running g++ ${GPP_BIN}: ${CMD_RESULT}") + message(FATAL_ERROR "Error running g++ ${CXX_BIN}: ${CMD_RESULT}") endif() message(STATUS "time for transforming to binary") diff --git a/test/w3c/run_promela_test.cmake b/test/w3c/run_promela_test.cmake index b403b7a..818cf66 100644 --- a/test/w3c/run_promela_test.cmake +++ b/test/w3c/run_promela_test.cmake @@ -20,10 +20,10 @@ if(CMD_RESULT) endif() message(STATUS "time for transforming to c") -message(STATUS "${GCC_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c") -execute_process(COMMAND time -p ${GCC_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) +message(STATUS "${CXX_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c") +execute_process(COMMAND time -p ${CXX_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) if(CMD_RESULT) - message(FATAL_ERROR "Error running gcc ${GCC_BIN}: ${CMD_RESULT}") + message(FATAL_ERROR "Error running gcc ${CXX_BIN}: ${CMD_RESULT}") endif() message(STATUS "time for transforming to binary") -- cgit v0.12