From 575c2711df910f0b8ecce277bf7333077e235855 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sun, 17 Jan 2016 22:27:21 +0100 Subject: Beautified generated C code from transformation --- src/uscxml/Interpreter.cpp | 88 +++---- src/uscxml/Interpreter.h | 8 +- src/uscxml/transform/ChartToC.cpp | 521 ++++++++++++++++++++++---------------- src/uscxml/transform/ChartToC.h | 2 + test/src/test-c-machine.cpp | 57 +++-- test/src/test-c-machine.machine.c | 395 ++++++++++++++++------------- test/src/test-lifecycle.cpp | 38 +-- test/src/test-w3c.cpp | 142 +++++------ 8 files changed, 697 insertions(+), 554 deletions(-) diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 0375f9b..d8bd1ec 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -386,12 +386,12 @@ void StateTransitionMonitor::beforeEnteringState(uscxml::Interpreter interpreter } void StateTransitionMonitor::beforeMicroStep(uscxml::Interpreter interpreter) { - tthread::lock_guard lock(_mutex); - std::cerr << "Config: {"; - printNodeSet(interpreter.getConfiguration()); - std::cerr << "}" << std::endl; + tthread::lock_guard lock(_mutex); + std::cerr << "Config: {"; + printNodeSet(interpreter.getConfiguration()); + std::cerr << "}" << std::endl; } - + void StateTransitionMonitor::printNodeSet(const Arabica::XPath::NodeSet& config) { std::string seperator; for (int i = 0; i < config.size(); i++) { @@ -601,13 +601,13 @@ InterpreterImpl::~InterpreterImpl() { // make sure we are done with setting up with early abort tthread::lock_guard lock(_mutex); stop(); // unset started bit - - setInterpreterState(USCXML_DESTROYED); - // unblock event queue - Event event; - event.name = "unblock.and.die"; - receive(event); + setInterpreterState(USCXML_DESTROYED); + + // unblock event queue + Event event; + event.name = "unblock.and.die"; + receive(event); } // std::cerr << "stopped " << this << std::endl; @@ -789,7 +789,7 @@ InterpreterState InterpreterImpl::step(int waitForMS) { // setup document and interpreter if (!_isInitialized) { init(); // will throw - return _state; + return _state; } if (_configuration.size() == 0) { @@ -960,19 +960,19 @@ EXIT_INTERPRETER: exitInterpreter(); if (_sendQueue) { - _sendQueue->stop(); + _sendQueue->stop(); std::map >::iterator sendIter = _sendIds.begin(); while(sendIter != _sendIds.end()) { _sendQueue->cancelEvent(sendIter->first); sendIter++; } - _sendQueue->start(); + _sendQueue->start(); } USCXML_MONITOR_CALLBACK(afterCompletion) // assert(hasLegalConfiguration()); - setInterpreterState(USCXML_FINISHED); + setInterpreterState(USCXML_FINISHED); _mutex.unlock(); // remove datamodel @@ -1292,11 +1292,11 @@ void InterpreterImpl::setInterpreterState(InterpreterState newState) { break; assert(false); break; - case USCXML_INITIALIZED: - if (VALID_FROM_INITIALIZED(newState)) - break; - assert(false); - break; + case USCXML_INITIALIZED: + if (VALID_FROM_INITIALIZED(newState)) + break; + assert(false); + break; case USCXML_MICROSTEPPED: if (VALID_FROM_MICROSTEPPED(newState)) break; @@ -1318,7 +1318,7 @@ void InterpreterImpl::setInterpreterState(InterpreterState newState) { assert(false); break; default: - assert(false); + assert(false); break; } @@ -1362,22 +1362,22 @@ bool InterpreterImpl::runOnMainThread(int fps, bool blocking) { void InterpreterImpl::reset() { tthread::lock_guard lock(_mutex); - - if (_sendQueue) { - _sendQueue->stop(); - std::map >::iterator sendIter = _sendIds.begin(); - while(sendIter != _sendIds.end()) { - _sendQueue->cancelEvent(sendIter->first); - sendIter = _sendIds.erase(sendIter); - } - _sendQueue->start(); - } - std::map::iterator invokeIter = _invokers.begin(); - while(invokeIter != _invokers.end()) { - invokeIter->second.uninvoke(); - invokeIter = _invokers.erase(invokeIter); - } - + + if (_sendQueue) { + _sendQueue->stop(); + std::map >::iterator sendIter = _sendIds.begin(); + while(sendIter != _sendIds.end()) { + _sendQueue->cancelEvent(sendIter->first); + _sendIds.erase(sendIter++); + } + _sendQueue->start(); + } + std::map::iterator invokeIter = _invokers.begin(); + while(invokeIter != _invokers.end()) { + invokeIter->second.uninvoke(); + _invokers.erase(invokeIter++); + } + _externalQueue.clear(); _internalQueue.clear(); _historyValue.clear(); @@ -1700,7 +1700,7 @@ void InterpreterImpl::init() { _isInitialized = true; _stable = false; - setInterpreterState(USCXML_INITIALIZED); + setInterpreterState(USCXML_INITIALIZED); } /** @@ -2597,19 +2597,19 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Element& c } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "log")) { // --- LOG -------------------------- Arabica::DOM::Element logElem = (Arabica::DOM::Element)content; - if (logElem.hasAttribute("label")) { - std::cout << logElem.getAttribute("label") << ": "; - } + if (logElem.hasAttribute("label")) { + std::cout << logElem.getAttribute("label") << ": "; + } if (logElem.hasAttribute("expr")) { try { - std::string msg = _dataModel.evalAsString(logElem.getAttribute("expr")); + std::string msg = _dataModel.evalAsString(logElem.getAttribute("expr")); std::cout << msg << std::endl; } CATCH_AND_DISTRIBUTE2("Syntax error in expr attribute of log element", content) } else { - if (logElem.hasAttribute("label")) { + if (logElem.hasAttribute("label")) { std::cout << std::endl; - } + } } } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "assign")) { // --- ASSIGN -------------------------- diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index a721ad3..c996c78 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -164,8 +164,8 @@ enum InterpreterState { USCXML_DESTROYED = -2, ///< destructor ran - users should never see this one USCXML_FINISHED = -1, ///< machine reached a final configuration and is done USCXML_IDLE = 0, ///< stable configuration and queues empty - USCXML_INITIALIZED = 1, ///< DOM is setup and all external components instantiated - USCXML_INSTANTIATED = 2, ///< nothing really, just instantiated + USCXML_INITIALIZED = 1, ///< DOM is setup and all external components instantiated + USCXML_INSTANTIATED = 2, ///< nothing really, just instantiated USCXML_MICROSTEPPED = 3, ///< processed one transition set USCXML_MACROSTEPPED = 4, ///< processed all transition sets and reached a stable configuration }; @@ -891,8 +891,8 @@ public: virtual void beforeProcessingEvent(uscxml::Interpreter interpreter, const uscxml::Event& event); virtual void beforeExitingState(uscxml::Interpreter interpreter, const Arabica::DOM::Element& state, bool moreComing); virtual void beforeEnteringState(uscxml::Interpreter interpreter, const Arabica::DOM::Element& state, bool moreComing); - virtual void beforeMicroStep(uscxml::Interpreter interpreter); - + virtual void beforeMicroStep(uscxml::Interpreter interpreter); + protected: static tthread::recursive_mutex _mutex; void printNodeSet(const Arabica::XPath::NodeSet& config); diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp index 8fe6ac7..aac1acf 100644 --- a/src/uscxml/transform/ChartToC.cpp +++ b/src/uscxml/transform/ChartToC.cpp @@ -60,7 +60,7 @@ void ChartToC::writeTo(std::ostream& stream) { elements.insert(_nsInfo.xmlNSPrefix + "parallel"); _states = inDocumentOrder(elements, _scxml); - for (int i = 0; i < _states.size(); i++) { + for (size_t i = 0; i < _states.size(); i++) { Element state(_states[i]); state.setAttribute("documentOrder", toStr(i)); if (HAS_ATTR(state, "id")) { @@ -72,7 +72,7 @@ void ChartToC::writeTo(std::ostream& stream) { elements.insert(_nsInfo.xmlNSPrefix + "transition"); _transitions = inPostFixOrder(elements, _scxml); - for (int i = 0; i < _transitions.size(); i++) { + for (size_t i = 0; i < _transitions.size(); i++) { Element transition(_transitions[i]); transition.setAttribute("postFixOrder", toStr(i)); } @@ -81,21 +81,43 @@ void ChartToC::writeTo(std::ostream& stream) { std::string seperator; _stateCharArraySize = ceil((float)_states.size() / (float)8); _stateCharArrayInit = "{"; - for (int i = 0; i < _stateCharArraySize; i++) { + 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 (int i = 0; i < _transCharArraySize; i++) { + 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"; + } + writeIncludes(stream); writeMacros(stream); writeTypes(stream); @@ -151,8 +173,8 @@ void ChartToC::writeMacros(std::ostream& stream) { stream << "#define SCXML_TRANS_SPONTANEOUS 0x01" << std::endl; stream << "#define SCXML_TRANS_TARGETLESS 0x02" << std::endl; stream << "#define SCXML_TRANS_INTERNAL 0x04" << std::endl; - stream << "#define SCXML_TRANS_HISTORY 0x08" << std::endl; - stream << "#define SCXML_TRANS_INITIAL 0x10" << std::endl; + stream << "#define SCXML_TRANS_HISTORY 0x08" << std::endl; + stream << "#define SCXML_TRANS_INITIAL 0x10" << std::endl; stream << std::endl; stream << "#define SCXML_STATE_ATOMIC 0x01" << std::endl; @@ -226,27 +248,27 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << "struct scxml_state {" << std::endl; stream << " const char* name; // eventual name" << std::endl; - stream << " uint16_t parent; // parent" << std::endl; - stream << " exec_content_t on_entry; // on entry handlers" << std::endl; - stream << " exec_content_t on_exit; // on exit handlers" << std::endl; - stream << " invoke_t invoke; // invocations" << std::endl; - stream << " char children[" << _stateCharArraySize << "]; // all children" << std::endl; - stream << " char completion[" << _stateCharArraySize << "]; // default completion" << std::endl; - stream << " char ancestors[" << _stateCharArraySize << "]; // all ancestors" << std::endl; + stream << " const " << _stateDataType << " parent; // parent" << std::endl; + stream << " const exec_content_t on_entry; // on entry handlers" << std::endl; + stream << " const exec_content_t on_exit; // on exit handlers" << std::endl; + stream << " const invoke_t invoke; // invocations" << std::endl; + stream << " const char children[" << _stateCharArraySize << "]; // all children" << std::endl; + stream << " const char completion[" << _stateCharArraySize << "]; // default completion" << std::endl; + stream << " const char ancestors[" << _stateCharArraySize << "]; // all ancestors" << std::endl; stream << " const scxml_elem_data* data;" << std::endl; - stream << " uint8_t type; // atomic, parallel, compound, final, history" << std::endl; + stream << " const uint8_t type; // atomic, parallel, compound, final, history" << std::endl; stream << "};" << std::endl; stream << std::endl; stream << "struct scxml_transition {" << std::endl; - stream << " uint16_t source;" << std::endl; - stream << " char target[" << _stateCharArraySize << "];" << std::endl; + stream << " const " << _stateDataType << " source;" << std::endl; + stream << " const char target[" << _stateCharArraySize << "];" << std::endl; stream << " const char* event;" << std::endl; stream << " const char* condition;" << std::endl; - stream << " exec_content_t on_transition;" << std::endl; - stream << " uint8_t type;" << std::endl; - stream << " char conflicts[" << _transCharArraySize << "];" << std::endl; - stream << " char exit_set[" << _stateCharArraySize << "];" << std::endl; + stream << " const exec_content_t on_transition;" << std::endl; + stream << " const uint8_t type;" << std::endl; + stream << " const char conflicts[" << _transCharArraySize << "];" << std::endl; + stream << " const char exit_set[" << _stateCharArraySize << "];" << std::endl; stream << "};" << std::endl; stream << std::endl; @@ -265,7 +287,7 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << std::endl; stream << "struct scxml_elem_donedata {" << std::endl; - stream << " uint16_t source;" << std::endl; + stream << " const " << _stateDataType << " source;" << std::endl; stream << " const char* content;" << std::endl; stream << " const char* contentexpr;" << std::endl; stream << " const scxml_elem_param* params;" << std::endl; @@ -280,12 +302,11 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << " const char* id;" << std::endl; stream << " const char* idlocation;" << std::endl; stream << " const char* namelist;" << std::endl; - stream << " uint8_t autoforward;" << std::endl; + stream << " const uint8_t autoforward;" << std::endl; stream << " const scxml_elem_param* params;" << std::endl; stream << " const exec_content_finalize_t* finalize;" << std::endl; stream << " const char* content;" << std::endl; stream << " const char* contentexpr;" << std::endl; - stream << " void* user_data;" << std::endl; stream << "};" << std::endl; stream << std::endl; @@ -304,7 +325,6 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << " const char* content;" << std::endl; stream << " const char* contentexpr;" << std::endl; stream << " const scxml_elem_param* params;" << std::endl; - stream << " void* user_data;" << std::endl; stream << "};" << std::endl; stream << std::endl; @@ -316,8 +336,8 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << " char pending_invokes[" << _stateCharArraySize << "];" << std::endl; stream << " char initialized_data[" << _stateCharArraySize << "];" << std::endl; stream << std::endl; - stream << " void* user_data;" << std::endl; - stream << " void* event;" << std::endl; + stream << " void* user_data;" << std::endl; + stream << " void* event;" << std::endl; stream << std::endl; stream << " dequeue_internal_cb_t dequeue_internal;" << std::endl; stream << " dequeue_external_cb_t dequeue_external;" << std::endl; @@ -344,7 +364,7 @@ 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 (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; stream << " if (IS_SET(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; @@ -356,9 +376,9 @@ 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 (int i = 0; i < length; i++) {" << std::endl; + stream << " for (size_t i = 0; i < length; i++) {" << std::endl; stream << " if (IS_SET(i, a)) {" << std::endl; - stream << " printf(\"%s%d\", seperator, i);" << std::endl; + stream << " printf(\"%s%lu\", seperator, i);" << std::endl; stream << " seperator = \", \";" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; @@ -417,31 +437,31 @@ void ChartToC::writeHelpers(std::ostream& stream) { } void ChartToC::writeExecContent(std::ostream& stream) { - for (int i = 0; i < _states.size(); i++) { + for (size_t i = 0; i < _states.size(); i++) { Element state(_states[i]); if (i == 0) { // root state - we need to perform some initialization here NodeSet globalScripts = filterChildElements(_nsInfo.xmlNSPrefix + "script", state); - for (int j = 0; j < globalScripts.size(); j++) { - stream << "static int global_script_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; - writeExecContent(stream, globalScripts[j], 1); - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - } - - stream << "static int global_script(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - for (int j = 0; j < globalScripts.size(); j++) { - stream << " global_script_" << toStr(j) << "(ctx, state, event);" << std::endl; - } - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; + for (size_t j = 0; j < globalScripts.size(); j++) { + stream << "static int global_script_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << " int err = SCXML_ERR_OK;" << std::endl; + writeExecContent(stream, globalScripts[j], 1); + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + } + + stream << "static int global_script(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + for (size_t j = 0; j < globalScripts.size(); j++) { + stream << " global_script_" << toStr(j) << "(ctx, state, event);" << std::endl; + } + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; } NodeSet onexit = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state); - for (int j = 0; j < onexit.size(); j++) { + for (size_t j = 0; j < onexit.size(); j++) { stream << "static int " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; stream << " int err = SCXML_ERR_OK;" << std::endl; writeExecContent(stream, onexit[j], 1); @@ -452,7 +472,7 @@ void ChartToC::writeExecContent(std::ostream& stream) { if (onexit.size() > 0) { stream << "static int " << DOMUtils::idForNode(state) << "_on_exit(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - for (int j = 0; j < onexit.size(); j++) { + for (size_t j = 0; j < onexit.size(); j++) { stream << " " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(ctx, state, event);" << std::endl; } stream << " return SCXML_ERR_OK;" << std::endl; @@ -462,7 +482,7 @@ void ChartToC::writeExecContent(std::ostream& stream) { NodeSet onentry = filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state); - for (int j = 0; j < onentry.size(); j++) { + for (size_t j = 0; j < onentry.size(); j++) { stream << "static int " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; stream << " int err = SCXML_ERR_OK;" << std::endl; writeExecContent(stream, onentry[j], 1); @@ -489,7 +509,7 @@ void ChartToC::writeExecContent(std::ostream& stream) { if (onentry.size() > 0) { stream << "static int " << DOMUtils::idForNode(state) << "_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - for (int j = 0; j < onentry.size(); j++) { + for (size_t j = 0; j < onentry.size(); j++) { stream << " " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(ctx, state, event);" << std::endl; } if (hasInitialState) { @@ -505,7 +525,7 @@ void ChartToC::writeExecContent(std::ostream& stream) { NodeSet invoke = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state); if (invoke.size() > 0) { stream << "static int " << DOMUtils::idForNode(state) << "_invoke(const scxml_ctx* ctx, const scxml_state* s, const scxml_invoke* x) {" << std::endl; - for (int j = 0; j < invoke.size(); j++) { + for (size_t j = 0; j < invoke.size(); j++) { stream << " ctx->invoke(ctx, s, x);" << std::endl; stream << " return SCXML_ERR_OK;" << std::endl; stream << std::endl; @@ -514,7 +534,7 @@ void ChartToC::writeExecContent(std::ostream& stream) { } } - for (int i = 0; i < _transitions.size(); i++) { + for (size_t i = 0; i < _transitions.size(); i++) { Element transition(_transitions[i]); if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) continue; @@ -524,7 +544,7 @@ void ChartToC::writeExecContent(std::ostream& stream) { if (execContent.size() > 0) { stream << "static int " << DOMUtils::idForNode(transition) << "_on_trans(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; stream << " int err = SCXML_ERR_OK;" << std::endl; - for (int j = 0; j < execContent.size(); j++) { + for (size_t j = 0; j < execContent.size(); j++) { writeExecContent(stream, Element(execContent[j]), 1); } stream << " return SCXML_ERR_OK;" << std::endl; @@ -547,7 +567,7 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Node foreachs = filterChildElements(_nsInfo.xmlNSPrefix + "foreach", _scxml, true); if (foreachs.size() > 0) { - stream << "static scxml_elem_foreach scxml_elem_foreachs[" << foreachs.size() << "] = {" << std::endl; - for (int i = 0; i < foreachs.size(); i++) { + stream << "static const scxml_elem_foreach scxml_elem_foreachs[" << foreachs.size() << "] = {" << std::endl; + stream << " /* array, item, index */" << std::endl; + for (size_t i = 0; i < foreachs.size(); i++) { Element foreach(foreachs[i]); stream << " { "; stream << (HAS_ATTR(foreach, "array") ? "\"" + escape(ATTR(foreach, "array")) + "\"" : "NULL") << ", "; @@ -731,7 +752,7 @@ void ChartToC::writeElementInfo(std::ostream& stream) { Element(_states[0]).setAttribute("dataIndex", "0"); distinctParents = 1; } else { - for (int i = 0; i < datas.size(); i++) { + for (size_t i = 0; i < datas.size(); i++) { Element data(datas[i]); if (data.getParentNode() != parent) { distinctParents++; @@ -741,8 +762,9 @@ void ChartToC::writeElementInfo(std::ostream& stream) { parent = Node(); - stream << "static scxml_elem_data scxml_elem_datas[" << datas.size() + distinctParents << "] = {" << std::endl; - for (int i = 0; i < datas.size(); i++) { + stream << "static const scxml_elem_data scxml_elem_datas[" << datas.size() + distinctParents << "] = {" << std::endl; + stream << " /* id, src, expr, content */" << std::endl; + for (size_t i = 0; i < datas.size(); i++) { Element data(datas[i]); if (data.getParentNode().getParentNode() != parent) { if (_binding == InterpreterImpl::LATE) { @@ -780,7 +802,7 @@ void ChartToC::writeElementInfo(std::ostream& stream) { if (params.size() > 0) { Node parent; size_t distinctParents = 0; - for (int i = 0; i < params.size(); i++) { + for (size_t i = 0; i < params.size(); i++) { Element param(params[i]); if (param.getParentNode() != parent) { distinctParents++; @@ -788,8 +810,9 @@ void ChartToC::writeElementInfo(std::ostream& stream) { } parent = Node(); - stream << "static scxml_elem_param scxml_elem_params[" << params.size() + distinctParents << "] = {" << std::endl; - for (int i = 0; i < params.size(); i++) { + stream << "static const scxml_elem_param scxml_elem_params[" << params.size() + distinctParents << "] = {" << std::endl; + stream << " /* name, expr, location */" << std::endl; + for (size_t i = 0; i < params.size(); i++) { Element param(params[i]); if (param.getParentNode() != parent) { Element(param.getParentNode()).setAttribute("paramIndex", toStr(i)); @@ -812,44 +835,60 @@ void ChartToC::writeElementInfo(std::ostream& stream) { NodeSet sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", _scxml, true); if (sends.size() > 0) { - stream << "static scxml_elem_send scxml_elem_sends[" << sends.size() << "] = {" << std::endl; - for (int i = 0; i < sends.size(); i++) { + stream << "static const scxml_elem_send scxml_elem_sends[" << sends.size() << "] = {" << std::endl; + for (size_t i = 0; i < sends.size(); i++) { Element send(sends[i]); stream << " { "; + stream << std::endl << " /* event */ "; stream << (HAS_ATTR(send, "event") ? "\"" + escape(ATTR(send, "event")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* eventexpr */ "; stream << (HAS_ATTR(send, "eventexpr") ? "\"" + escape(ATTR(send, "eventexpr")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* target */ "; stream << (HAS_ATTR(send, "target") ? "\"" + escape(ATTR(send, "target")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* targetexpr */ "; stream << (HAS_ATTR(send, "targetexpr") ? "\"" + escape(ATTR(send, "targetexpr")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* type */ "; stream << (HAS_ATTR(send, "type") ? "\"" + escape(ATTR(send, "type")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* typeexpr */ "; stream << (HAS_ATTR(send, "typeexpr") ? "\"" + escape(ATTR(send, "typeexpr")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* id */ "; stream << (HAS_ATTR(send, "id") ? "\"" + escape(ATTR(send, "id")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* idlocation */ "; stream << (HAS_ATTR(send, "idlocation") ? "\"" + escape(ATTR(send, "idlocation")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* delay */ "; stream << (HAS_ATTR(send, "delay") ? "\"" + escape(ATTR(send, "delay")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* delayexpr */ "; stream << (HAS_ATTR(send, "delayexpr") ? "\"" + escape(ATTR(send, "delayexpr")) + "\"" : "NULL") << ", "; + stream << std::endl << " /* namelist */ "; stream << (HAS_ATTR(send, "namelist") ? "\"" + escape(ATTR(send, "namelist")) + "\"" : "NULL") << ", "; NodeSet contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", send); if (contents.size() > 0) { std::stringstream ss; NodeList cChilds = contents[0].getChildNodes(); - for (int j = 0; j < cChilds.getLength(); j++) { + for (size_t j = 0; j < cChilds.getLength(); j++) { ss << cChilds.item(j); } + stream << std::endl << " /* content */ "; stream << (ss.str().size() > 0 ? "\"" + escape(ss.str()) + "\", " : "NULL, "); + stream << std::endl << " /* contentexpr */ "; stream << (HAS_ATTR_CAST(contents[0], "expr") ? "\"" + ATTR_CAST(contents[0], "expr") + "\", " : "NULL, "); } else { - stream << "NULL, NULL, "; + stream << std::endl << " /* content */ "; + stream << "NULL,"; + stream << std::endl << " /* contentexpr */ "; + stream << "NULL,"; } + stream << std::endl << " /* params */ "; if (HAS_ATTR(send, "paramIndex")) { - stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(send, "paramIndex")) << "], "; + stream << "&scxml_elem_params[" << escape(ATTR(send, "paramIndex")) << "] "; } else { - stream << "NULL, "; + stream << "NULL "; } - stream << "NULL"; - stream << " }" << (i + 1 < sends.size() ? ",": "") << std::endl; + stream << std::endl << " }" << (i + 1 < sends.size() ? ",": "") << std::endl; send.setAttribute("documentOrder", toStr(i)); } stream << "};" << std::endl; @@ -857,67 +896,78 @@ void ChartToC::writeElementInfo(std::ostream& stream) { } NodeSet donedatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", _scxml, true); - stream << "static scxml_elem_donedata scxml_elem_donedatas[" << donedatas.size() + 1 << "] = {" << std::endl; - for (int i = 0; i < donedatas.size(); i++) { - Element donedata(donedatas[i]); - stream << " { "; - - // parent - stream << ATTR_CAST(donedata.getParentNode(), "documentOrder") << ", "; - - NodeSet contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata); - if (contents.size() > 0) { - std::stringstream ss; - NodeList cChilds = contents[0].getChildNodes(); - for (int j = 0; j < cChilds.getLength(); j++) { - ss << cChilds.item(j); - } - stream << (ss.str().size() > 0 ? "\"" + escape(ss.str()) + "\", " : "NULL, "); - stream << (HAS_ATTR_CAST(contents[0], "expr") ? "\"" + ATTR_CAST(contents[0], "expr") + "\", " : "NULL, "); - } else { - stream << "NULL, NULL, "; - } - - if (HAS_ATTR(donedata, "paramIndex")) { - stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(donedata, "paramIndex")) << "]"; - } else { - stream << "NULL"; - } - - stream << " }," << std::endl; - donedata.setAttribute("documentOrder", toStr(i)); - } - stream << " { 0, NULL, NULL }" << std::endl; - stream << "};" << std::endl; - stream << std::endl; + stream << "static const scxml_elem_donedata scxml_elem_donedatas[" << donedatas.size() + 1 << "] = {" << std::endl; + stream << " /* source, content, contentexpr, params */" << std::endl; + for (size_t i = 0; i < donedatas.size(); i++) { + Element donedata(donedatas[i]); + stream << " { "; + + // parent + stream << ATTR_CAST(donedata.getParentNode(), "documentOrder") << ", "; + + NodeSet contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata); + if (contents.size() > 0) { + std::stringstream ss; + NodeList cChilds = contents[0].getChildNodes(); + for (size_t j = 0; j < cChilds.getLength(); j++) { + ss << cChilds.item(j); + } + stream << (ss.str().size() > 0 ? "\"" + escape(ss.str()) + "\", " : "NULL, "); + stream << (HAS_ATTR_CAST(contents[0], "expr") ? "\"" + ATTR_CAST(contents[0], "expr") + "\", " : "NULL, "); + } else { + stream << "NULL, NULL, "; + } + + if (HAS_ATTR(donedata, "paramIndex")) { + stream << "&scxml_elem_params[" << escape(ATTR(donedata, "paramIndex")) << "]"; + } else { + stream << "NULL"; + } + + stream << " }," << std::endl; + donedata.setAttribute("documentOrder", toStr(i)); + } + stream << " { 0, NULL, NULL, NULL }" << std::endl; + stream << "};" << std::endl; + stream << std::endl; } void ChartToC::writeStates(std::ostream& stream) { - stream << "static scxml_state scxml_states[" << toStr(_states.size()) << "] = {" << std::endl; - for (int i = 0; i < _states.size(); i++) { + stream << "static const scxml_state scxml_states[" << toStr(_states.size()) << "] = {" << std::endl; + for (size_t i = 0; i < _states.size(); i++) { Element state(_states[i]); - stream << " { "; + stream << " { /* state number " << toStr(i) << " */" << std::endl; // name - stream << (HAS_ATTR(state, "id") ? "\"" + escape(ATTR(state, "id")) + "\"" : "NULL") << ", "; + stream << " /* name */ "; + stream << (HAS_ATTR(state, "id") ? "\"" + escape(ATTR(state, "id")) + "\"" : "NULL"); + stream << "," << std::endl; // parent - stream << (i == 0 ? "0" : ATTR_CAST(state.getParentNode(), "documentOrder")) << ", "; + stream << " /* parent */ "; + stream << (i == 0 ? "0" : ATTR_CAST(state.getParentNode(), "documentOrder")); + stream << "," << std::endl; // onentry - stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_entry" : "NULL") << ", "; + stream << " /* onentry */ "; + stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_entry" : "NULL"); + stream << "," << std::endl; // onexit - stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_exit" : "NULL") << ", "; + stream << " /* onexit */ "; + stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_exit" : "NULL"); + stream << "," << std::endl; // invokers - stream << (filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state).size() > 0 ? DOMUtils::idForNode(state) + "_invoke" : "NULL") << ", "; + stream << " /* invoke */ "; + stream << (filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state).size() > 0 ? DOMUtils::idForNode(state) + "_invoke" : "NULL"); + stream << "," << std::endl; // children std::string childBools; std::string childBoolsIdx; - for (int j = 0; j < _states.size(); j++) { + for (size_t j = 0; j < _states.size(); j++) { if (_states[j].getParentNode() == state) { childBools += "1"; childBoolsIdx += " " + toStr(j); @@ -925,16 +975,16 @@ void ChartToC::writeStates(std::ostream& stream) { childBools += "0"; } } - stream << "{ "; + stream << " /* children */ { "; writeCharArrayInitList(stream, childBools); stream << " /* " << childBools << "," << childBoolsIdx << " */"; - stream << " }, "; + stream << " }," << std::endl; // default completion NodeSet completion; if (isHistory(state)) { bool deep = (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")); - for (int j = 0; j < _states.size(); j++) { + for (size_t j = 0; j < _states.size(); j++) { if (deep) { if (isDescendant(_states[j], state.getParentNode()) && !isHistory(Element(_states[j]))) { completion.push_back(_states[j]); @@ -959,7 +1009,7 @@ void ChartToC::writeStates(std::ostream& stream) { // first child state Arabica::XPath::NodeSet initStates; NodeList childs = state.getChildNodes(); - for (int i = 0; i < childs.getLength(); i++) { + for (size_t i = 0; i < childs.getLength(); i++) { if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; if (isState(Element(childs.item(i)))) { @@ -972,7 +1022,7 @@ void ChartToC::writeStates(std::ostream& stream) { std::string descBools; std::string descBoolsIdx; - for (int j = 0; j < _states.size(); j++) { + for (size_t j = 0; j < _states.size(); j++) { if (isMember(_states[j], completion)) { descBools += "1"; descBoolsIdx += " " + toStr(j); @@ -980,15 +1030,15 @@ void ChartToC::writeStates(std::ostream& stream) { descBools += "0"; } } - stream << "{ "; + stream << " /* completion */ { "; writeCharArrayInitList(stream, descBools); stream << " /* " << descBools << "," << descBoolsIdx << " */"; - stream << " }, "; + stream << " }, \t" << std::endl; // ancestors std::string ancBools; std::string ancBoolsIdx; - for (int j = 0; j < _states.size(); j++) { + for (size_t j = 0; j < _states.size(); j++) { if (isDescendant(state, _states[j])) { ancBools += "1"; ancBoolsIdx += " " + toStr(j); @@ -996,17 +1046,16 @@ void ChartToC::writeStates(std::ostream& stream) { ancBools += "0"; } } - stream << "{ "; + stream << " /* ancestors */ { "; writeCharArrayInitList(stream, ancBools); stream << " /* " << ancBools << "," << ancBoolsIdx << " */"; - stream << " }, "; + stream << " }," << std::endl; - if (HAS_ATTR(state, "dataIndex")) { - stream << "(const scxml_elem_data*)&scxml_elem_datas[" << escape(ATTR(state, "dataIndex")) << "], "; - } else { - stream << "NULL, "; - } + stream << " /* data */ "; + stream << (HAS_ATTR(state, "dataIndex") ? "&scxml_elem_datas[" + escape(ATTR(state, "dataIndex")) + "]" : "NULL"); + stream << "," << std::endl; + stream << " /* type */ "; if (false) { } else if (iequals(TAGNAME(state), "initial")) { stream << "SCXML_STATE_INITIAL"; @@ -1027,8 +1076,9 @@ void ChartToC::writeStates(std::ostream& stream) { } else { // stream << "SCXML_STATE_COMPOUND"; } + stream << "," << std::endl; - stream << " }" << (i + 1 < _states.size() ? ",": "") << std::endl; + stream << " }" << (i + 1 < _states.size() ? ",": "") << std::endl; } stream << "};" << std::endl; stream << std::endl; @@ -1037,10 +1087,30 @@ void ChartToC::writeStates(std::ostream& stream) { void ChartToC::writeTransitions(std::ostream& stream) { - stream << "static scxml_transition scxml_transitions[" << toStr(_transitions.size()) << "] = {" << std::endl; - for (int i = 0; i < _transitions.size(); i++) { +#if 0 + // cross reference transition by document order - is this really needed?! + std::set elements; + elements.insert(_nsInfo.xmlNSPrefix + "transition"); + NodeSet transDocOrder = inDocumentOrder(elements, _scxml); + + stream << "static const " << _transDataType << " scxml_transitions_doc_order[" << toStr(_transitions.size()) << "] = {" << std::endl; + stream << " "; + std::string seperator = ""; + for (size_t i = 0; i < transDocOrder.size(); i++) { Element transition(_transitions[i]); - stream << " { "; + transition.setAttribute("documentOrder", toStr(i)); + stream << seperator << ATTR(transition, "postFixOrder"); + seperator = ", "; + } + + 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 transition(_transitions[i]); + stream << " { /* transition number " << ATTR(transition, "documentOrder") << " with priority " << toStr(i) << " */" << std::endl; /** uint16_t source; @@ -1054,19 +1124,24 @@ void ChartToC::writeTransitions(std::ostream& stream) { */ // source - stream << ATTR_CAST(transition.getParentNode(), "documentOrder") << ", "; + stream << " /* name */ "; + stream << ATTR_CAST(transition.getParentNode(), "documentOrder"); + stream << "," << std::endl; // targets + stream << " /* target */ "; if (HAS_ATTR(transition, "target")) { std::list targets = tokenize(ATTR(transition, "target")); std::string targetBools; - for (int j = 0; j < _states.size(); j++) { + std::string targetBoolsIdx; + for (size_t j = 0; j < _states.size(); j++) { Element state(_states[j]); if (HAS_ATTR(state, "id") && std::find(targets.begin(), targets.end(), escape(ATTR(state, "id"))) != targets.end()) { targetBools += "1"; + targetBoolsIdx += " " + toStr(j); } else { targetBools += "0"; } @@ -1074,28 +1149,34 @@ void ChartToC::writeTransitions(std::ostream& stream) { stream << "{ "; writeCharArrayInitList(stream, targetBools); - stream << " /* " << targetBools << " */"; - stream << " }, "; + stream << " /* " << targetBools << "," << targetBoolsIdx << " */"; + stream << " }"; } else { - stream << "{ NULL }, "; + stream << "{ NULL }"; } + stream << "," << std::endl; - // event - stream << (HAS_ATTR(transition, "event") ? "\"" + escape(ATTR(transition, "event")) + "\"" : "NULL") << ", "; + stream << " /* event */ "; + stream << (HAS_ATTR(transition, "event") ? "\"" + escape(ATTR(transition, "event")) + "\"" : "NULL"); + stream << "," << std::endl; - // condition - stream << (HAS_ATTR(transition, "cond") ? "\"" + escape(ATTR(transition, "cond")) + "\"" : "NULL") << ", "; + stream << " /* condition */ "; + stream << (HAS_ATTR(transition, "cond") ? "\"" + escape(ATTR(transition, "cond")) + "\"" : "NULL"); + stream << "," << std::endl; // on transition handlers + stream << " /* ontrans */ "; if (filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0 && !iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) { - stream << DOMUtils::idForNode(transition) + "_on_trans, "; + stream << DOMUtils::idForNode(transition) + "_on_trans"; } else { - stream << "NULL, "; + stream << "NULL"; } + stream << "," << std::endl; // type + stream << " /* type */ "; std::string seperator = ""; if (!HAS_ATTR(transition, "target")) { stream << seperator << "SCXML_TRANS_TARGETLESS"; @@ -1117,18 +1198,19 @@ void ChartToC::writeTransitions(std::ostream& stream) { seperator = " | "; } - if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) { - stream << seperator << "SCXML_TRANS_INITIAL"; - seperator = " | "; - } + if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) { + stream << seperator << "SCXML_TRANS_INITIAL"; + seperator = " | "; + } if (seperator.size() == 0) { stream << "0"; } - stream << ", "; + stream << "," << std::endl; // conflicts std::string conflictBools; + std::string conflictBoolsIdx; for (unsigned int j = 0; j < _transitions.size(); j++) { Element t2(_transitions[j]); if (hasIntersection(computeExitSet(transition), computeExitSet(t2)) || @@ -1136,32 +1218,36 @@ void ChartToC::writeTransitions(std::ostream& stream) { (isDescendant(getSourceState(transition), getSourceState(t2))) || (isDescendant(getSourceState(t2), getSourceState(transition)))) { conflictBools += "1"; + conflictBoolsIdx += " " + toStr(j); } else { conflictBools += "0"; } } - stream << "{ "; + stream << " /* conflicts */ { "; writeCharArrayInitList(stream, conflictBools); - stream << " /* " << conflictBools << " */"; - stream << " }, "; + stream << " /* " << conflictBools << "," << conflictBoolsIdx << " */"; + stream << " }, " << std::endl; // exit set std::string exitSetBools; + std::string exitSetBoolsIdx; NodeSet exitSet = computeExitSet(transition); for (unsigned int j = 0; j < _states.size(); j++) { Element state(_states[j]); if (isMember(state, exitSet)) { exitSetBools += "1"; + exitSetBoolsIdx += " " + toStr(j); } else { exitSetBools += "0"; } } - stream << "{ "; + stream << " /* exit set */ { "; writeCharArrayInitList(stream, exitSetBools); - stream << " /* " << exitSetBools << " */"; - stream << " }"; + stream << " /* " << exitSetBools << "," << exitSetBoolsIdx << " */"; - stream << " }" << (i + 1 < _transitions.size() ? ",": "") << std::endl; + stream << " }" << std::endl; + + stream << " }" << (i + 1 < _transitions.size() ? ",": "") << std::endl; } stream << "};" << std::endl; stream << std::endl; @@ -1234,7 +1320,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << "#endif" << std::endl; stream << std::endl; - stream << "MACRO_STEP:" << std::endl; + stream << "// MACRO_STEP:" << std::endl; stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl; stream << std::endl; @@ -1251,7 +1337,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << " if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {" << std::endl; - stream << " global_script(ctx, &scxml_states[0], NULL);" << std::endl; + stream << " global_script(ctx, &scxml_states[0], NULL);" << std::endl; stream << " bit_or(target_set, scxml_states[0].completion, " << _stateCharArraySize << ");" << std::endl; stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS | SCXML_CTX_INITIALIZED;" << std::endl; stream << " goto ESTABLISH_ENTRY_SET;" << std::endl; @@ -1271,7 +1357,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "SELECT_TRANSITIONS:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; + stream << " for (size_t 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; @@ -1328,34 +1414,34 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " printStateNames(ctx->history);" << std::endl; stream << "#endif" << std::endl; stream << std::endl; - - stream << "// REMEMBER_HISTORY:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW || 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 << std::endl; - stream << " // set those states who were enabled" << std::endl; - stream << " bit_and(history, ctx->config, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " // clear current history with completion mask - TODO: errornously clears nested history" << 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 << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << "ESTABLISH_ENTRY_SET:" << std::endl; + + stream << "// REMEMBER_HISTORY:" << std::endl; + stream << " for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW || 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 << std::endl; + stream << " // set those states who were enabled" << std::endl; + stream << " bit_and(history, ctx->config, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " // clear current history with completion mask - TODO: errornously clears nested history" << 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 << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << "ESTABLISH_ENTRY_SET:" << std::endl; stream << " // calculate new entry set" << std::endl; stream << " bit_copy(entry_set, target_set, " << _stateCharArraySize << ");" << std::endl; stream << std::endl; stream << " // iterate for ancestors" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << 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 << " bit_or(entry_set, scxml_states[i].ancestors, " << _stateCharArraySize << ");" << std::endl; stream << " }" << std::endl; @@ -1363,7 +1449,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << " // iterate for descendants" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << 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 << " switch (scxml_states[i].type) {" << std::endl; stream << " case SCXML_STATE_PARALLEL: {" << std::endl; @@ -1373,10 +1459,10 @@ void ChartToC::writeFSM(std::ostream& stream) { 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 << " 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 << " for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << 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; @@ -1392,7 +1478,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " break;" << std::endl; stream << " }" << std::endl; stream << " case SCXML_STATE_INITIAL: {" << std::endl; - stream << " for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << 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; @@ -1404,9 +1490,9 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " break;" << std::endl; stream << " }" << std::endl; stream << " case SCXML_STATE_COMPOUND: { // we need to check whether one child is already in entry_set" << std::endl; - stream << " if (!bit_has_and(entry_set, scxml_states[i].children, " << _stateCharArraySize << ") &&" << std::endl; - stream << " (!bit_has_and(ctx->config, scxml_states[i].children, " << _stateCharArraySize << ") ||" << std::endl; - stream << " bit_has_and(exit_set, scxml_states[i].children, " << _stateCharArraySize << ")))" << std::endl; + stream << " if (!bit_has_and(entry_set, scxml_states[i].children, " << _stateCharArraySize << ") &&" << std::endl; + stream << " (!bit_has_and(ctx->config, scxml_states[i].children, " << _stateCharArraySize << ") ||" << std::endl; + stream << " bit_has_and(exit_set, scxml_states[i].children, " << _stateCharArraySize << ")))" << std::endl; stream << " {" << std::endl; stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; stream << " }" << std::endl; @@ -1423,21 +1509,22 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << "#endif" << std::endl; stream << std::endl; - stream << "// EXIT_STATES:" << std::endl; - stream << " for (int i = SCXML_NUMBER_STATES - 1; i >= 0; i--) {" << std::endl; - stream << " if (IS_SET(i, exit_set) && IS_SET(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 << " }" << std::endl; - stream << " }" << std::endl; - stream << std::endl; + 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 << " // 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 << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; stream << "// TAKE_TRANSITIONS:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << 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) == 0) {" << std::endl; stream << " // call executable content in transition" << std::endl; stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl; @@ -1457,7 +1544,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "// ENTER_STATES:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << 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 << " // these are no proper states" << std::endl; stream << " if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_DEEP ||" << std::endl; @@ -1485,7 +1572,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << " // take history transitions" << std::endl; - stream << " for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << 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 << " (scxml_transitions[j].type & SCXML_TRANS_HISTORY) &&" << std::endl; stream << " scxml_states[scxml_transitions[j].source].parent == i) {" << std::endl; @@ -1498,7 +1585,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " }" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; - stream << std::endl; + stream << std::endl; stream << " // handle final states" << std::endl; stream << " if unlikely(scxml_states[i].type == SCXML_STATE_FINAL) {" << std::endl; @@ -1506,13 +1593,13 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL;" << std::endl; stream << " } else {" << std::endl; stream << " // raise done event" << std::endl; - stream << " scxml_elem_donedata* donedata = &scxml_elem_donedatas[0];" << std::endl; - stream << " while(ELEM_DONEDATA_IS_SET(donedata)) {" << std::endl; - stream << " if unlikely(donedata->source == i)" << std::endl; - stream << " break;" << std::endl; - stream << " donedata++;" << std::endl; - stream << " }" << std::endl; - stream << " ctx->raise_done_event(ctx, &scxml_states[scxml_states[i].parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl; + stream << " const scxml_elem_donedata* donedata = &scxml_elem_donedatas[0];" << std::endl; + stream << " while(ELEM_DONEDATA_IS_SET(donedata)) {" << std::endl; + stream << " if unlikely(donedata->source == i)" << std::endl; + stream << " break;" << std::endl; + stream << " donedata++;" << std::endl; + stream << " }" << std::endl; + stream << " ctx->raise_done_event(ctx, &scxml_states[scxml_states[i].parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl; stream << " }" << std::endl; stream << std::endl; @@ -1523,11 +1610,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 (int j = 0; j < SCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " for (size_t j = 0; j < SCXML_NUMBER_STATES; j++) {" << std::endl; stream << " if unlikely(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 << " for (int k = 0; k < SCXML_NUMBER_STATES; k++) {" << 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 (scxml_states[k].type == SCXML_STATE_FINAL) {" << std::endl; stream << " bit_and_not(parallel_children, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl; @@ -1551,7 +1638,7 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; // stream << "// HISTORY_TRANSITIONS:" << std::endl; -// stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << 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; @@ -1578,14 +1665,14 @@ NodeSet ChartToC::inPostFixOrder(const std::set& eleme void ChartToC::inPostFixOrder(const std::set& elements, const Element& root, NodeSet& nodes) { NodeList children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { + for (size_t 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++) { + for (size_t i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; Arabica::DOM::Element childElem(children.item(i)); @@ -1608,7 +1695,7 @@ void ChartToC::inDocumentOrder(const std::set& elements, const Elem } NodeList children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { + for (size_t i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; Arabica::DOM::Element childElem(children.item(i)); diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h index e600241..1513235 100644 --- a/src/uscxml/transform/ChartToC.h +++ b/src/uscxml/transform/ChartToC.h @@ -81,9 +81,11 @@ protected: size_t _transCharArraySize; std::string _transCharArrayInit; + std::string _transDataType; size_t _stateCharArraySize; std::string _stateCharArrayInit; + std::string _stateDataType; }; } diff --git a/test/src/test-c-machine.cpp b/test/src/test-c-machine.cpp index c8848ac..35f06a4 100644 --- a/test/src/test-c-machine.cpp +++ b/test/src/test-c-machine.cpp @@ -493,15 +493,15 @@ int exec_content_foreach_done(const scxml_ctx* ctx, const scxml_elem_foreach* fo int exec_content_log(const scxml_ctx* ctx, const char* label, const char* expr) { try { if (label != NULL) { - printf("%s%s", label, (expr != NULL ? ": " : "")); - } - if (expr != NULL) { - std::string msg = USER_DATA(ctx)->datamodel.evalAsString(expr); - printf("%s", msg.c_str()); - } - if (label != NULL || expr != NULL) { - printf("\n"); - } + printf("%s%s", label, (expr != NULL ? ": " : "")); + } + if (expr != NULL) { + std::string msg = USER_DATA(ctx)->datamodel.evalAsString(expr); + printf("%s", msg.c_str()); + } + if (label != NULL || expr != NULL) { + printf("\n"); + } } catch (Event e) { exec_content_raise(ctx, e.name.c_str()); return SCXML_ERR_EXEC_CONTENT; @@ -546,6 +546,10 @@ void* dequeue_internal(const scxml_ctx* ctx) { int main(int argc, char** argv) { + std::cout << "sizeof(scxml_state): " << sizeof(scxml_state) << std::endl; + std::cout << "sizeof(scxml_transition): " << sizeof(scxml_transition) << std::endl; + std::cout << "sizeof(scxml_ctx): " << sizeof(scxml_ctx) << std::endl; + #ifdef APPLE mach_timebase_info_data_t timebase_info; mach_timebase_info(&timebase_info); @@ -574,7 +578,7 @@ int main(int argc, char** argv) { const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); if (envBenchmarkRuns != NULL) { benchmarkRuns = strTo(envBenchmarkRuns); - } + } size_t remainingRuns = benchmarkRuns; @@ -594,8 +598,8 @@ int main(int argc, char** argv) { double avgDm = 0; #endif - Timer tTotal; - tTotal.start(); + Timer tTotal; + tTotal.start(); while(remainingRuns-- > 0) { memset(&ctx, 0, sizeof(scxml_ctx)); @@ -628,14 +632,14 @@ int main(int argc, char** argv) { microSteps = 0; while((err = scxml_step(&ctx)) == SCXML_ERR_OK) { - t.stop(); - microSteps++; - if (ctx.event != NULL) { - delete ((Event*)(ctx.event)); - } - t.start(); + t.stop(); + microSteps++; + if (ctx.event != NULL) { + delete ((Event*)(ctx.event)); + } + t.start(); } - microSteps++; + microSteps++; assert(ctx.flags & SCXML_CTX_TOP_LEVEL_FINAL); @@ -653,17 +657,20 @@ int main(int argc, char** argv) { } } - assert(IS_SET(passIdx, ctx.config)); + if(!IS_SET(passIdx, ctx.config)) { + std::cerr << "Interpreter did not end in pass" << std::endl; + exit(EXIT_FAILURE); + } interpreterInfo.delayQueue.cancelAllEvents(); interpreterInfo.eq.clear(); interpreterInfo.iq.clear(); } - tTotal.stop(); - std::cout << benchmarkRuns << " iterations" << std::endl; - std::cout << tTotal.elapsed * 1000.0 << " ms in total" << std::endl; + tTotal.stop(); + std::cout << benchmarkRuns << " iterations" << std::endl; + std::cout << tTotal.elapsed * 1000.0 << " ms in total" << std::endl; std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms per execution" << std::endl; - std::cout << microSteps << " microsteps per iteration" << std::endl; - std::cout << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep" << std::endl; + std::cout << microSteps << " microsteps per iteration" << std::endl; + std::cout << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep" << std::endl; #ifdef BUILD_PROFILING std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; std::cout << ((avg - avgDm) * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep \\wo datamodel" << std::endl; diff --git a/test/src/test-c-machine.machine.c b/test/src/test-c-machine.machine.c index efc4c22..e9616dc 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 11 -#define SCXML_NUMBER_TRANSITIONS 13 +#define SCXML_NUMBER_STATES 5 +#define SCXML_NUMBER_TRANSITIONS 4 #define SCXML_TRANS_SPONTANEOUS 0x01 #define SCXML_TRANS_TARGETLESS 0x02 @@ -93,26 +93,26 @@ struct scxml_elem_data { struct scxml_state { const char* name; // eventual name - uint16_t parent; // parent - exec_content_t on_entry; // on entry handlers - exec_content_t on_exit; // on exit handlers - invoke_t invoke; // invocations - char children[2]; // all children - char completion[2]; // default completion - char ancestors[2]; // all ancestors + const uint8_t parent; // parent + 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 scxml_elem_data* data; - uint8_t type; // atomic, parallel, compound, final, history + const uint8_t type; // atomic, parallel, compound, final, history }; struct scxml_transition { - uint16_t source; - char target[2]; + const uint8_t source; + const char target[1]; const char* event; const char* condition; - exec_content_t on_transition; - uint8_t type; - char conflicts[2]; - char exit_set[2]; + const exec_content_t on_transition; + const uint8_t type; + const char conflicts[1]; + const char exit_set[1]; }; struct scxml_elem_foreach { @@ -128,7 +128,7 @@ struct scxml_elem_param { }; struct scxml_elem_donedata { - uint16_t source; + const uint8_t source; const char* content; const char* contentexpr; const scxml_elem_param* params; @@ -142,12 +142,11 @@ struct scxml_elem_invoke { const char* id; const char* idlocation; const char* namelist; - uint8_t autoforward; + const uint8_t autoforward; const scxml_elem_param* params; const exec_content_finalize_t* finalize; const char* content; const char* contentexpr; - void* user_data; }; struct scxml_elem_send { @@ -165,16 +164,15 @@ struct scxml_elem_send { const char* content; const char* contentexpr; const scxml_elem_param* params; - void* user_data; }; 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,91 +196,64 @@ struct scxml_ctx { invoke_t invoke; }; -static scxml_elem_data scxml_elem_datas[2] = { - { "Var1", NULL, "0", NULL }, +static const scxml_elem_data scxml_elem_datas[3] = { + /* id, src, expr, content */ + { "Var1", NULL, "1", NULL }, + { "Var2", NULL, NULL, NULL }, { NULL, NULL, NULL, NULL } }; -static scxml_elem_send scxml_elem_sends[1] = { - { "timeout", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "'1s'", NULL, NULL, NULL, NULL, NULL } +static const scxml_elem_param scxml_elem_params[2] = { + /* name, expr, location */ + { "aParam", "Var1", NULL }, + { NULL, NULL, NULL } +}; + +static const scxml_elem_send scxml_elem_sends[1] = { + { + /* event */ "event1", + /* eventexpr */ NULL, + /* target */ NULL, + /* targetexpr */ NULL, + /* type */ NULL, + /* typeexpr */ NULL, + /* id */ NULL, + /* idlocation */ NULL, + /* delay */ NULL, + /* delayexpr */ NULL, + /* namelist */ NULL, + /* content */ NULL, + /* contentexpr */ NULL, + /* params */ &scxml_elem_params[0] + } }; -static scxml_elem_donedata scxml_elem_donedatas[1] = { - { 0, NULL, NULL } +static const scxml_elem_donedata scxml_elem_donedatas[1] = { + /* source, content, contentexpr, params */ + { 0, NULL, NULL, NULL } }; static int global_script(const scxml_ctx* ctx, const scxml_state* state, const void* event) { return SCXML_ERR_OK; } -static int s0_on_exit_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { +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; - } - if likely(ctx->exec_content_log != NULL) { - if unlikely((ctx->exec_content_log(ctx, "Var1 is", "Var1")) != SCXML_ERR_OK) return err; + if ((ctx->exec_content_assign(ctx, "Var1", "2")) != SCXML_ERR_OK) return err; } else { return SCXML_ERR_MISSING_CALLBACK; } - return SCXML_ERR_OK; -} - -static int s0_on_exit(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - s0_on_exit_0(ctx, state, event); - return SCXML_ERR_OK; -} - -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_send != NULL) { if ((ctx->exec_content_send(ctx, &scxml_elem_sends[0])) != SCXML_ERR_OK) return err; } else { return SCXML_ERR_MISSING_CALLBACK; } - if likely(ctx->exec_content_raise != NULL) { - if unlikely((ctx->exec_content_raise(ctx, "event1")) != SCXML_ERR_OK) return err; - } else { - return SCXML_ERR_MISSING_CALLBACK; - } - return SCXML_ERR_OK; -} - -static int s0_initial(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, "event2")) != SCXML_ERR_OK) return err; - } else { - return SCXML_ERR_MISSING_CALLBACK; - } - if likely(ctx->exec_content_log != NULL) { - if unlikely((ctx->exec_content_log(ctx, "initial transition in s0", NULL)) != 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); - s0_initial(ctx, state, event); - return SCXML_ERR_OK; -} - -static int s03_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, "Var1 when entering s03", "Var1")) != SCXML_ERR_OK) return err; - } else { - return SCXML_ERR_MISSING_CALLBACK; - } - return SCXML_ERR_OK; -} - -static int s03_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - s03_on_entry_0(ctx, state, event); return SCXML_ERR_OK; } @@ -316,55 +287,130 @@ static int fail_on_entry(const scxml_ctx* ctx, const scxml_state* state, const v return SCXML_ERR_OK; } -static int sh1_transition0_on_trans(const scxml_ctx* ctx, const scxml_state* state, const void* event) { +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_raise != NULL) { - if unlikely((ctx->exec_content_raise(ctx, "event3")) != SCXML_ERR_OK) return err; - } else { - return SCXML_ERR_MISSING_CALLBACK; - } - if likely(ctx->exec_content_log != NULL) { - if unlikely((ctx->exec_content_log(ctx, "history transition in sh1", NULL)) != SCXML_ERR_OK) return err; + if likely(ctx->exec_content_assign != NULL) { + if ((ctx->exec_content_assign(ctx, "Var2", "_event.data.aParam")) != SCXML_ERR_OK) return err; } else { return SCXML_ERR_MISSING_CALLBACK; } return SCXML_ERR_OK; } -static scxml_state scxml_states[11] = { - { NULL, 0, NULL, NULL, NULL, { 0x82, 0x07 /* 01000001111, 1 7 8 9 10 */ }, { 0x02, 0x00 /* 01000000000, 1 */ }, { 0x00, 0x00 /* 00000000000, */ }, (const scxml_elem_data*)&scxml_elem_datas[0], SCXML_STATE_COMPOUND }, - { "s0", 0, s0_on_entry, s0_on_exit, NULL, { 0x7c, 0x00 /* 00111110000, 2 3 4 5 6 */ }, { 0x04, 0x00 /* 00100000000, 2 */ }, { 0x01, 0x00 /* 10000000000, 0 */ }, NULL, SCXML_STATE_COMPOUND }, - { NULL, 1, NULL, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x03, 0x00 /* 11000000000, 0 1 */ }, NULL, SCXML_STATE_INITIAL }, - { "sh1", 1, NULL, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x74, 0x00 /* 00101110000, 2 4 5 6 */ }, { 0x03, 0x00 /* 11000000000, 0 1 */ }, NULL, SCXML_STATE_HISTORY_SHALLOW }, - { "s01", 1, NULL, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x03, 0x00 /* 11000000000, 0 1 */ }, NULL, SCXML_STATE_ATOMIC }, - { "s02", 1, NULL, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x03, 0x00 /* 11000000000, 0 1 */ }, NULL, SCXML_STATE_ATOMIC }, - { "s03", 1, s03_on_entry, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x03, 0x00 /* 11000000000, 0 1 */ }, NULL, SCXML_STATE_ATOMIC }, - { "s2", 0, NULL, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x01, 0x00 /* 10000000000, 0 */ }, NULL, SCXML_STATE_ATOMIC }, - { "s3", 0, NULL, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x01, 0x00 /* 10000000000, 0 */ }, NULL, SCXML_STATE_ATOMIC }, - { "pass", 0, pass_on_entry, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x01, 0x00 /* 10000000000, 0 */ }, NULL, SCXML_STATE_FINAL }, - { "fail", 0, fail_on_entry, NULL, NULL, { 0x00, 0x00 /* 00000000000, */ }, { 0x00, 0x00 /* 00000000000, */ }, { 0x01, 0x00 /* 10000000000, 0 */ }, NULL, SCXML_STATE_FINAL } +static const scxml_state scxml_states[5] = { + { /* state number 0 */ + /* name */ NULL, + /* parent */ 0, + /* onentry */ NULL, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x1e /* 01111, 1 2 3 4 */ }, + /* completion */ { 0x02 /* 01000, 1 */ }, + /* ancestors */ { 0x00 /* 00000, */ }, + /* 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 */ { 0x00 /* 00000, */ }, + /* completion */ { 0x00 /* 00000, */ }, + /* ancestors */ { 0x01 /* 10000, 0 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_ATOMIC, + }, + { /* state number 2 */ + /* name */ "s1", + /* parent */ 0, + /* onentry */ NULL, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00 /* 00000, */ }, + /* completion */ { 0x00 /* 00000, */ }, + /* ancestors */ { 0x01 /* 10000, 0 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_ATOMIC, + }, + { /* state number 3 */ + /* name */ "pass", + /* parent */ 0, + /* onentry */ pass_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00 /* 00000, */ }, + /* completion */ { 0x00 /* 00000, */ }, + /* ancestors */ { 0x01 /* 10000, 0 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_FINAL, + }, + { /* state number 4 */ + /* name */ "fail", + /* parent */ 0, + /* onentry */ fail_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00 /* 00000, */ }, + /* completion */ { 0x00 /* 00000, */ }, + /* ancestors */ { 0x01 /* 10000, 0 */ }, + /* data */ NULL, + /* type */ SCXML_STATE_FINAL, + } +}; + +static const uint8_t scxml_transitions_doc_order[4] = { + 0, 1, 2, 3 }; -static scxml_transition scxml_transitions[13] = { - { 2, { 0x08, 0x00 /* 00010000000 */ }, NULL, NULL, NULL, SCXML_TRANS_SPONTANEOUS | SCXML_TRANS_INITIAL, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 3, { 0x10, 0x00 /* 00001000000 */ }, NULL, NULL, sh1_transition0_on_trans, SCXML_TRANS_SPONTANEOUS | SCXML_TRANS_HISTORY, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 4, { 0x20, 0x00 /* 00000100000 */ }, "event1", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0x7c, 0x00 /* 00111110000 */ } }, - { 4, { 0x00, 0x04 /* 00000000001 */ }, "*", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 5, { 0x40, 0x00 /* 00000010000 */ }, "event2", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0x7c, 0x00 /* 00111110000 */ } }, - { 5, { 0x00, 0x04 /* 00000000001 */ }, "*", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 6, { 0x02, 0x00 /* 01000000000 */ }, "event3", "Var1==0", NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 6, { 0x80, 0x00 /* 00000001000 */ }, "event1", "Var1==1", NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 6, { 0x00, 0x04 /* 00000000001 */ }, "*", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 7, { 0x00, 0x01 /* 00000000100 */ }, "event2", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 7, { 0x00, 0x04 /* 00000000001 */ }, "*", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 8, { 0x00, 0x04 /* 00000000001 */ }, "event3", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } }, - { 8, { 0x00, 0x02 /* 00000000010 */ }, "timeout", NULL, NULL, 0, { 0xff, 0x1f /* 1111111111111 */ }, { 0xfe, 0x07 /* 01111111111 */ } } +static const scxml_transition scxml_transitions[4] = { + { /* transition number 0 with priority 0 */ + /* name */ 1, + /* target */ { 0x04 /* 00100, 2 */ }, + /* event */ "event1", + /* condition */ NULL, + /* ontrans */ s0_transition0_on_trans, + /* type */ 0, + /* conflicts */ { 0x0f /* 1111, 0 1 2 3 */ }, + /* exit set */ { 0x1e /* 01111, 1 2 3 4 */ } + }, + { /* transition number 1 with priority 1 */ + /* name */ 1, + /* target */ { 0x10 /* 00001, 4 */ }, + /* event */ "*", + /* condition */ NULL, + /* ontrans */ NULL, + /* type */ 0, + /* conflicts */ { 0x0f /* 1111, 0 1 2 3 */ }, + /* exit set */ { 0x1e /* 01111, 1 2 3 4 */ } + }, + { /* transition number 2 with priority 2 */ + /* name */ 2, + /* target */ { 0x08 /* 00010, 3 */ }, + /* event */ NULL, + /* condition */ "Var2==2", + /* ontrans */ NULL, + /* type */ SCXML_TRANS_SPONTANEOUS, + /* conflicts */ { 0x0f /* 1111, 0 1 2 3 */ }, + /* exit set */ { 0x1e /* 01111, 1 2 3 4 */ } + }, + { /* transition number 3 with priority 3 */ + /* name */ 2, + /* target */ { 0x10 /* 00001, 4 */ }, + /* event */ NULL, + /* condition */ NULL, + /* ontrans */ NULL, + /* type */ SCXML_TRANS_SPONTANEOUS, + /* conflicts */ { 0x0f /* 1111, 0 1 2 3 */ }, + /* exit set */ { 0x1e /* 01111, 1 2 3 4 */ } + } }; #ifdef SCXML_VERBOSE static void printStateNames(const char* a) { const char* seperator = ""; - for (int i = 0; i < SCXML_NUMBER_STATES; i++) { + for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { if (IS_SET(i, a)) { printf("%s%s", seperator, (scxml_states[i].name != NULL ? scxml_states[i].name : "UNK")); seperator = ", "; @@ -375,9 +421,9 @@ static void printStateNames(const char* a) { static void printBitsetIndices(const char* a, size_t length) { const char* seperator = ""; - for (int i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) { if (IS_SET(i, a)) { - printf("%s%d", seperator, i); + printf("%s%lu", seperator, i); seperator = ", "; } } @@ -439,15 +485,15 @@ MACRO_STEP: return SCXML_ERR_DONE; int err = SCXML_ERR_OK; - 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 conflicts[1] = {0}; + char target_set[1] = {0}; + char exit_set[1] = {0}; + char trans_set[1] = {0}; + char entry_set[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; } @@ -464,7 +510,7 @@ MACRO_STEP: } SELECT_TRANSITIONS: - for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) { + for (size_t i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) { // never select history or initial transitions automatically if unlikely(scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) continue; @@ -479,20 +525,20 @@ SELECT_TRANSITIONS: ctx->flags |= SCXML_CTX_TRANSITION_FOUND; // transitions that are pre-empted - bit_or(conflicts, scxml_transitions[i].conflicts, 2); + 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_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; @@ -515,77 +561,72 @@ SELECT_TRANSITIONS: printStateNames(ctx->history); #endif - - // REMEMBER_HISTORY: - for (int i = 0; i < SCXML_NUMBER_STATES; i++) { +// REMEMBER_HISTORY: + for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW || 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); - + char history[1] = {0}; + bit_copy(history, scxml_states[i].completion, 1); + // set those states who were enabled - bit_and(history, ctx->config, 2); - + bit_and(history, ctx->config, 1); + // clear current history with completion mask - TODO: errornously clears nested history - bit_and_not(ctx->history, scxml_states[i].completion, 2); - + bit_and_not(ctx->history, scxml_states[i].completion, 1); + // set history - bit_or(ctx->history, history, 2); + bit_or(ctx->history, history, 1); } } } -#ifdef SCXML_VERBOSE - printf("Transitions: "); - printBitsetIndices(trans_set, sizeof(char) * 8 * 2); -#endif 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 (int i = 0; i < SCXML_NUMBER_STATES; i++) { + 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); + bit_or(entry_set, scxml_states[i].ancestors, 1); } } // iterate for descendants - for (int i = 0; i < SCXML_NUMBER_STATES; i++) { + for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { if (IS_SET(i, entry_set)) { switch (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) && + char history_targets[1] = {0}; + if (!bit_has_and(scxml_states[i].completion, ctx->history, 1) && !IS_SET(scxml_states[i].parent, ctx->config)) { // nothing set for history, look for a default transition or enter parents completion - for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) { + 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); + bit_or(entry_set, scxml_transitions[j].target, 1); SET_BIT(j, trans_set); break; } } // TODO: enter parents default completion here } 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(history_targets, scxml_states[i].completion, 1); + bit_and(history_targets, ctx->history, 1); + bit_or(entry_set, history_targets, 1); } break; } case SCXML_STATE_INITIAL: { - for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) { + 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_or(entry_set, scxml_transitions[j].target, 1); // one target may have been above, reestablish completion // goto ADD_DESCENDANTS; // initial will have to be first! } @@ -593,11 +634,11 @@ 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); + bit_or(entry_set, scxml_states[i].completion, 1); } break; } @@ -605,8 +646,14 @@ ESTABLISH_ENTRY_SET: } } +#ifdef SCXML_VERBOSE + printf("Transitions: "); + printBitsetIndices(trans_set, sizeof(char) * 8 * 1); +#endif + // EXIT_STATES: - for (int i = SCXML_NUMBER_STATES - 1; i >= 0; i--) { + size_t i = SCXML_NUMBER_STATES; + while(i-- > 0) { if (IS_SET(i, exit_set) && IS_SET(i, ctx->config)) { // call all on exit handlers if (scxml_states[i].on_exit != NULL) { @@ -618,7 +665,7 @@ ESTABLISH_ENTRY_SET: } // TAKE_TRANSITIONS: - for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) { + for (size_t i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) { if (IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY) == 0) { // call executable content in transition if (scxml_transitions[i].on_transition != NULL) { @@ -636,7 +683,7 @@ ESTABLISH_ENTRY_SET: #endif // ENTER_STATES: - for (int i = 0; i < SCXML_NUMBER_STATES; i++) { + for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { if (IS_SET(i, entry_set) && !IS_SET(i, ctx->config)) { // these are no proper states if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_DEEP || @@ -660,7 +707,7 @@ ESTABLISH_ENTRY_SET: } // take history transitions - for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) { + for (size_t j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) { if unlikely(IS_SET(j, trans_set) && (scxml_transitions[j].type & SCXML_TRANS_HISTORY) && scxml_states[scxml_transitions[j].source].parent == i) { @@ -680,7 +727,7 @@ ESTABLISH_ENTRY_SET: ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL; } else { // raise done event - scxml_elem_donedata* donedata = &scxml_elem_donedatas[0]; + const scxml_elem_donedata* donedata = &scxml_elem_donedatas[0]; while(ELEM_DONEDATA_IS_SET(donedata)) { if unlikely(donedata->source == i) break; @@ -696,20 +743,20 @@ ESTABLISH_ENTRY_SET: * 3. Iterate all active final states and remove their ancestors * 4. If a state remains, not all children of a parallel are final */ - for (int j = 0; j < SCXML_NUMBER_STATES; j++) { + for (size_t j = 0; j < SCXML_NUMBER_STATES; j++) { if unlikely(scxml_states[j].type == SCXML_STATE_PARALLEL) { - char parallel_children[2] = {0, 0}; + char parallel_children[1] = {0}; size_t parallel = j; - for (int k = 0; k < SCXML_NUMBER_STATES; k++) { + 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 (scxml_states[k].type == SCXML_STATE_FINAL) { - bit_and_not(parallel_children, scxml_states[k].ancestors, 2); + bit_and_not(parallel_children, scxml_states[k].ancestors, 1); } else { SET_BIT(k, parallel_children); } } } - if unlikely(!bit_any_set(parallel_children, 2)) { + if unlikely(!bit_any_set(parallel_children, 1)) { ctx->raise_done_event(ctx, &scxml_states[parallel], NULL); } } diff --git a/test/src/test-lifecycle.cpp b/test/src/test-lifecycle.cpp index 7ac40fa..eeaad96 100644 --- a/test/src/test-lifecycle.cpp +++ b/test/src/test-lifecycle.cpp @@ -275,9 +275,9 @@ int main(int argc, char** argv) { Interpreter interpreter = Interpreter::fromXML(xml, ""); interpreter.addMonitor(mon); - callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); - callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); - callBackSeq.push_back(USCXML_BEFOREENTERINGSTATE); + callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); + callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); + callBackSeq.push_back(USCXML_BEFOREENTERINGSTATE); callBackSeq.push_back(USCXML_AFTERENTERINGSTATE); callBackSeq.push_back(USCXML_BEFOREMICROSTEP); @@ -301,10 +301,10 @@ int main(int argc, char** argv) { callBackSeq.push_back(USCXML_BEFORECOMPLETION); callBackSeq.push_back(USCXML_AFTERCOMPLETION); - assert(interpreter.getState() == USCXML_INSTANTIATED); - assert(interpreter.step() == USCXML_INITIALIZED); + assert(interpreter.getState() == USCXML_INSTANTIATED); + assert(interpreter.step() == USCXML_INITIALIZED); + assert(interpreter.step() == USCXML_MICROSTEPPED); assert(interpreter.step() == USCXML_MICROSTEPPED); - assert(interpreter.step() == USCXML_MICROSTEPPED); assert(interpreter.step() == USCXML_FINISHED); assert(callBackSeq.empty()); } @@ -322,8 +322,8 @@ int main(int argc, char** argv) { Interpreter interpreter = Interpreter::fromXML(xml, ""); interpreter.addMonitor(mon); - callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); - callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); + callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); + callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); callBackSeq.push_back(USCXML_BEFOREENTERINGSTATE); callBackSeq.push_back(USCXML_AFTERENTERINGSTATE); @@ -340,13 +340,13 @@ int main(int argc, char** argv) { callBackSeq.push_back(USCXML_AFTERCOMPLETION); assert(interpreter.getState() == USCXML_INSTANTIATED); - assert(interpreter.step() == USCXML_INITIALIZED); - assert(interpreter.step() == USCXML_MICROSTEPPED); + assert(interpreter.step() == USCXML_INITIALIZED); + assert(interpreter.step() == USCXML_MICROSTEPPED); assert(interpreter.step() == USCXML_FINISHED); interpreter.reset(); - callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); - callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); + callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); + callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); callBackSeq.push_back(USCXML_BEFOREENTERINGSTATE); callBackSeq.push_back(USCXML_AFTERENTERINGSTATE); @@ -363,8 +363,8 @@ int main(int argc, char** argv) { callBackSeq.push_back(USCXML_AFTERCOMPLETION); assert(interpreter.getState() == USCXML_INSTANTIATED); - assert(interpreter.step() == USCXML_INITIALIZED); - assert(interpreter.step() == USCXML_MICROSTEPPED); + assert(interpreter.step() == USCXML_INITIALIZED); + assert(interpreter.step() == USCXML_MICROSTEPPED); assert(interpreter.step() == USCXML_FINISHED); } @@ -387,8 +387,8 @@ int main(int argc, char** argv) { Interpreter interpreter = Interpreter::fromXML(xml, ""); interpreter.addMonitor(mon); - callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); - callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); + callBackSeq.push_back(USCXML_BEFORETAKINGTRANSITION); + callBackSeq.push_back(USCXML_AFTERTAKINGTRANSITION); callBackSeq.push_back(USCXML_BEFOREENTERINGSTATE); callBackSeq.push_back(USCXML_BEFOREEXECUTINGCONTENT); callBackSeq.push_back(USCXML_AFTEREXECUTINGCONTENT); @@ -417,11 +417,11 @@ int main(int argc, char** argv) { callBackSeq.push_back(USCXML_BEFORECOMPLETION); callBackSeq.push_back(USCXML_AFTERCOMPLETION); - assert(interpreter.getState() == USCXML_INSTANTIATED); - assert(interpreter.step() == USCXML_INITIALIZED); + assert(interpreter.getState() == USCXML_INSTANTIATED); + assert(interpreter.step() == USCXML_INITIALIZED); assert(interpreter.step() == USCXML_IDLE); assert(interpreter.step(true) == USCXML_MACROSTEPPED); - assert(interpreter.step() == USCXML_MICROSTEPPED); + assert(interpreter.step() == USCXML_MICROSTEPPED); assert(interpreter.step() == USCXML_FINISHED); } } diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp index aa2bff5..0ac33a7 100644 --- a/test/src/test-w3c.cpp +++ b/test/src/test-w3c.cpp @@ -81,7 +81,7 @@ class W3CStatusMonitor : public uscxml::InterpreterMonitor { void beforeCompletion(uscxml::Interpreter tmp) { if (interpreter.getConfiguration().size() == 1 && interpreter.isInState("pass")) { #ifndef BUILD_PROFILING - std::cout << "TEST SUCCEEDED" << std::endl; + std::cout << "TEST SUCCEEDED" << std::endl; #endif retCode = EXIT_SUCCESS; return; @@ -89,34 +89,34 @@ class W3CStatusMonitor : public uscxml::InterpreterMonitor { #ifndef BUILD_PROFILING std::cout << "TEST FAILED" << std::endl; #endif - retCode = EXIT_FAILURE; - } + retCode = EXIT_FAILURE; + } }; int main(int argc, char** argv) { using namespace uscxml; #ifdef APPLE - mach_timebase_info_data_t timebase_info; - mach_timebase_info(&timebase_info); - - const uint64_t NANOS_PER_MSEC = 1000000ULL; - double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC; - - thread_time_constraint_policy_data_t policy; - policy.period = 0; - policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work - policy.constraint = (uint32_t)(10 * clock2abs); - policy.preemptible = FALSE; - - int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()), - THREAD_TIME_CONSTRAINT_POLICY, - (thread_policy_t)&policy, - THREAD_TIME_CONSTRAINT_POLICY_COUNT); - if (kr != KERN_SUCCESS) { - mach_error("thread_policy_set:", kr); - exit(1); - } + mach_timebase_info_data_t timebase_info; + mach_timebase_info(&timebase_info); + + const uint64_t NANOS_PER_MSEC = 1000000ULL; + double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC; + + thread_time_constraint_policy_data_t policy; + policy.period = 0; + policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work + policy.constraint = (uint32_t)(10 * clock2abs); + policy.preemptible = FALSE; + + int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()), + THREAD_TIME_CONSTRAINT_POLICY, + (thread_policy_t)&policy, + THREAD_TIME_CONSTRAINT_POLICY_COUNT); + if (kr != KERN_SUCCESS) { + mach_error("thread_policy_set:", kr); + exit(1); + } #endif try { @@ -138,13 +138,13 @@ int main(int argc, char** argv) { delayFactor = strTo(dfEnv); } - const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); - if (envBenchmarkRuns != NULL) { - benchmarkRuns = strTo(envBenchmarkRuns); - google::SetStderrLogging(3); - } else { - google::LogToStderr(); - } + const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); + if (envBenchmarkRuns != NULL) { + benchmarkRuns = strTo(envBenchmarkRuns); + google::SetStderrLogging(3); + } else { + google::LogToStderr(); + } int option; while ((option = getopt(argc, argv, "fd:b:")) != -1) { @@ -209,58 +209,58 @@ int main(int argc, char** argv) { W3CStatusMonitor* vm = new W3CStatusMonitor(); interpreter.addMonitor(vm); - LOG(INFO) << "Benchmarking " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)); + LOG(INFO) << "Benchmarking " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)); - size_t remainingRuns = benchmarkRuns; - size_t microSteps = 0; + size_t remainingRuns = benchmarkRuns; + size_t microSteps = 0; - Timer tTotal; - tTotal.start(); + Timer tTotal; + tTotal.start(); - double avg = 0; + double avg = 0; #ifdef BUILD_PROFILING - double avgDm = 0; - double avgStep = 0; + double avgDm = 0; + double avgStep = 0; #endif - while(remainingRuns-- > 0) { - Timer t; - microSteps = 0; + while(remainingRuns-- > 0) { + Timer t; + microSteps = 0; - InterpreterState state = interpreter.getState(); + InterpreterState state = interpreter.getState(); - for(;;) { - state = interpreter.step(true); - microSteps++; - if (state == USCXML_INITIALIZED) { - t.start(); - } else if (state == USCXML_FINISHED) { + for(;;) { + state = interpreter.step(true); + microSteps++; + if (state == USCXML_INITIALIZED) { + t.start(); + } else if (state == USCXML_FINISHED) { #ifdef BUILD_PROFILING - avgDm += interpreter._impl->_dataModel.timer.elapsed; - interpreter._impl->_dataModel.timer.reset(); - avgStep += interpreter.timer.elapsed; + avgDm += interpreter._impl->_dataModel.timer.elapsed; + interpreter._impl->_dataModel.timer.reset(); + avgStep += interpreter.timer.elapsed; #endif - } - if (state < 0) - break; - } - assert(retCode == EXIT_SUCCESS); - t.stop(); - avg += t.elapsed; - interpreter.reset(); - std::cout << "." << std::flush; - } - - tTotal.stop(); - - std::cout << benchmarkRuns << " iterations" << std::endl; - std::cout << tTotal.elapsed * 1000.0 << " ms in total" << std::endl; - std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms per execution" << std::endl; - std::cout << microSteps << " microsteps per iteration" << std::endl; - std::cout << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep" << std::endl; + } + if (state < 0) + break; + } + assert(retCode == EXIT_SUCCESS); + t.stop(); + avg += t.elapsed; + interpreter.reset(); + std::cout << "." << std::flush; + } + + tTotal.stop(); + + std::cout << benchmarkRuns << " iterations" << std::endl; + std::cout << tTotal.elapsed * 1000.0 << " ms in total" << std::endl; + std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms per execution" << std::endl; + std::cout << microSteps << " microsteps per iteration" << std::endl; + std::cout << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep" << std::endl; #ifdef BUILD_PROFILING - std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; - std::cout << ((avg - avgDm) * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep \\wo datamodel" << std::endl; + std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; + std::cout << ((avg - avgDm) * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep \\wo datamodel" << std::endl; #endif } } catch(Event e) { -- cgit v0.12