summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/uscxml/Interpreter.cpp88
-rw-r--r--src/uscxml/Interpreter.h8
-rw-r--r--src/uscxml/transform/ChartToC.cpp521
-rw-r--r--src/uscxml/transform/ChartToC.h2
-rw-r--r--test/src/test-c-machine.cpp57
-rw-r--r--test/src/test-c-machine.machine.c395
-rw-r--r--test/src/test-lifecycle.cpp38
-rw-r--r--test/src/test-w3c.cpp142
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<tthread::recursive_mutex> lock(_mutex);
- std::cerr << "Config: {";
- printNodeSet(interpreter.getConfiguration());
- std::cerr << "}" << std::endl;
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
+ std::cerr << "Config: {";
+ printNodeSet(interpreter.getConfiguration());
+ std::cerr << "}" << std::endl;
}
-
+
void StateTransitionMonitor::printNodeSet(const Arabica::XPath::NodeSet<std::string>& 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<tthread::recursive_mutex> 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<std::string, std::pair<InterpreterImpl*, SendRequest> >::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<tthread::recursive_mutex> lock(_mutex);
-
- if (_sendQueue) {
- _sendQueue->stop();
- std::map<std::string, std::pair<InterpreterImpl*, SendRequest> >::iterator sendIter = _sendIds.begin();
- while(sendIter != _sendIds.end()) {
- _sendQueue->cancelEvent(sendIter->first);
- sendIter = _sendIds.erase(sendIter);
- }
- _sendQueue->start();
- }
- std::map<std::string, Invoker>::iterator invokeIter = _invokers.begin();
- while(invokeIter != _invokers.end()) {
- invokeIter->second.uninvoke();
- invokeIter = _invokers.erase(invokeIter);
- }
-
+
+ if (_sendQueue) {
+ _sendQueue->stop();
+ std::map<std::string, std::pair<InterpreterImpl*, SendRequest> >::iterator sendIter = _sendIds.begin();
+ while(sendIter != _sendIds.end()) {
+ _sendQueue->cancelEvent(sendIter->first);
+ _sendIds.erase(sendIter++);
+ }
+ _sendQueue->start();
+ }
+ std::map<std::string, Invoker>::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<std::string>& c
} else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "log")) {
// --- LOG --------------------------
Arabica::DOM::Element<std::string> logElem = (Arabica::DOM::Element<std::string>)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<std::string>& state, bool moreComing);
virtual void beforeEnteringState(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& 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<std::string>& 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<std::string> 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<std::string> 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<std::string> state(_states[i]);
if (i == 0) {
// root state - we need to perform some initialization here
NodeSet<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string>(execContent[j]), 1);
}
stream << " return SCXML_ERR_OK;" << std::endl;
@@ -547,7 +567,7 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Node<s
}
std::string padding;
- for (int i = 0; i < indent; i++) {
+ for (size_t i = 0; i < indent; i++) {
padding += " ";
}
@@ -707,8 +727,9 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Node<s
void ChartToC::writeElementInfo(std::ostream& stream) {
NodeSet<std::string> 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<std::string> 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<std::string>(_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<std::string> data(datas[i]);
if (data.getParentNode() != parent) {
distinctParents++;
@@ -741,8 +762,9 @@ void ChartToC::writeElementInfo(std::ostream& stream) {
parent = Node<std::string>();
- 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<std::string> 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<std::string> parent;
size_t distinctParents = 0;
- for (int i = 0; i < params.size(); i++) {
+ for (size_t i = 0; i < params.size(); i++) {
Element<std::string> param(params[i]);
if (param.getParentNode() != parent) {
distinctParents++;
@@ -788,8 +810,9 @@ void ChartToC::writeElementInfo(std::ostream& stream) {
}
parent = Node<std::string>();
- 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<std::string> param(params[i]);
if (param.getParentNode() != parent) {
Element<std::string>(param.getParentNode()).setAttribute("paramIndex", toStr(i));
@@ -812,44 +835,60 @@ void ChartToC::writeElementInfo(std::ostream& stream) {
NodeSet<std::string> 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<std::string> 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<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", send);
if (contents.size() > 0) {
std::stringstream ss;
NodeList<std::string> 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<std::string> 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<std::string> donedata(donedatas[i]);
- stream << " { ";
-
- // parent
- stream << ATTR_CAST(donedata.getParentNode(), "documentOrder") << ", ";
-
- NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata);
- if (contents.size() > 0) {
- std::stringstream ss;
- NodeList<std::string> 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<std::string> donedata(donedatas[i]);
+ stream << " { ";
+
+ // parent
+ stream << ATTR_CAST(donedata.getParentNode(), "documentOrder") << ", ";
+
+ NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata);
+ if (contents.size() > 0) {
+ std::stringstream ss;
+ NodeList<std::string> 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<std::string> 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<std::string> 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<std::string>(_states[j]))) {
completion.push_back(_states[j]);
@@ -959,7 +1009,7 @@ void ChartToC::writeStates(std::ostream& stream) {
// first child state
Arabica::XPath::NodeSet<std::string> initStates;
NodeList<std::string> 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<std::string>(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 { // <scxml>
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<std::string> elements;
+ elements.insert(_nsInfo.xmlNSPrefix + "transition");
+ NodeSet<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> exitSet = computeExitSet(transition);
for (unsigned int j = 0; j < _states.size(); j++) {
Element<std::string> 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<std::string> ChartToC::inPostFixOrder(const std::set<std::string>& eleme
void ChartToC::inPostFixOrder(const std::set<std::string>& elements, const Element<std::string>& root, NodeSet<std::string>& nodes) {
NodeList<std::string> 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<std::string> 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<std::string> childElem(children.item(i));
@@ -1608,7 +1695,7 @@ void ChartToC::inDocumentOrder(const std::set<std::string>& elements, const Elem
}
NodeList<std::string> 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<std::string> 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<size_t>(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<double>(dfEnv);
}
- const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS");
- if (envBenchmarkRuns != NULL) {
- benchmarkRuns = strTo<size_t>(envBenchmarkRuns);
- google::SetStderrLogging(3);
- } else {
- google::LogToStderr();
- }
+ const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS");
+ if (envBenchmarkRuns != NULL) {
+ benchmarkRuns = strTo<size_t>(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) {