summaryrefslogtreecommitdiffstats
path: root/src/uscxml/transform
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/transform')
-rw-r--r--src/uscxml/transform/ChartToC.cpp3051
-rw-r--r--src/uscxml/transform/ChartToC.h100
-rw-r--r--src/uscxml/transform/ChartToFSM.cpp674
-rw-r--r--src/uscxml/transform/ChartToFSM.h66
-rw-r--r--src/uscxml/transform/ChartToFlatSCXML.cpp134
-rw-r--r--src/uscxml/transform/ChartToFlatSCXML.h10
-rw-r--r--src/uscxml/transform/ChartToMinimalSCXML.cpp48
-rw-r--r--src/uscxml/transform/ChartToMinimalSCXML.h18
-rw-r--r--src/uscxml/transform/ChartToPromela.cpp976
-rw-r--r--src/uscxml/transform/ChartToPromela.h126
-rw-r--r--src/uscxml/transform/ChartToTex.cpp65
-rw-r--r--src/uscxml/transform/ChartToTex.h10
-rw-r--r--src/uscxml/transform/FlatStateIdentifier.h4
-rw-r--r--src/uscxml/transform/Transformer.h14
14 files changed, 2655 insertions, 2641 deletions
diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp
index 3944b92..2d3f6ba 100644
--- a/src/uscxml/transform/ChartToC.cpp
+++ b/src/uscxml/transform/ChartToC.cpp
@@ -35,1592 +35,1593 @@ namespace uscxml {
using namespace Arabica::DOM;
using namespace Arabica::XPath;
-
+
Transformer ChartToC::transform(const Interpreter& other) {
- ChartToC* c2c = new ChartToC(other);
-
- return boost::shared_ptr<TransformerImpl>(c2c);
+ ChartToC* c2c = new ChartToC(other);
+
+ return boost::shared_ptr<TransformerImpl>(c2c);
}
ChartToC::ChartToC(const Interpreter& other) : TransformerImpl() {
- cloneFrom(other.getImpl());
+ cloneFrom(other.getImpl());
}
void ChartToC::writeTo(std::ostream& stream) {
- _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY);
- _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : "");
-
- std::set<std::string> elements;
- elements.insert(_nsInfo.xmlNSPrefix + "scxml");
- elements.insert(_nsInfo.xmlNSPrefix + "state");
- elements.insert(_nsInfo.xmlNSPrefix + "final");
- elements.insert(_nsInfo.xmlNSPrefix + "parallel");
- elements.insert(_nsInfo.xmlNSPrefix + "history");
- elements.insert(_nsInfo.xmlNSPrefix + "initial");
- elements.insert(_nsInfo.xmlNSPrefix + "parallel");
- _states = inDocumentOrder(elements, _scxml);
-
- for (int i = 0; i < _states.size(); i++) {
- Element<std::string> state(_states[i]);
- state.setAttribute("documentOrder", toStr(i));
- if (HAS_ATTR(state, "id")) {
- _stateNames[ATTR(state, "id")] = state;
- }
- }
-
- elements.clear();
- elements.insert(_nsInfo.xmlNSPrefix + "transition");
- _transitions = inPostFixOrder(elements, _scxml);
-
- for (int i = 0; i < _transitions.size(); i++) {
- Element<std::string> transition(_transitions[i]);
- transition.setAttribute("postFixOrder", toStr(i));
- }
-
- // how many bits do we need to represent the state array?
- std::string seperator;
- _stateCharArraySize = ceil((float)_states.size() / (float)8);
- _stateCharArrayInit = "{";
- for (int i = 0; i < _stateCharArraySize; i++) {
- _stateCharArrayInit += seperator + "0";
- seperator = ", ";
- }
- _stateCharArrayInit += "}";
-
- seperator = "";
- _transCharArraySize = ceil((float)_transitions.size() / (float)8);
- _transCharArrayInit = "{";
- for (int i = 0; i < _transCharArraySize; i++) {
- _transCharArrayInit += seperator + "0";
- seperator = ", ";
- }
- _transCharArrayInit += "}";
-
- writeIncludes(stream);
- writeMacros(stream);
- writeTypes(stream);
- writeElementInfo(stream);
- writeExecContent(stream);
- writeStates(stream);
- writeTransitions(stream);
- writeHelpers(stream);
- writeFSM(stream);
-
- // http://stackoverflow.com/questions/2525310/how-to-define-and-work-with-an-array-of-bits-in-c
-
+ _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY);
+ _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : "");
+
+ std::set<std::string> elements;
+ elements.insert(_nsInfo.xmlNSPrefix + "scxml");
+ elements.insert(_nsInfo.xmlNSPrefix + "state");
+ elements.insert(_nsInfo.xmlNSPrefix + "final");
+ elements.insert(_nsInfo.xmlNSPrefix + "parallel");
+ elements.insert(_nsInfo.xmlNSPrefix + "history");
+ elements.insert(_nsInfo.xmlNSPrefix + "initial");
+ elements.insert(_nsInfo.xmlNSPrefix + "parallel");
+ _states = inDocumentOrder(elements, _scxml);
+
+ for (int i = 0; i < _states.size(); i++) {
+ Element<std::string> state(_states[i]);
+ state.setAttribute("documentOrder", toStr(i));
+ if (HAS_ATTR(state, "id")) {
+ _stateNames[ATTR(state, "id")] = state;
+ }
+ }
+
+ elements.clear();
+ elements.insert(_nsInfo.xmlNSPrefix + "transition");
+ _transitions = inPostFixOrder(elements, _scxml);
+
+ for (int i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ transition.setAttribute("postFixOrder", toStr(i));
+ }
+
+ // how many bits do we need to represent the state array?
+ std::string seperator;
+ _stateCharArraySize = ceil((float)_states.size() / (float)8);
+ _stateCharArrayInit = "{";
+ for (int i = 0; i < _stateCharArraySize; i++) {
+ _stateCharArrayInit += seperator + "0";
+ seperator = ", ";
+ }
+ _stateCharArrayInit += "}";
+
+ seperator = "";
+ _transCharArraySize = ceil((float)_transitions.size() / (float)8);
+ _transCharArrayInit = "{";
+ for (int i = 0; i < _transCharArraySize; i++) {
+ _transCharArrayInit += seperator + "0";
+ seperator = ", ";
+ }
+ _transCharArrayInit += "}";
+
+ writeIncludes(stream);
+ writeMacros(stream);
+ writeTypes(stream);
+ writeElementInfo(stream);
+ writeExecContent(stream);
+ writeStates(stream);
+ writeTransitions(stream);
+ writeHelpers(stream);
+ writeFSM(stream);
+
+ // http://stackoverflow.com/questions/2525310/how-to-define-and-work-with-an-array-of-bits-in-c
+
}
void ChartToC::writeIncludes(std::ostream& stream) {
- stream << "#include <stdint.h> // explicit types" << std::endl;
- stream << "#include <stddef.h> // NULL" << std::endl;
- stream << std::endl;
+ stream << "#include <stdint.h> // explicit types" << std::endl;
+ stream << "#include <stddef.h> // NULL" << std::endl;
+ stream << std::endl;
}
void ChartToC::writeMacros(std::ostream& stream) {
- stream << "#define IS_SET(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl;
- stream << "#define SET_BIT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl;
- stream << "#define CLEARBIT(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl;
- stream << std::endl;
-
- stream << "#ifdef __GNUC__" << std::endl;
- stream << "#define likely(x) __builtin_expect(!!(x), 1)" << std::endl;
- stream << "#define unlikely(x) __builtin_expect(!!(x), 0)" << std::endl;
- stream << "#else" << std::endl;
- stream << "#define likely(x) (x)" << std::endl;
- stream << "#define unlikely(x) (x)" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << "// error return codes" << std::endl;
- stream << "#define SCXML_ERR_OK 0" << std::endl;
- stream << "#define SCXML_ERR_IDLE 1" << std::endl;
- stream << "#define SCXML_ERR_DONE 2" << std::endl;
- stream << "#define SCXML_ERR_MISSING_CALLBACK 3" << std::endl;
- stream << "#define SCXML_ERR_FOREACH_DONE 4" << std::endl;
- stream << "#define SCXML_ERR_EXEC_CONTENT 5" << std::endl;
- stream << "#define SCXML_ERR_INVALID_TARGET 6" << std::endl;
- stream << "#define SCXML_ERR_INVALID_TYPE 7" << std::endl;
- stream << "#define SCXML_ERR_UNSUPPORTED 8" << std::endl;
- stream << std::endl;
-
- stream << "#define SCXML_MACHINE_NAME \"" << _name << "\"" << std::endl;
- stream << "#define SCXML_NUMBER_STATES " << _states.size() << std::endl;
- stream << "#define SCXML_NUMBER_TRANSITIONS " << _transitions.size() << std::endl;
- stream << std::endl;
-
- 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 << std::endl;
-
- stream << "#define SCXML_STATE_ATOMIC 0x01" << std::endl;
- stream << "#define SCXML_STATE_PARALLEL 0x02" << std::endl;
- stream << "#define SCXML_STATE_COMPOUND 0x03" << std::endl;
- stream << "#define SCXML_STATE_FINAL 0x04" << std::endl;
- stream << "#define SCXML_STATE_HISTORY_DEEP 0x05" << std::endl;
- stream << "#define SCXML_STATE_HISTORY_SHALLOW 0x06" << std::endl;
- stream << "#define SCXML_STATE_INITIAL 0x07" << std::endl;
-
- stream << "" << std::endl;
- stream << "#define SCXML_CTX_PRISTINE 0x00" << std::endl;
- stream << "#define SCXML_CTX_SPONTANEOUS 0x01" << std::endl;
- stream << "#define SCXML_CTX_INITIALIZED 0x02" << std::endl;
- stream << "#define SCXML_CTX_TOP_LEVEL_FINAL 0x04" << std::endl;
- stream << "#define SCXML_CTX_TRANSITION_FOUND 0x08" << std::endl;
- stream << std::endl;
-
- stream << "#define ELEM_DATA_IS_SET(data) (data->id != NULL)" << std::endl;
- stream << "#define ELEM_DONEDATA_IS_SET(donedata) (donedata->content != NULL || donedata->contentexpr != NULL || donedata->params != NULL)" << std::endl;
- stream << "#define ELEM_PARAM_IS_SET(param) (param->name != NULL)" << std::endl;
- stream << std::endl;
+ stream << "#define IS_SET(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl;
+ stream << "#define SET_BIT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl;
+ stream << "#define CLEARBIT(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl;
+ stream << std::endl;
+
+ stream << "#ifdef __GNUC__" << std::endl;
+ stream << "#define likely(x) __builtin_expect(!!(x), 1)" << std::endl;
+ stream << "#define unlikely(x) __builtin_expect(!!(x), 0)" << std::endl;
+ stream << "#else" << std::endl;
+ stream << "#define likely(x) (x)" << std::endl;
+ stream << "#define unlikely(x) (x)" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << "// error return codes" << std::endl;
+ stream << "#define SCXML_ERR_OK 0" << std::endl;
+ stream << "#define SCXML_ERR_IDLE 1" << std::endl;
+ stream << "#define SCXML_ERR_DONE 2" << std::endl;
+ stream << "#define SCXML_ERR_MISSING_CALLBACK 3" << std::endl;
+ stream << "#define SCXML_ERR_FOREACH_DONE 4" << std::endl;
+ stream << "#define SCXML_ERR_EXEC_CONTENT 5" << std::endl;
+ stream << "#define SCXML_ERR_INVALID_TARGET 6" << std::endl;
+ stream << "#define SCXML_ERR_INVALID_TYPE 7" << std::endl;
+ stream << "#define SCXML_ERR_UNSUPPORTED 8" << std::endl;
+ stream << std::endl;
+
+ stream << "#define SCXML_MACHINE_NAME \"" << _name << "\"" << std::endl;
+ stream << "#define SCXML_NUMBER_STATES " << _states.size() << std::endl;
+ stream << "#define SCXML_NUMBER_TRANSITIONS " << _transitions.size() << std::endl;
+ stream << std::endl;
+
+ 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 << std::endl;
+
+ stream << "#define SCXML_STATE_ATOMIC 0x01" << std::endl;
+ stream << "#define SCXML_STATE_PARALLEL 0x02" << std::endl;
+ stream << "#define SCXML_STATE_COMPOUND 0x03" << std::endl;
+ stream << "#define SCXML_STATE_FINAL 0x04" << std::endl;
+ stream << "#define SCXML_STATE_HISTORY_DEEP 0x05" << std::endl;
+ stream << "#define SCXML_STATE_HISTORY_SHALLOW 0x06" << std::endl;
+ stream << "#define SCXML_STATE_INITIAL 0x07" << std::endl;
+
+ stream << "" << std::endl;
+ stream << "#define SCXML_CTX_PRISTINE 0x00" << std::endl;
+ stream << "#define SCXML_CTX_SPONTANEOUS 0x01" << std::endl;
+ stream << "#define SCXML_CTX_INITIALIZED 0x02" << std::endl;
+ stream << "#define SCXML_CTX_TOP_LEVEL_FINAL 0x04" << std::endl;
+ stream << "#define SCXML_CTX_TRANSITION_FOUND 0x08" << std::endl;
+ stream << std::endl;
+
+ stream << "#define ELEM_DATA_IS_SET(data) (data->id != NULL)" << std::endl;
+ stream << "#define ELEM_DONEDATA_IS_SET(donedata) (donedata->content != NULL || donedata->contentexpr != NULL || donedata->params != NULL)" << std::endl;
+ stream << "#define ELEM_PARAM_IS_SET(param) (param->name != NULL)" << std::endl;
+ stream << std::endl;
}
void ChartToC::writeTypes(std::ostream& stream) {
-
- stream << std::endl;
- stream << "typedef struct scxml_transition scxml_transition;" << std::endl;
- stream << "typedef struct scxml_state scxml_state;" << std::endl;
- stream << "typedef struct scxml_ctx scxml_ctx;" << std::endl;
- stream << "typedef struct scxml_invoke scxml_invoke;" << std::endl;
-
- stream << std::endl;
-
- stream << "typedef struct scxml_elem_send scxml_elem_send;" << std::endl;
- stream << "typedef struct scxml_elem_param scxml_elem_param;" << std::endl;
- stream << "typedef struct scxml_elem_data scxml_elem_data;" << std::endl;
- stream << "typedef struct scxml_elem_donedata scxml_elem_donedata;" << std::endl;
- stream << "typedef struct scxml_elem_foreach scxml_elem_foreach;" << std::endl;
- stream << std::endl;
-
- stream << "typedef void* (*dequeue_internal_cb_t)(const scxml_ctx* ctx);" << std::endl;
- stream << "typedef void* (*dequeue_external_cb_t)(const scxml_ctx* ctx);" << std::endl;
- stream << "typedef int (*is_enabled_cb_t)(const scxml_ctx* ctx, const scxml_transition* transition, const void* event);" << std::endl;
- stream << "typedef int (*is_true_cb_t)(const scxml_ctx* ctx, const char* expr);" << std::endl;
- stream << "typedef int (*exec_content_t)(const scxml_ctx* ctx, const scxml_state* state, const void* event);" << std::endl;
- stream << "typedef int (*raise_done_event_t)(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata);" << std::endl;
- stream << "typedef int (*invoke_t)(const scxml_ctx* ctx, const scxml_state* s, const scxml_invoke* x);" << std::endl;
- stream << std::endl;
-
- stream << "typedef int (*exec_content_log_t)(const scxml_ctx* ctx, const char* label, const char* expr);" << std::endl;
- stream << "typedef int (*exec_content_raise_t)(const scxml_ctx* ctx, const char* event);" << std::endl;
- stream << "typedef int (*exec_content_send_t)(const scxml_ctx* ctx, const scxml_elem_send* send);" << std::endl;
- stream << "typedef int (*exec_content_foreach_init_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl;
- stream << "typedef int (*exec_content_foreach_next_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl;
- stream << "typedef int (*exec_content_foreach_done_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl;
- stream << "typedef int (*exec_content_assign_t)(const scxml_ctx* ctx, const char* location, const char* expr);" << std::endl;
- stream << "typedef int (*exec_content_init_t)(const scxml_ctx* ctx, const scxml_elem_data* data);" << std::endl;
- stream << "typedef int (*exec_content_cancel_t)(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr);" << std::endl;
- stream << "typedef int (*exec_content_finalize_t)(const scxml_ctx* ctx, const scxml_invoke* invoker, const void* event);" << std::endl;
- stream << "typedef int (*exec_content_script_t)(const scxml_ctx* ctx, const char* src, const char* content);" << std::endl;
- stream << std::endl;
-
- stream << "struct scxml_elem_data {" << std::endl;
- stream << " const char* id;" << std::endl;
- stream << " const char* src;" << std::endl;
- stream << " const char* expr;" << std::endl;
- stream << " const char* content;" << std::endl;
- stream << "};" << std::endl;
- stream << std::endl;
-
- stream << "struct scxml_state {" << std::endl;
- stream << " const char* name; // eventual name" << std::endl;
- stream << " uint16_t source; // 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 scxml_elem_data* data;" << std::endl;
- stream << " 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 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 << "};" << std::endl;
- stream << std::endl;
-
- stream << "struct scxml_elem_foreach {" << std::endl;
- stream << " const char* array;" << std::endl;
- stream << " const char* item;" << std::endl;
- stream << " const char* index;" << std::endl;
- stream << "};" << std::endl;
- stream << std::endl;
-
- stream << "struct scxml_elem_param {" << std::endl;
- stream << " const char* name;" << std::endl;
- stream << " const char* expr;" << std::endl;
- stream << " const char* location;" << std::endl;
- stream << "};" << std::endl;
- stream << std::endl;
-
- stream << "struct scxml_elem_donedata {" << std::endl;
- stream << " uint16_t source;" << std::endl;
- stream << " const char* content;" << std::endl;
- stream << " const char* contentexpr;" << std::endl;
- stream << " const scxml_elem_param* params;" << std::endl;
- stream << "};" << std::endl;
- stream << std::endl;
-
- stream << "struct scxml_elem_invoke {" << std::endl;
- stream << " const char* type;" << std::endl;
- stream << " const char* typeexpr;" << std::endl;
- stream << " const char* src;" << std::endl;
- stream << " const char* srcexpr;" << std::endl;
- 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 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;
-
- stream << "struct scxml_elem_send {" << std::endl;
- stream << " const char* event;" << std::endl;
- stream << " const char* eventexpr;" << std::endl;
- stream << " const char* target;" << std::endl;
- stream << " const char* targetexpr;" << std::endl;
- stream << " const char* type;" << std::endl;
- stream << " const char* typeexpr;" << std::endl;
- stream << " const char* id;" << std::endl;
- stream << " const char* idlocation;" << std::endl;
- stream << " const char* delay;" << std::endl;
- stream << " const char* delayexpr;" << std::endl;
- stream << " const char* namelist;" << std::endl;
- 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;
-
- stream << "struct scxml_ctx {" << std::endl;
- stream << " uint8_t flags;" << std::endl;
- stream << std::endl;
- stream << " char config[" << _stateCharArraySize << "];" << std::endl;
- stream << " char history[" << _stateCharArraySize << "];" << std::endl;
- stream << " char pending_invokes[" << _stateCharArraySize << "];" << std::endl;
- stream << " char initialized_data[" << _stateCharArraySize << "];" << std::endl;
- stream << std::endl;
- stream << " void* user_data;" << std::endl;
- stream << std::endl;
- stream << " dequeue_internal_cb_t dequeue_internal;" << std::endl;
- stream << " dequeue_external_cb_t dequeue_external;" << std::endl;
- stream << " is_enabled_cb_t is_enabled;" << std::endl;
- stream << " is_true_cb_t is_true;" << std::endl;
- stream << " raise_done_event_t raise_done_event;" << std::endl;
- stream << std::endl;
- stream << " exec_content_log_t exec_content_log;" << std::endl;
- stream << " exec_content_raise_t exec_content_raise;" << std::endl;
- stream << " exec_content_send_t exec_content_send;" << std::endl;
- stream << " exec_content_foreach_init_t exec_content_foreach_init;" << std::endl;
- stream << " exec_content_foreach_next_t exec_content_foreach_next;" << std::endl;
- stream << " exec_content_foreach_done_t exec_content_foreach_done;" << std::endl;
- stream << " exec_content_assign_t exec_content_assign;" << std::endl;
- stream << " exec_content_init_t exec_content_init;" << std::endl;
- stream << " exec_content_cancel_t exec_content_cancel;" << std::endl;
- stream << " exec_content_script_t exec_content_script;" << std::endl;
- stream << " invoke_t invoke;" << std::endl;
- stream << "};" << std::endl;
- stream << std::endl;
+
+ stream << std::endl;
+ stream << "typedef struct scxml_transition scxml_transition;" << std::endl;
+ stream << "typedef struct scxml_state scxml_state;" << std::endl;
+ stream << "typedef struct scxml_ctx scxml_ctx;" << std::endl;
+ stream << "typedef struct scxml_invoke scxml_invoke;" << std::endl;
+
+ stream << std::endl;
+
+ stream << "typedef struct scxml_elem_send scxml_elem_send;" << std::endl;
+ stream << "typedef struct scxml_elem_param scxml_elem_param;" << std::endl;
+ stream << "typedef struct scxml_elem_data scxml_elem_data;" << std::endl;
+ stream << "typedef struct scxml_elem_donedata scxml_elem_donedata;" << std::endl;
+ stream << "typedef struct scxml_elem_foreach scxml_elem_foreach;" << std::endl;
+ stream << std::endl;
+
+ stream << "typedef void* (*dequeue_internal_cb_t)(const scxml_ctx* ctx);" << std::endl;
+ stream << "typedef void* (*dequeue_external_cb_t)(const scxml_ctx* ctx);" << std::endl;
+ stream << "typedef int (*is_enabled_cb_t)(const scxml_ctx* ctx, const scxml_transition* transition, const void* event);" << std::endl;
+ stream << "typedef int (*is_true_cb_t)(const scxml_ctx* ctx, const char* expr);" << std::endl;
+ stream << "typedef int (*exec_content_t)(const scxml_ctx* ctx, const scxml_state* state, const void* event);" << std::endl;
+ stream << "typedef int (*raise_done_event_t)(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata);" << std::endl;
+ stream << "typedef int (*invoke_t)(const scxml_ctx* ctx, const scxml_state* s, const scxml_invoke* x);" << std::endl;
+ stream << std::endl;
+
+ stream << "typedef int (*exec_content_log_t)(const scxml_ctx* ctx, const char* label, const char* expr);" << std::endl;
+ stream << "typedef int (*exec_content_raise_t)(const scxml_ctx* ctx, const char* event);" << std::endl;
+ stream << "typedef int (*exec_content_send_t)(const scxml_ctx* ctx, const scxml_elem_send* send);" << std::endl;
+ stream << "typedef int (*exec_content_foreach_init_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl;
+ stream << "typedef int (*exec_content_foreach_next_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl;
+ stream << "typedef int (*exec_content_foreach_done_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl;
+ stream << "typedef int (*exec_content_assign_t)(const scxml_ctx* ctx, const char* location, const char* expr);" << std::endl;
+ stream << "typedef int (*exec_content_init_t)(const scxml_ctx* ctx, const scxml_elem_data* data);" << std::endl;
+ stream << "typedef int (*exec_content_cancel_t)(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr);" << std::endl;
+ stream << "typedef int (*exec_content_finalize_t)(const scxml_ctx* ctx, const scxml_invoke* invoker, const void* event);" << std::endl;
+ stream << "typedef int (*exec_content_script_t)(const scxml_ctx* ctx, const char* src, const char* content);" << std::endl;
+ stream << std::endl;
+
+ stream << "struct scxml_elem_data {" << std::endl;
+ stream << " const char* id;" << std::endl;
+ stream << " const char* src;" << std::endl;
+ stream << " const char* expr;" << std::endl;
+ stream << " const char* content;" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
+
+ stream << "struct scxml_state {" << std::endl;
+ stream << " const char* name; // eventual name" << std::endl;
+ stream << " uint16_t source; // 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 scxml_elem_data* data;" << std::endl;
+ stream << " 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 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 << "};" << std::endl;
+ stream << std::endl;
+
+ stream << "struct scxml_elem_foreach {" << std::endl;
+ stream << " const char* array;" << std::endl;
+ stream << " const char* item;" << std::endl;
+ stream << " const char* index;" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
+
+ stream << "struct scxml_elem_param {" << std::endl;
+ stream << " const char* name;" << std::endl;
+ stream << " const char* expr;" << std::endl;
+ stream << " const char* location;" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
+
+ stream << "struct scxml_elem_donedata {" << std::endl;
+ stream << " uint16_t source;" << std::endl;
+ stream << " const char* content;" << std::endl;
+ stream << " const char* contentexpr;" << std::endl;
+ stream << " const scxml_elem_param* params;" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
+
+ stream << "struct scxml_elem_invoke {" << std::endl;
+ stream << " const char* type;" << std::endl;
+ stream << " const char* typeexpr;" << std::endl;
+ stream << " const char* src;" << std::endl;
+ stream << " const char* srcexpr;" << std::endl;
+ 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 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;
+
+ stream << "struct scxml_elem_send {" << std::endl;
+ stream << " const char* event;" << std::endl;
+ stream << " const char* eventexpr;" << std::endl;
+ stream << " const char* target;" << std::endl;
+ stream << " const char* targetexpr;" << std::endl;
+ stream << " const char* type;" << std::endl;
+ stream << " const char* typeexpr;" << std::endl;
+ stream << " const char* id;" << std::endl;
+ stream << " const char* idlocation;" << std::endl;
+ stream << " const char* delay;" << std::endl;
+ stream << " const char* delayexpr;" << std::endl;
+ stream << " const char* namelist;" << std::endl;
+ 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;
+
+ stream << "struct scxml_ctx {" << std::endl;
+ stream << " uint8_t flags;" << std::endl;
+ stream << std::endl;
+ stream << " char config[" << _stateCharArraySize << "];" << std::endl;
+ stream << " char history[" << _stateCharArraySize << "];" << std::endl;
+ stream << " char pending_invokes[" << _stateCharArraySize << "];" << std::endl;
+ stream << " char initialized_data[" << _stateCharArraySize << "];" << std::endl;
+ stream << std::endl;
+ stream << " void* user_data;" << std::endl;
+ stream << std::endl;
+ stream << " dequeue_internal_cb_t dequeue_internal;" << std::endl;
+ stream << " dequeue_external_cb_t dequeue_external;" << std::endl;
+ stream << " is_enabled_cb_t is_enabled;" << std::endl;
+ stream << " is_true_cb_t is_true;" << std::endl;
+ stream << " raise_done_event_t raise_done_event;" << std::endl;
+ stream << std::endl;
+ stream << " exec_content_log_t exec_content_log;" << std::endl;
+ stream << " exec_content_raise_t exec_content_raise;" << std::endl;
+ stream << " exec_content_send_t exec_content_send;" << std::endl;
+ stream << " exec_content_foreach_init_t exec_content_foreach_init;" << std::endl;
+ stream << " exec_content_foreach_next_t exec_content_foreach_next;" << std::endl;
+ stream << " exec_content_foreach_done_t exec_content_foreach_done;" << std::endl;
+ stream << " exec_content_assign_t exec_content_assign;" << std::endl;
+ stream << " exec_content_init_t exec_content_init;" << std::endl;
+ stream << " exec_content_cancel_t exec_content_cancel;" << std::endl;
+ stream << " exec_content_script_t exec_content_script;" << std::endl;
+ stream << " invoke_t invoke;" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
}
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 << " 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;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " printf(\"\\n\");" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
-
- 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 << " if (IS_SET(i, a)) {" << std::endl;
- stream << " printf(\"%s%d\", seperator, i);" << std::endl;
- stream << " seperator = \", \";" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " printf(\"\\n\");" << std::endl;
- stream << "}" << std::endl;
-
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << "static void bit_or(char* dest, const char* mask, size_t i) {" << std::endl;
- stream << " do {" << std::endl;
- stream << " dest[i - 1] |= mask[i - 1];" << std::endl;
- stream << " } while(--i);" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
-
- stream << "static void bit_copy(char* dest, const char* source, size_t i) {" << std::endl;
- stream << " do {" << std::endl;
- stream << " dest[i - 1] = source[i - 1];" << std::endl;
- stream << " } while(--i);" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
-
- stream << "static int bit_has_and(const char* a, const char* b, size_t i) {" << std::endl;
- stream << " do {" << std::endl;
- stream << " if (a[i - 1] & b[i - 1])" << std::endl;
- stream << " return true;" << std::endl;
- stream << " } while(--i);" << std::endl;
- stream << " return false;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
-
- stream << "static void bit_and_not(char* dest, const char* mask, size_t i) {" << std::endl;
- stream << " do {" << std::endl;
- stream << " dest[i - 1] &= ~mask[i - 1];" << std::endl;
- stream << " } while(--i);" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
-
- stream << "static void bit_and(char* dest, const char* mask, size_t i) {" << std::endl;
- stream << " do {" << std::endl;
- stream << " dest[i - 1] &= mask[i - 1];" << std::endl;
- stream << " } while(--i);" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
-
- stream << "static int bit_any_set(const char* a, size_t i) {" << std::endl;
- stream << " do {" << std::endl;
- stream << " if (a[i - 1] > 0)" << std::endl;
- stream << " return true;" << std::endl;
- stream << " } while(--i);" << std::endl;
- stream << " return false;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
+ stream << "#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 << " 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;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " printf(\"\\n\");" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+ 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 << " if (IS_SET(i, a)) {" << std::endl;
+ stream << " printf(\"%s%d\", seperator, i);" << std::endl;
+ stream << " seperator = \", \";" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " printf(\"\\n\");" << std::endl;
+ stream << "}" << std::endl;
+
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << "static void bit_or(char* dest, const char* mask, size_t i) {" << std::endl;
+ stream << " do {" << std::endl;
+ stream << " dest[i - 1] |= mask[i - 1];" << std::endl;
+ stream << " } while(--i);" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+ stream << "static void bit_copy(char* dest, const char* source, size_t i) {" << std::endl;
+ stream << " do {" << std::endl;
+ stream << " dest[i - 1] = source[i - 1];" << std::endl;
+ stream << " } while(--i);" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+ stream << "static int bit_has_and(const char* a, const char* b, size_t i) {" << std::endl;
+ stream << " do {" << std::endl;
+ stream << " if (a[i - 1] & b[i - 1])" << std::endl;
+ stream << " return true;" << std::endl;
+ stream << " } while(--i);" << std::endl;
+ stream << " return false;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+ stream << "static void bit_and_not(char* dest, const char* mask, size_t i) {" << std::endl;
+ stream << " do {" << std::endl;
+ stream << " dest[i - 1] &= ~mask[i - 1];" << std::endl;
+ stream << " } while(--i);" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+ stream << "static void bit_and(char* dest, const char* mask, size_t i) {" << std::endl;
+ stream << " do {" << std::endl;
+ stream << " dest[i - 1] &= mask[i - 1];" << std::endl;
+ stream << " } while(--i);" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+ stream << "static int bit_any_set(const char* a, size_t i) {" << std::endl;
+ stream << " do {" << std::endl;
+ stream << " if (a[i - 1] > 0)" << std::endl;
+ stream << " return true;" << std::endl;
+ stream << " } while(--i);" << std::endl;
+ stream << " return false;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
}
-
+
void ChartToC::writeExecContent(std::ostream& stream) {
- for (int 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);
- if (globalScripts.size() > 0) {
- _hasGlobalScripts = true;
- 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;
- } else {
- _hasGlobalScripts = false;
- }
- }
-
- NodeSet<std::string> onexit = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state);
- for (int 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);
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
- }
-
- 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++) {
- stream << " " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(ctx, state, event);" << std::endl;
- }
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
- }
-
-
- NodeSet<std::string> onentry = filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state);
- for (int 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);
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
- }
-
- bool hasInitialState = false;
- NodeSet<std::string> initial = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state);
- if (initial.size() > 0) {
- NodeSet<std::string> initialTransition = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial);
- if (initialTransition.size() > 0) {
- hasInitialState = true;
- stream << "static int " << DOMUtils::idForNode(state) << "_initial" << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl;
- stream << " int err = SCXML_ERR_OK;" << std::endl;
- writeExecContent(stream, initialTransition[0], 1);
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
- }
- }
-
-
- 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++) {
- stream << " " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(ctx, state, event);" << std::endl;
- }
- if (hasInitialState) {
- stream << " " << DOMUtils::idForNode(state) << "_initial" << "(ctx, state, event);" << std::endl;
- }
-
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
- }
-
-
- 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++) {
- stream << " ctx->invoke(ctx, s, x);" << std::endl;
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << std::endl;
- }
- stream << "}" << std::endl;
- }
- }
-
- for (int i = 0; i < _transitions.size(); i++) {
- Element<std::string> transition(_transitions[i]);
- if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial"))
- continue;
-
- NodeSet<std::string> execContent = filterChildType(Node_base::ELEMENT_NODE, transition);
-
- 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++) {
- writeExecContent(stream, Element<std::string>(execContent[j]), 1);
- }
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
- }
- }
+ for (int 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);
+ if (globalScripts.size() > 0) {
+ _hasGlobalScripts = true;
+ 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;
+ } else {
+ _hasGlobalScripts = false;
+ }
+ }
+
+ NodeSet<std::string> onexit = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state);
+ for (int 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);
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+ }
+
+ 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++) {
+ stream << " " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(ctx, state, event);" << std::endl;
+ }
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+ }
+
+
+ NodeSet<std::string> onentry = filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state);
+ for (int 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);
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+ }
+
+ bool hasInitialState = false;
+ NodeSet<std::string> initial = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state);
+ if (initial.size() > 0) {
+ NodeSet<std::string> initialTransition = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial);
+ if (initialTransition.size() > 0) {
+ hasInitialState = true;
+ stream << "static int " << DOMUtils::idForNode(state) << "_initial" << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl;
+ stream << " int err = SCXML_ERR_OK;" << std::endl;
+ writeExecContent(stream, initialTransition[0], 1);
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+ }
+ }
+
+
+ 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++) {
+ stream << " " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(ctx, state, event);" << std::endl;
+ }
+ if (hasInitialState) {
+ stream << " " << DOMUtils::idForNode(state) << "_initial" << "(ctx, state, event);" << std::endl;
+ }
+
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+ }
+
+
+ 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++) {
+ stream << " ctx->invoke(ctx, s, x);" << std::endl;
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << std::endl;
+ }
+ stream << "}" << std::endl;
+ }
+ }
+
+ for (int i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial"))
+ continue;
+
+ NodeSet<std::string> execContent = filterChildType(Node_base::ELEMENT_NODE, transition);
+
+ 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++) {
+ writeExecContent(stream, Element<std::string>(execContent[j]), 1);
+ }
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
+ }
+ }
}
void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent) {
- if (!node)
- return;
-
- if (node.getNodeType() == Node_base::TEXT_NODE) {
- if (boost::trim_copy(node.getNodeValue()).length() > 0) {
- std::string escaped = escape(node.getNodeValue());
- stream << escaped;
- }
- return;
- }
-
- std::string padding;
- for (int i = 0; i < indent; i++) {
- padding += " ";
- }
-
-
- if (node.getNodeType() != Node_base::ELEMENT_NODE)
- return; // skip anything not an element
-
- Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(node);
-
- if (false) {
- } else if(TAGNAME(elem) == "onentry" || TAGNAME(elem) == "onexit" || TAGNAME(elem) == "transition" || TAGNAME(elem) == "finalize") {
- // descent into childs and write their contents
- Arabica::DOM::Node<std::string> child = node.getFirstChild();
- while(child) {
- writeExecContent(stream, child, indent);
- child = child.getNextSibling();
- }
- } else if(TAGNAME(elem) == "script") {
- stream << padding;
- stream << "if likely(ctx->exec_content_script != NULL) {" << std::endl;
- stream << padding;
- stream << " if unlikely((err = ctx->exec_content_script(ctx, ";
- stream << (HAS_ATTR(elem, "src") ? "\"" + escape(ATTR(elem, "src")) + "\"" : "NULL") << ", ";
-
- NodeSet<std::string> scriptTexts = filterChildType(Node_base::TEXT_NODE, elem);
- if (scriptTexts.size() > 0) {
- stream << "\"";
- writeExecContent(stream, scriptTexts[0], 0);
- stream << "\"";
- } else {
- stream << "NULL";
- }
-
- stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
- } else if(TAGNAME(elem) == "log") {
- stream << padding;
- stream << "if likely(ctx->exec_content_log != NULL) {" << std::endl;
- stream << padding;
- stream << " if unlikely((ctx->exec_content_log(ctx, ";
- stream << (HAS_ATTR(elem, "label") ? "\"" + escape(ATTR(elem, "label")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(elem, "expr") ? "\"" + escape(ATTR(elem, "expr")) + "\"" : "NULL");
- stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
- } else if(TAGNAME(elem) == "foreach") {
- stream << padding << "if likely(ctx->exec_content_foreach_init != NULL &&" << std::endl;
- stream << padding << " ctx->exec_content_foreach_next != NULL &&" << std::endl;
- stream << padding << " ctx->exec_content_foreach_done != NULL) {" << std::endl;
- stream << std::endl;
-
- stream << padding << " if unlikely((ctx->exec_content_foreach_init(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << " while (ctx->exec_content_foreach_next(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "]) == SCXML_ERR_OK) {" << std::endl;
- Arabica::DOM::Node<std::string> child = node.getFirstChild();
- while(child) {
- writeExecContent(stream, child, indent + 2);
- child = child.getNextSibling();
- }
- stream << padding << " }" << std::endl;
- stream << padding << " if ((ctx->exec_content_foreach_done(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
- } else if(TAGNAME(elem) == "if") {
- stream << padding;
- stream << "if likely(ctx->is_true != NULL) {" << std::endl;
- stream << padding;
- stream << " if (ctx->is_true(ctx, " << (HAS_ATTR(elem, "cond") ? "\"" + escape(ATTR(elem, "cond")) + "\"" : "NULL") << ")) {" << std::endl;
- Arabica::DOM::Node<std::string> child = elem.getFirstChild();
- while(child) {
- if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "elseif") {
- stream << padding;
- stream << " } else if (ctx->is_true(ctx, " << (HAS_ATTR_CAST(child, "cond") ? "\"" + escape(ATTR_CAST(child, "cond")) + "\"" : "NULL") << ")) {" << std::endl;
- } else if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "else") {
- stream << padding;
- stream << " } else {" << std::endl;
- } else {
- writeExecContent(stream, child, indent + 2);
- }
- child = child.getNextSibling();
- }
- stream << padding << " }" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
- } else if(TAGNAME(elem) == "assign") {
- stream << padding;
- stream << "if likely(ctx->exec_content_assign != NULL) {" << std::endl;
- stream << padding;
- stream << " if ((ctx->exec_content_assign(ctx, ";
- stream << (HAS_ATTR(elem, "location") ? "\"" + escape(ATTR(elem, "location")) + "\"" : "NULL") << ", ";
- if (HAS_ATTR(elem, "expr")) {
- stream << "\"" + escape(ATTR(elem, "expr")) + "\"";
- } else {
- NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, elem);
- if (assignTexts.size() > 0) {
- stream << "\"";
- writeExecContent(stream, assignTexts[0], 0);
- stream << "\"";
- } else {
- stream << "NULL";
- }
- }
- stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
-
- } else if(TAGNAME(elem) == "raise") {
- stream << padding;
- stream << "if likely(ctx->exec_content_raise != NULL) {" << std::endl;
- stream << padding;
- stream << " if unlikely((ctx->exec_content_raise(ctx, ";
- stream << (HAS_ATTR(elem, "event") ? "\"" + escape(ATTR(elem, "event")) + "\"" : "NULL");
- stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
- } else if(TAGNAME(elem) == "send") {
- stream << padding;
- stream << "if likely(ctx->exec_content_send != NULL) {" << std::endl;
- stream << padding;
- stream << " if ((ctx->exec_content_send(ctx, &scxml_elem_sends[" << ATTR(elem, "documentOrder") << "]";
- stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
- } else if(TAGNAME(elem) == "cancel") {
- stream << padding;
- stream << "if likely(ctx->exec_content_cancel != NULL) {" << std::endl;
- stream << padding;
- stream << " if ((ctx->exec_content_cancel(ctx, ";
- stream << (HAS_ATTR(elem, "sendid") ? "\"" + escape(ATTR(elem, "sendid")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(elem, "sendidexpr") ? "\"" + escape(ATTR(elem, "sendidexpr")) + "\"" : "NULL");
- stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
- stream << padding << "} else {" << std::endl;
- stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
- stream << padding << "}" << std::endl;
-
- } else {
- std::cerr << "'" << TAGNAME(elem) << "'" << std::endl << elem << std::endl;
- assert(false);
- }
+ if (!node)
+ return;
+
+ if (node.getNodeType() == Node_base::TEXT_NODE) {
+ if (boost::trim_copy(node.getNodeValue()).length() > 0) {
+ std::string escaped = escape(node.getNodeValue());
+ stream << escaped;
+ }
+ return;
+ }
+
+ std::string padding;
+ for (int i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+
+ if (node.getNodeType() != Node_base::ELEMENT_NODE)
+ return; // skip anything not an element
+
+ Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(node);
+
+ if (false) {
+ } else if(TAGNAME(elem) == "onentry" || TAGNAME(elem) == "onexit" || TAGNAME(elem) == "transition" || TAGNAME(elem) == "finalize") {
+ // descent into childs and write their contents
+ Arabica::DOM::Node<std::string> child = node.getFirstChild();
+ while(child) {
+ writeExecContent(stream, child, indent);
+ child = child.getNextSibling();
+ }
+ } else if(TAGNAME(elem) == "script") {
+ stream << padding;
+ stream << "if likely(ctx->exec_content_script != NULL) {" << std::endl;
+ stream << padding;
+ stream << " if unlikely((err = ctx->exec_content_script(ctx, ";
+ stream << (HAS_ATTR(elem, "src") ? "\"" + escape(ATTR(elem, "src")) + "\"" : "NULL") << ", ";
+
+ NodeSet<std::string> scriptTexts = filterChildType(Node_base::TEXT_NODE, elem);
+ if (scriptTexts.size() > 0) {
+ stream << "\"";
+ writeExecContent(stream, scriptTexts[0], 0);
+ stream << "\"";
+ } else {
+ stream << "NULL";
+ }
+
+ stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+ } else if(TAGNAME(elem) == "log") {
+ stream << padding;
+ stream << "if likely(ctx->exec_content_log != NULL) {" << std::endl;
+ stream << padding;
+ stream << " if unlikely((ctx->exec_content_log(ctx, ";
+ stream << (HAS_ATTR(elem, "label") ? "\"" + escape(ATTR(elem, "label")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(elem, "expr") ? "\"" + escape(ATTR(elem, "expr")) + "\"" : "NULL");
+ stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+ } else if(TAGNAME(elem) == "foreach") {
+ stream << padding << "if likely(ctx->exec_content_foreach_init != NULL &&" << std::endl;
+ stream << padding << " ctx->exec_content_foreach_next != NULL &&" << std::endl;
+ stream << padding << " ctx->exec_content_foreach_done != NULL) {" << std::endl;
+ stream << std::endl;
+
+ stream << padding << " if unlikely((ctx->exec_content_foreach_init(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << " while (ctx->exec_content_foreach_next(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "]) == SCXML_ERR_OK) {" << std::endl;
+ Arabica::DOM::Node<std::string> child = node.getFirstChild();
+ while(child) {
+ writeExecContent(stream, child, indent + 2);
+ child = child.getNextSibling();
+ }
+ stream << padding << " }" << std::endl;
+ stream << padding << " if ((ctx->exec_content_foreach_done(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+ } else if(TAGNAME(elem) == "if") {
+ stream << padding;
+ stream << "if likely(ctx->is_true != NULL) {" << std::endl;
+ stream << padding;
+ stream << " if (ctx->is_true(ctx, " << (HAS_ATTR(elem, "cond") ? "\"" + escape(ATTR(elem, "cond")) + "\"" : "NULL") << ")) {" << std::endl;
+ Arabica::DOM::Node<std::string> child = elem.getFirstChild();
+ while(child) {
+ if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "elseif") {
+ stream << padding;
+ stream << " } else if (ctx->is_true(ctx, " << (HAS_ATTR_CAST(child, "cond") ? "\"" + escape(ATTR_CAST(child, "cond")) + "\"" : "NULL") << ")) {" << std::endl;
+ } else if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "else") {
+ stream << padding;
+ stream << " } else {" << std::endl;
+ } else {
+ writeExecContent(stream, child, indent + 2);
+ }
+ child = child.getNextSibling();
+ }
+ stream << padding << " }" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+ } else if(TAGNAME(elem) == "assign") {
+ stream << padding;
+ stream << "if likely(ctx->exec_content_assign != NULL) {" << std::endl;
+ stream << padding;
+ stream << " if ((ctx->exec_content_assign(ctx, ";
+ stream << (HAS_ATTR(elem, "location") ? "\"" + escape(ATTR(elem, "location")) + "\"" : "NULL") << ", ";
+ if (HAS_ATTR(elem, "expr")) {
+ stream << "\"" + escape(ATTR(elem, "expr")) + "\"";
+ } else {
+ NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, elem);
+ if (assignTexts.size() > 0) {
+ stream << "\"";
+ writeExecContent(stream, assignTexts[0], 0);
+ stream << "\"";
+ } else {
+ stream << "NULL";
+ }
+ }
+ stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+
+ } else if(TAGNAME(elem) == "raise") {
+ stream << padding;
+ stream << "if likely(ctx->exec_content_raise != NULL) {" << std::endl;
+ stream << padding;
+ stream << " if unlikely((ctx->exec_content_raise(ctx, ";
+ stream << (HAS_ATTR(elem, "event") ? "\"" + escape(ATTR(elem, "event")) + "\"" : "NULL");
+ stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+ } else if(TAGNAME(elem) == "send") {
+ stream << padding;
+ stream << "if likely(ctx->exec_content_send != NULL) {" << std::endl;
+ stream << padding;
+ stream << " if ((ctx->exec_content_send(ctx, &scxml_elem_sends[" << ATTR(elem, "documentOrder") << "]";
+ stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+ } else if(TAGNAME(elem) == "cancel") {
+ stream << padding;
+ stream << "if likely(ctx->exec_content_cancel != NULL) {" << std::endl;
+ stream << padding;
+ stream << " if ((ctx->exec_content_cancel(ctx, ";
+ stream << (HAS_ATTR(elem, "sendid") ? "\"" + escape(ATTR(elem, "sendid")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(elem, "sendidexpr") ? "\"" + escape(ATTR(elem, "sendidexpr")) + "\"" : "NULL");
+ stream << ")) != SCXML_ERR_OK) return err;" << std::endl;
+ stream << padding << "} else {" << std::endl;
+ stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl;
+ stream << padding << "}" << std::endl;
+
+ } else {
+ std::cerr << "'" << TAGNAME(elem) << "'" << std::endl << elem << std::endl;
+ assert(false);
+ }
}
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++) {
- Element<std::string> foreach(foreachs[i]);
- stream << " { ";
- stream << (HAS_ATTR(foreach, "array") ? "\"" + escape(ATTR(foreach, "array")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(foreach, "item") ? "\"" + escape(ATTR(foreach, "item")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(foreach, "index") ? "\"" + escape(ATTR(foreach, "index")) + "\"" : "NULL");
- stream << " }" << (i + 1 < foreachs.size() ? ",": "") << std::endl;
- foreach.setAttribute("documentOrder", toStr(i));
- }
- stream << "};" << std::endl;
- stream << std::endl;
- }
-
- NodeSet<std::string> datas = filterChildElements(_nsInfo.xmlNSPrefix + "data", _scxml, true);
- if (datas.size() > 0) {
- size_t dataIndexOffset = 0;
- Node<std::string> parent;
- size_t distinctParents = 0;
-
- if (_binding == InterpreterImpl::EARLY) {
- Element<std::string>(_states[0]).setAttribute("dataIndex", "0");
- distinctParents = 1;
- } else {
- for (int i = 0; i < datas.size(); i++) {
- Element<std::string> data(datas[i]);
- if (data.getParentNode() != parent) {
- distinctParents++;
- }
- }
- }
-
- 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++) {
- Element<std::string> data(datas[i]);
- if (data.getParentNode().getParentNode() != parent) {
- if (_binding == InterpreterImpl::LATE) {
- if (i > 0) {
- stream << " { NULL, NULL, NULL, NULL }," << std::endl;
- dataIndexOffset++;
- }
- Element<std::string>(data.getParentNode().getParentNode()).setAttribute("dataIndex", toStr(i + dataIndexOffset));
- }
- parent = data.getParentNode().getParentNode();
- }
- stream << " { ";
- stream << (HAS_ATTR(data, "id") ? "\"" + escape(ATTR(data, "id")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(data, "src") ? "\"" + escape(ATTR(data, "src")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(data, "expr") ? "\"" + escape(ATTR(data, "expr")) + "\"" : "NULL") << ", ";
-
- NodeSet<std::string> dataTexts = filterChildType(Node_base::TEXT_NODE, data);
- if (dataTexts.size() > 0) {
- if (boost::trim_copy(dataTexts[0].getNodeValue()).length() > 0) {
- std::string escaped = escape(dataTexts[0].getNodeValue());
- stream << "\"" << escaped << "\"" << std::endl;
- }
- } else {
- stream << "NULL";
- }
- stream << " }," << std::endl;
-
- }
- stream << " { NULL, NULL, NULL, NULL }" << std::endl;
- stream << "};" << std::endl;
- stream << std::endl;
- }
-
- NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", _scxml, true);
- if (params.size() > 0) {
- Node<std::string> parent;
- size_t distinctParents = 0;
- for (int i = 0; i < params.size(); i++) {
- Element<std::string> param(params[i]);
- if (param.getParentNode() != parent) {
- distinctParents++;
- }
- }
- 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++) {
- Element<std::string> param(params[i]);
- if (param.getParentNode() != parent) {
- Element<std::string>(param.getParentNode()).setAttribute("paramIndex", toStr(i));
- if (i > 0) {
- stream << " { NULL, NULL, NULL }," << std::endl;
- }
- parent = param.getParentNode();
- }
- stream << " { ";
- stream << (HAS_ATTR(param, "name") ? "\"" + escape(ATTR(param, "name")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(param, "expr") ? "\"" + escape(ATTR(param, "expr")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(param, "location") ? "\"" + escape(ATTR(param, "location")) + "\"" : "NULL");
- stream << " }," << std::endl;
-
- }
- stream << " { NULL, NULL, NULL }" << std::endl;
- stream << "};" << std::endl;
- stream << std::endl;
- }
-
- 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++) {
- Element<std::string> send(sends[i]);
- stream << " { ";
- stream << (HAS_ATTR(send, "event") ? "\"" + escape(ATTR(send, "event")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "eventexpr") ? "\"" + escape(ATTR(send, "eventexpr")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "target") ? "\"" + escape(ATTR(send, "target")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "targetexpr") ? "\"" + escape(ATTR(send, "targetexpr")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "type") ? "\"" + escape(ATTR(send, "type")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "typeexpr") ? "\"" + escape(ATTR(send, "typeexpr")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "id") ? "\"" + escape(ATTR(send, "id")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "idlocation") ? "\"" + escape(ATTR(send, "idlocation")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "delay") ? "\"" + escape(ATTR(send, "delay")) + "\"" : "NULL") << ", ";
- stream << (HAS_ATTR(send, "delayexpr") ? "\"" + escape(ATTR(send, "delayexpr")) + "\"" : "NULL") << ", ";
- 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++) {
- 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(send, "paramIndex")) {
- stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(send, "paramIndex")) << "], ";
- } else {
- stream << "NULL, ";
- }
- stream << "NULL";
-
- stream << " }" << (i + 1 < sends.size() ? ",": "") << std::endl;
- send.setAttribute("documentOrder", toStr(i));
- }
- stream << "};" << std::endl;
- stream << std::endl;
- }
-
- NodeSet<std::string> donedatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", _scxml, true);
- if (donedatas.size() > 0) {
- _hasDoneData = 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;
- } else {
- _hasDoneData = false;
- }
+ 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++) {
+ Element<std::string> foreach(foreachs[i]);
+ stream << " { ";
+ stream << (HAS_ATTR(foreach, "array") ? "\"" + escape(ATTR(foreach, "array")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(foreach, "item") ? "\"" + escape(ATTR(foreach, "item")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(foreach, "index") ? "\"" + escape(ATTR(foreach, "index")) + "\"" : "NULL");
+ stream << " }" << (i + 1 < foreachs.size() ? ",": "") << std::endl;
+ foreach.setAttribute("documentOrder", toStr(i));
+ }
+ stream << "};" << std::endl;
+ stream << std::endl;
+ }
+
+ NodeSet<std::string> datas = filterChildElements(_nsInfo.xmlNSPrefix + "data", _scxml, true);
+ if (datas.size() > 0) {
+ size_t dataIndexOffset = 0;
+ Node<std::string> parent;
+ size_t distinctParents = 0;
+
+ if (_binding == InterpreterImpl::EARLY) {
+ Element<std::string>(_states[0]).setAttribute("dataIndex", "0");
+ distinctParents = 1;
+ } else {
+ for (int i = 0; i < datas.size(); i++) {
+ Element<std::string> data(datas[i]);
+ if (data.getParentNode() != parent) {
+ distinctParents++;
+ }
+ }
+ }
+
+ 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++) {
+ Element<std::string> data(datas[i]);
+ if (data.getParentNode().getParentNode() != parent) {
+ if (_binding == InterpreterImpl::LATE) {
+ if (i > 0) {
+ stream << " { NULL, NULL, NULL, NULL }," << std::endl;
+ dataIndexOffset++;
+ }
+ Element<std::string>(data.getParentNode().getParentNode()).setAttribute("dataIndex", toStr(i + dataIndexOffset));
+ }
+ parent = data.getParentNode().getParentNode();
+ }
+ stream << " { ";
+ stream << (HAS_ATTR(data, "id") ? "\"" + escape(ATTR(data, "id")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(data, "src") ? "\"" + escape(ATTR(data, "src")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(data, "expr") ? "\"" + escape(ATTR(data, "expr")) + "\"" : "NULL") << ", ";
+
+ NodeSet<std::string> dataTexts = filterChildType(Node_base::TEXT_NODE, data);
+ if (dataTexts.size() > 0) {
+ if (boost::trim_copy(dataTexts[0].getNodeValue()).length() > 0) {
+ std::string escaped = escape(dataTexts[0].getNodeValue());
+ stream << "\"" << escaped << "\"" << std::endl;
+ }
+ } else {
+ stream << "NULL";
+ }
+ stream << " }," << std::endl;
+
+ }
+ stream << " { NULL, NULL, NULL, NULL }" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
+ }
+
+ NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", _scxml, true);
+ if (params.size() > 0) {
+ Node<std::string> parent;
+ size_t distinctParents = 0;
+ for (int i = 0; i < params.size(); i++) {
+ Element<std::string> param(params[i]);
+ if (param.getParentNode() != parent) {
+ distinctParents++;
+ }
+ }
+ 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++) {
+ Element<std::string> param(params[i]);
+ if (param.getParentNode() != parent) {
+ Element<std::string>(param.getParentNode()).setAttribute("paramIndex", toStr(i));
+ if (i > 0) {
+ stream << " { NULL, NULL, NULL }," << std::endl;
+ }
+ parent = param.getParentNode();
+ }
+ stream << " { ";
+ stream << (HAS_ATTR(param, "name") ? "\"" + escape(ATTR(param, "name")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(param, "expr") ? "\"" + escape(ATTR(param, "expr")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(param, "location") ? "\"" + escape(ATTR(param, "location")) + "\"" : "NULL");
+ stream << " }," << std::endl;
+
+ }
+ stream << " { NULL, NULL, NULL }" << std::endl;
+ stream << "};" << std::endl;
+ stream << std::endl;
+ }
+
+ 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++) {
+ Element<std::string> send(sends[i]);
+ stream << " { ";
+ stream << (HAS_ATTR(send, "event") ? "\"" + escape(ATTR(send, "event")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "eventexpr") ? "\"" + escape(ATTR(send, "eventexpr")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "target") ? "\"" + escape(ATTR(send, "target")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "targetexpr") ? "\"" + escape(ATTR(send, "targetexpr")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "type") ? "\"" + escape(ATTR(send, "type")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "typeexpr") ? "\"" + escape(ATTR(send, "typeexpr")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "id") ? "\"" + escape(ATTR(send, "id")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "idlocation") ? "\"" + escape(ATTR(send, "idlocation")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "delay") ? "\"" + escape(ATTR(send, "delay")) + "\"" : "NULL") << ", ";
+ stream << (HAS_ATTR(send, "delayexpr") ? "\"" + escape(ATTR(send, "delayexpr")) + "\"" : "NULL") << ", ";
+ 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++) {
+ 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(send, "paramIndex")) {
+ stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(send, "paramIndex")) << "], ";
+ } else {
+ stream << "NULL, ";
+ }
+ stream << "NULL";
+
+ stream << " }" << (i + 1 < sends.size() ? ",": "") << std::endl;
+ send.setAttribute("documentOrder", toStr(i));
+ }
+ stream << "};" << std::endl;
+ stream << std::endl;
+ }
+
+ NodeSet<std::string> donedatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", _scxml, true);
+ if (donedatas.size() > 0) {
+ _hasDoneData = 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;
+ } else {
+ _hasDoneData = false;
+ }
}
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++) {
- Element<std::string> state(_states[i]);
- stream << " { ";
-
- // name
- stream << (HAS_ATTR(state, "id") ? "\"" + escape(ATTR(state, "id")) + "\"" : "NULL") << ", ";
-
- // parent
- stream << (i == 0 ? "0" : ATTR_CAST(state.getParentNode(), "documentOrder")) << ", ";
-
- // onentry
- stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_entry" : "NULL") << ", ";
-
- // onexit
- stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_exit" : "NULL") << ", ";
-
- // invokers
- stream << (filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state).size() > 0 ? DOMUtils::idForNode(state) + "_invoke" : "NULL") << ", ";
-
- // children
- std::string childBools;
- std::string childBoolsIdx;
- for (int j = 0; j < _states.size(); j++) {
- if (_states[j].getParentNode() == state) {
- childBools += "1";
- childBoolsIdx += " " + toStr(j);
- } else {
- childBools += "0";
- }
- }
- stream << "{ ";
- writeCharArrayInitList(stream, childBools);
- stream << " /* " << childBools << "," << childBoolsIdx << " */";
- stream << " }, ";
-
- // 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++) {
- if (deep) {
- if (isDescendant(_states[j], state.getParentNode()) && !isHistory(Element<std::string>(_states[j]))) {
- completion.push_back(_states[j]);
- }
- } else {
- if (_states[j].getParentNode() == state.getParentNode() && !isHistory(Element<std::string>(_states[j]))) {
- completion.push_back(_states[j]);
- }
- }
- }
- } if (isParallel(state)) {
- completion = getChildStates(state);
- } else if (state.hasAttribute("initial")) {
- completion = getStates(tokenizeIdRefs(state.getAttribute("initial")));
- } else {
- NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state);
- if(initElems.size() > 0 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) {
- // initial element is first child
- completion.push_back(initElems[0]);
- } else {
- // first child state
- Arabica::XPath::NodeSet<std::string> initStates;
- NodeList<std::string> childs = state.getChildNodes();
- for (int i = 0; i < childs.getLength(); i++) {
- if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (isState(Element<std::string>(childs.item(i)))) {
- completion.push_back(childs.item(i));
- break;
- }
- }
- }
- }
-
- std::string descBools;
- std::string descBoolsIdx;
- for (int j = 0; j < _states.size(); j++) {
- if (isMember(_states[j], completion)) {
- descBools += "1";
- descBoolsIdx += " " + toStr(j);
- } else {
- descBools += "0";
- }
- }
- stream << "{ ";
- writeCharArrayInitList(stream, descBools);
- stream << " /* " << descBools << "," << descBoolsIdx << " */";
- stream << " }, ";
-
- // ancestors
- std::string ancBools;
- std::string ancBoolsIdx;
- for (int j = 0; j < _states.size(); j++) {
- if (isDescendant(state, _states[j])) {
- ancBools += "1";
- ancBoolsIdx += " " + toStr(j);
- } else {
- ancBools += "0";
- }
- }
- stream << "{ ";
- writeCharArrayInitList(stream, ancBools);
- stream << " /* " << ancBools << "," << ancBoolsIdx << " */";
- stream << " }, ";
-
- if (HAS_ATTR(state, "dataIndex")) {
- stream << "(const scxml_elem_data*)&scxml_elem_datas[" << escape(ATTR(state, "dataIndex")) << "], ";
- } else {
- stream << "NULL, ";
- }
-
- if (false) {
- } else if (iequals(TAGNAME(state), "initial")) {
- stream << "SCXML_STATE_INITIAL";
- } else if (isFinal(state)) {
- stream << "SCXML_STATE_FINAL";
- } else if (isHistory(state)) {
- if (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")) {
- stream << "SCXML_STATE_HISTORY_DEEP";
- } else {
- stream << "SCXML_STATE_HISTORY_SHALLOW";
- }
- } else if (isAtomic(state)) {
- stream << "SCXML_STATE_ATOMIC";
- } else if (isParallel(state)) {
- stream << "SCXML_STATE_PARALLEL";
- } else if (isCompound(state)) {
- stream << "SCXML_STATE_COMPOUND";
- } else { // <scxml>
- stream << "SCXML_STATE_COMPOUND";
- }
-
- stream << " }" << (i + 1 < _states.size() ? ",": "") << std::endl;
- }
- stream << "};" << std::endl;
- stream << std::endl;
+ stream << "static scxml_state scxml_states[" << toStr(_states.size()) << "] = {" << std::endl;
+ for (int i = 0; i < _states.size(); i++) {
+ Element<std::string> state(_states[i]);
+ stream << " { ";
+
+ // name
+ stream << (HAS_ATTR(state, "id") ? "\"" + escape(ATTR(state, "id")) + "\"" : "NULL") << ", ";
+
+ // parent
+ stream << (i == 0 ? "0" : ATTR_CAST(state.getParentNode(), "documentOrder")) << ", ";
+
+ // onentry
+ stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_entry" : "NULL") << ", ";
+
+ // onexit
+ stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_exit" : "NULL") << ", ";
+
+ // invokers
+ stream << (filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state).size() > 0 ? DOMUtils::idForNode(state) + "_invoke" : "NULL") << ", ";
+
+ // children
+ std::string childBools;
+ std::string childBoolsIdx;
+ for (int j = 0; j < _states.size(); j++) {
+ if (_states[j].getParentNode() == state) {
+ childBools += "1";
+ childBoolsIdx += " " + toStr(j);
+ } else {
+ childBools += "0";
+ }
+ }
+ stream << "{ ";
+ writeCharArrayInitList(stream, childBools);
+ stream << " /* " << childBools << "," << childBoolsIdx << " */";
+ stream << " }, ";
+
+ // 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++) {
+ if (deep) {
+ if (isDescendant(_states[j], state.getParentNode()) && !isHistory(Element<std::string>(_states[j]))) {
+ completion.push_back(_states[j]);
+ }
+ } else {
+ if (_states[j].getParentNode() == state.getParentNode() && !isHistory(Element<std::string>(_states[j]))) {
+ completion.push_back(_states[j]);
+ }
+ }
+ }
+ }
+ if (isParallel(state)) {
+ completion = getChildStates(state);
+ } else if (state.hasAttribute("initial")) {
+ completion = getStates(tokenizeIdRefs(state.getAttribute("initial")));
+ } else {
+ NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state);
+ if(initElems.size() > 0 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) {
+ // initial element is first child
+ completion.push_back(initElems[0]);
+ } else {
+ // first child state
+ Arabica::XPath::NodeSet<std::string> initStates;
+ NodeList<std::string> childs = state.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (isState(Element<std::string>(childs.item(i)))) {
+ completion.push_back(childs.item(i));
+ break;
+ }
+ }
+ }
+ }
+
+ std::string descBools;
+ std::string descBoolsIdx;
+ for (int j = 0; j < _states.size(); j++) {
+ if (isMember(_states[j], completion)) {
+ descBools += "1";
+ descBoolsIdx += " " + toStr(j);
+ } else {
+ descBools += "0";
+ }
+ }
+ stream << "{ ";
+ writeCharArrayInitList(stream, descBools);
+ stream << " /* " << descBools << "," << descBoolsIdx << " */";
+ stream << " }, ";
+
+ // ancestors
+ std::string ancBools;
+ std::string ancBoolsIdx;
+ for (int j = 0; j < _states.size(); j++) {
+ if (isDescendant(state, _states[j])) {
+ ancBools += "1";
+ ancBoolsIdx += " " + toStr(j);
+ } else {
+ ancBools += "0";
+ }
+ }
+ stream << "{ ";
+ writeCharArrayInitList(stream, ancBools);
+ stream << " /* " << ancBools << "," << ancBoolsIdx << " */";
+ stream << " }, ";
+
+ if (HAS_ATTR(state, "dataIndex")) {
+ stream << "(const scxml_elem_data*)&scxml_elem_datas[" << escape(ATTR(state, "dataIndex")) << "], ";
+ } else {
+ stream << "NULL, ";
+ }
+
+ if (false) {
+ } else if (iequals(TAGNAME(state), "initial")) {
+ stream << "SCXML_STATE_INITIAL";
+ } else if (isFinal(state)) {
+ stream << "SCXML_STATE_FINAL";
+ } else if (isHistory(state)) {
+ if (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")) {
+ stream << "SCXML_STATE_HISTORY_DEEP";
+ } else {
+ stream << "SCXML_STATE_HISTORY_SHALLOW";
+ }
+ } else if (isAtomic(state)) {
+ stream << "SCXML_STATE_ATOMIC";
+ } else if (isParallel(state)) {
+ stream << "SCXML_STATE_PARALLEL";
+ } else if (isCompound(state)) {
+ stream << "SCXML_STATE_COMPOUND";
+ } else { // <scxml>
+ stream << "SCXML_STATE_COMPOUND";
+ }
+
+ stream << " }" << (i + 1 < _states.size() ? ",": "") << std::endl;
+ }
+ stream << "};" << std::endl;
+ stream << std::endl;
}
-
-
+
+
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++) {
- Element<std::string> transition(_transitions[i]);
- stream << " { ";
-
- /**
- uint16_t source;
- target[SCXML_NUMBER_STATES / 8 + 1];
- const char* event;
- const char* condition;
- exec_content_t on_transition;
- uint8_t type;
- char conflicts[SCXML_NUMBER_STATES / 8 + 1];
- char exit_set[SCXML_NUMBER_STATES / 8 + 1];
- */
-
- // source
- stream << ATTR_CAST(transition.getParentNode(), "documentOrder") << ", ";
-
- // targets
- 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++) {
- 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";
- } else {
- targetBools += "0";
- }
- }
-
- stream << "{ ";
- writeCharArrayInitList(stream, targetBools);
- stream << " /* " << targetBools << " */";
- stream << " }, ";
-
- } else {
- stream << "{ NULL }, ";
- }
-
- // event
- stream << (HAS_ATTR(transition, "event") ? "\"" + escape(ATTR(transition, "event")) + "\"" : "NULL") << ", ";
-
- // condition
- stream << (HAS_ATTR(transition, "cond") ? "\"" + escape(ATTR(transition, "cond")) + "\"" : "NULL") << ", ";
-
- // on transition handlers
- if (filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0 &&
- !iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) {
- stream << DOMUtils::idForNode(transition) + "_on_trans, ";
- } else {
- stream << "NULL, ";
- }
-
- // type
- std::string seperator = "";
- if (!HAS_ATTR(transition, "target")) {
- stream << seperator << "SCXML_TRANS_TARGETLESS";
- seperator = " | ";
- }
-
- if (HAS_ATTR(transition, "type") && iequals(ATTR(transition, "type"), "internal")) {
- stream << seperator << "SCXML_TRANS_INTERNAL";
- seperator = " | ";
- }
-
- if (!HAS_ATTR(transition, "event")) {
- stream << seperator << "SCXML_TRANS_SPONTANEOUS";
- seperator = " | ";
- }
-
- if (iequals(TAGNAME_CAST(transition.getParentNode()), "history")) {
- stream << seperator << "SCXML_TRANS_HISTORY";
- seperator = " | ";
- }
-
- if (seperator.size() == 0) {
- stream << "0";
- }
- stream << ", ";
-
- // conflicts
- std::string conflictBools;
- for (unsigned int j = 0; j < _transitions.size(); j++) {
- Element<std::string> t2(_transitions[j]);
- if (hasIntersection(computeExitSet(transition), computeExitSet(t2)) ||
- (getSourceState(transition) == getSourceState(t2)) ||
- (isDescendant(getSourceState(transition), getSourceState(t2))) ||
- (isDescendant(getSourceState(t2), getSourceState(transition)))) {
- conflictBools += "1";
- } else {
- conflictBools += "0";
- }
- }
- stream << "{ ";
- writeCharArrayInitList(stream, conflictBools);
- stream << " /* " << conflictBools << " */";
- stream << " }, ";
-
- // exit set
- std::string exitSetBools;
- 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";
- } else {
- exitSetBools += "0";
- }
- }
- stream << "{ ";
- writeCharArrayInitList(stream, exitSetBools);
- stream << " /* " << exitSetBools << " */";
- stream << " }";
-
- stream << " }" << (i + 1 < _transitions.size() ? ",": "") << std::endl;
- }
- stream << "};" << std::endl;
- stream << std::endl;
+ stream << "static scxml_transition scxml_transitions[" << toStr(_transitions.size()) << "] = {" << std::endl;
+ for (int i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ stream << " { ";
+
+ /**
+ uint16_t source;
+ target[SCXML_NUMBER_STATES / 8 + 1];
+ const char* event;
+ const char* condition;
+ exec_content_t on_transition;
+ uint8_t type;
+ char conflicts[SCXML_NUMBER_STATES / 8 + 1];
+ char exit_set[SCXML_NUMBER_STATES / 8 + 1];
+ */
+
+ // source
+ stream << ATTR_CAST(transition.getParentNode(), "documentOrder") << ", ";
+
+ // targets
+ 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++) {
+ 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";
+ } else {
+ targetBools += "0";
+ }
+ }
+
+ stream << "{ ";
+ writeCharArrayInitList(stream, targetBools);
+ stream << " /* " << targetBools << " */";
+ stream << " }, ";
+
+ } else {
+ stream << "{ NULL }, ";
+ }
+
+ // event
+ stream << (HAS_ATTR(transition, "event") ? "\"" + escape(ATTR(transition, "event")) + "\"" : "NULL") << ", ";
+
+ // condition
+ stream << (HAS_ATTR(transition, "cond") ? "\"" + escape(ATTR(transition, "cond")) + "\"" : "NULL") << ", ";
+
+ // on transition handlers
+ if (filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0 &&
+ !iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) {
+ stream << DOMUtils::idForNode(transition) + "_on_trans, ";
+ } else {
+ stream << "NULL, ";
+ }
+
+ // type
+ std::string seperator = "";
+ if (!HAS_ATTR(transition, "target")) {
+ stream << seperator << "SCXML_TRANS_TARGETLESS";
+ seperator = " | ";
+ }
+
+ if (HAS_ATTR(transition, "type") && iequals(ATTR(transition, "type"), "internal")) {
+ stream << seperator << "SCXML_TRANS_INTERNAL";
+ seperator = " | ";
+ }
+
+ if (!HAS_ATTR(transition, "event")) {
+ stream << seperator << "SCXML_TRANS_SPONTANEOUS";
+ seperator = " | ";
+ }
+
+ if (iequals(TAGNAME_CAST(transition.getParentNode()), "history")) {
+ stream << seperator << "SCXML_TRANS_HISTORY";
+ seperator = " | ";
+ }
+
+ if (seperator.size() == 0) {
+ stream << "0";
+ }
+ stream << ", ";
+
+ // conflicts
+ std::string conflictBools;
+ for (unsigned int j = 0; j < _transitions.size(); j++) {
+ Element<std::string> t2(_transitions[j]);
+ if (hasIntersection(computeExitSet(transition), computeExitSet(t2)) ||
+ (getSourceState(transition) == getSourceState(t2)) ||
+ (isDescendant(getSourceState(transition), getSourceState(t2))) ||
+ (isDescendant(getSourceState(t2), getSourceState(transition)))) {
+ conflictBools += "1";
+ } else {
+ conflictBools += "0";
+ }
+ }
+ stream << "{ ";
+ writeCharArrayInitList(stream, conflictBools);
+ stream << " /* " << conflictBools << " */";
+ stream << " }, ";
+
+ // exit set
+ std::string exitSetBools;
+ 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";
+ } else {
+ exitSetBools += "0";
+ }
+ }
+ stream << "{ ";
+ writeCharArrayInitList(stream, exitSetBools);
+ stream << " /* " << exitSetBools << " */";
+ stream << " }";
+
+ stream << " }" << (i + 1 < _transitions.size() ? ",": "") << std::endl;
+ }
+ stream << "};" << std::endl;
+ stream << std::endl;
}
Arabica::XPath::NodeSet<std::string> ChartToC::computeExitSet(const Arabica::DOM::Element<std::string>& transition) {
-
- NodeSet<std::string> statesToExit;
- if (!isTargetless(transition)) {
- Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
- if (!domain)
- return statesToExit;
- for (unsigned int j = 0; j < _states.size(); j++) {
- const Node<std::string>& s = _states[j];
- if (isDescendant(s, domain)) {
- statesToExit.push_back(s);
- }
- }
- }
-
- return statesToExit;
+
+ NodeSet<std::string> statesToExit;
+ if (!isTargetless(transition)) {
+ Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
+ if (!domain)
+ return statesToExit;
+ for (unsigned int j = 0; j < _states.size(); j++) {
+ const Node<std::string>& s = _states[j];
+ if (isDescendant(s, domain)) {
+ statesToExit.push_back(s);
+ }
+ }
+ }
+
+ return statesToExit;
}
void ChartToC::writeCharArrayInitList(std::ostream& stream, const std::string& boolString) {
- /**
- * 0111 -> 0x08
- * 1111 -> 0x0f
- * 1111 1111 -> 0xff
- * 1111 1111 1110 -> 0x0f, 0xfd
- *
- * 76543210 fedcba98 ...
- */
-
- std::string charArray;
- size_t index = 0;
- char currChar = 0;
-
- for (std::string::const_iterator bIter = boolString.begin(); bIter != boolString.end(); bIter++) {
-
- if (*bIter == '1') {
- currChar |= 1 << index;
- }
-
- index++;
- if (index == 8) {
- charArray += currChar;
- currChar = 0;
- index = 0;
- }
- }
-
- if (index != 0) {
- charArray += currChar;
- }
-
- std::string seperator = "";
- for (std::string::const_iterator cIter = charArray.begin(); cIter != charArray.end(); cIter++) {
- stream << seperator << "0x" << std::setw(2) << std::setfill('0') << std::hex << int(*cIter & 0xFF);
- seperator = ", ";
- }
+ /**
+ * 0111 -> 0x08
+ * 1111 -> 0x0f
+ * 1111 1111 -> 0xff
+ * 1111 1111 1110 -> 0x0f, 0xfd
+ *
+ * 76543210 fedcba98 ...
+ */
+
+ std::string charArray;
+ size_t index = 0;
+ char currChar = 0;
+
+ for (std::string::const_iterator bIter = boolString.begin(); bIter != boolString.end(); bIter++) {
+
+ if (*bIter == '1') {
+ currChar |= 1 << index;
+ }
+
+ index++;
+ if (index == 8) {
+ charArray += currChar;
+ currChar = 0;
+ index = 0;
+ }
+ }
+
+ if (index != 0) {
+ charArray += currChar;
+ }
+
+ std::string seperator = "";
+ for (std::string::const_iterator cIter = charArray.begin(); cIter != charArray.end(); cIter++) {
+ stream << seperator << "0x" << std::setw(2) << std::setfill('0') << std::hex << int(*cIter & 0xFF);
+ seperator = ", ";
+ }
}
void ChartToC::writeFSM(std::ostream& stream) {
- stream << "static int scxml_step(scxml_ctx* ctx) {" << std::endl;
- stream << std::endl;
-
- stream << "#ifdef SCXML_VERBOSE" << std::endl;
- stream << " printf(\"Config: \");" << std::endl;
- stream << " printStateNames(ctx->config);" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << "// MACRO_STEP:" << std::endl;
- stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl;
- stream << std::endl;
-
- stream << " if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL) " << std::endl;
- stream << " return SCXML_ERR_DONE; " << std::endl;
- stream << std::endl;
-
- stream << " int err = SCXML_ERR_OK;" << std::endl;
- stream << " char conflicts[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl;
- stream << " char target_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
- stream << " char exit_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
- stream << " char trans_set[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl;
- stream << " char entry_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
- stream << std::endl;
-
- stream << " void* event;" << std::endl;
- stream << " if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {" << std::endl;
- if (_hasGlobalScripts) {
- 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 COMPLETE_CONFIG;" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << " if (ctx->flags & SCXML_CTX_SPONTANEOUS) {" << std::endl;
- stream << " event = NULL;" << std::endl;
- stream << " goto SELECT_TRANSITIONS;" << std::endl;
- stream << " }" << std::endl;
- stream << " if ((event = ctx->dequeue_internal(ctx)) != NULL) {" << std::endl;
- stream << " goto SELECT_TRANSITIONS;" << std::endl;
- stream << " }" << std::endl;
- stream << " if ((event = ctx->dequeue_external(ctx)) != NULL) {" << std::endl;
-
- stream << " goto SELECT_TRANSITIONS;" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
+ stream << "static int scxml_step(scxml_ctx* ctx) {" << std::endl;
+ stream << std::endl;
+
+ stream << "#ifdef SCXML_VERBOSE" << std::endl;
+ stream << " printf(\"Config: \");" << std::endl;
+ stream << " printStateNames(ctx->config);" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << "// MACRO_STEP:" << std::endl;
+ stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl;
+ stream << std::endl;
+
+ stream << " if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL) " << std::endl;
+ stream << " return SCXML_ERR_DONE; " << std::endl;
+ stream << std::endl;
+
+ stream << " int err = SCXML_ERR_OK;" << std::endl;
+ stream << " char conflicts[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl;
+ stream << " char target_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
+ stream << " char exit_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
+ stream << " char trans_set[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl;
+ stream << " char entry_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
+ stream << std::endl;
+
+ stream << " void* event;" << std::endl;
+ stream << " if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {" << std::endl;
+ if (_hasGlobalScripts) {
+ 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 COMPLETE_CONFIG;" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << " if (ctx->flags & SCXML_CTX_SPONTANEOUS) {" << std::endl;
+ stream << " event = NULL;" << std::endl;
+ stream << " goto SELECT_TRANSITIONS;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " if ((event = ctx->dequeue_internal(ctx)) != NULL) {" << std::endl;
+ stream << " goto SELECT_TRANSITIONS;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " if ((event = ctx->dequeue_external(ctx)) != NULL) {" << std::endl;
+
+ stream << " goto SELECT_TRANSITIONS;" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
// HISTORY TRANSITION IS SELECTED BY ACCIDENT!
-
- stream << "SELECT_TRANSITIONS:" << std::endl;
- stream << " for (int 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_HISTORY))" << std::endl;
- stream << " continue;" << std::endl;
- stream << std::endl;
- stream << " // is the transition active?" << std::endl;
- stream << " if (IS_SET(scxml_transitions[i].source, ctx->config)) {" << std::endl;
- stream << " // is it non-conflicting?" << std::endl;
- stream << " if (!IS_SET(i, conflicts)) {" << std::endl;
- stream << " // is it enabled?" << std::endl;
- stream << " if (ctx->is_enabled(ctx, &scxml_transitions[i], event) > 0) {" << std::endl;
- stream << " // remember that we found a transition" << std::endl;
- stream << " ctx->flags |= SCXML_CTX_TRANSITION_FOUND;" << std::endl;
- stream << std::endl;
-
- stream << " // transitions that are pre-empted" << std::endl;
- stream << " bit_or(conflicts, scxml_transitions[i].conflicts, " << _transCharArraySize << ");" << std::endl;
- stream << std::endl;
- stream << " // states that are directly targeted (resolve as entry-set later)" << std::endl;
- stream << " bit_or(target_set, scxml_transitions[i].target, " << _stateCharArraySize << ");" << std::endl;
- stream << std::endl;
- stream << " // states that will be left" << std::endl;
- stream << " bit_or(exit_set, scxml_transitions[i].exit_set, " << _stateCharArraySize << ");" << std::endl;
- stream << std::endl;
- stream << " SET_BIT(i, trans_set);" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " bit_and(exit_set, ctx->config, " << _stateCharArraySize << ");" << std::endl;
- stream << std::endl;
-
- stream << " if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) {" << std::endl;
- stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS;" << std::endl;
- stream << " } else {" << std::endl;
- stream << " ctx->flags &= ~SCXML_CTX_SPONTANEOUS;" << std::endl;
- stream << " // goto MACRO_STEP;" << std::endl;
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << "#ifdef SCXML_VERBOSE" << std::endl;
- stream << " printf(\"Targets: \");" << std::endl;
- stream << " printStateNames(target_set);" << 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].source, 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" << 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 << "#ifdef SCXML_VERBOSE" << std::endl;
- stream << " printf(\"Exiting: \");" << std::endl;
- stream << " printStateNames(exit_set);" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << "#ifdef SCXML_VERBOSE" << std::endl;
- stream << " printf(\"History: \");" << std::endl;
- stream << " printStateNames(ctx->history);" << std::endl;
- 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], 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 << "COMPLETE_CONFIG:" << 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 << " if (IS_SET(i, entry_set)) {" << std::endl;
- stream << " bit_or(entry_set, scxml_states[i].ancestors, " << _stateCharArraySize << ");" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << "// ADD_DESCENDANTS:" << std::endl;
- stream << " // iterate for descendants" << std::endl;
- stream << " for (int 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;
- stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
- stream << " break;" << std::endl;
- stream << " }" << std::endl;
- stream << " case SCXML_STATE_HISTORY_SHALLOW:" << std::endl;
- stream << " case SCXML_STATE_HISTORY_DEEP: {" << std::endl;
- stream << " char history_targets[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
- stream << " if (!bit_has_and(scxml_states[i].completion, ctx->history, " << _stateCharArraySize << ")) {" << std::endl;
- stream << " // 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 << " if unlikely(scxml_transitions[j].source == i) {" << std::endl;
- stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl;
- stream << " SET_BIT(j, trans_set);" << std::endl;
- stream << " break;" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " // TODO: enter parents default completion here" << std::endl;
- stream << " } else {" << std::endl;
- stream << " bit_copy(history_targets, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
- stream << " bit_and(history_targets, ctx->history, " << _stateCharArraySize << ");" << std::endl;
- stream << " bit_or(entry_set, history_targets, " << _stateCharArraySize << ");" << std::endl;
- stream << " }" << std::endl;
- 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 << " if (scxml_transitions[j].source == i) {" << std::endl;
- stream << " SET_BIT(j, trans_set);" << std::endl;
- stream << " CLEARBIT(i, entry_set);" << std::endl;
- stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl;
- stream << " // one target may have been above, reestablish completion" << std::endl;
- stream << " // goto ADD_DESCENDANTS; // initial will have to be first!" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- 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 << " {" << std::endl;
- stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
- stream << " }" << std::endl;
- stream << " break;" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << "#ifdef SCXML_VERBOSE" << std::endl;
- stream << " printf(\"Transitions: \");" << std::endl;
- stream << " printBitsetIndices(trans_set, sizeof(char) * 8 * " << _transCharArraySize << ");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << "// TAKE_TRANSITIONS:" << std::endl;
- stream << " for (int 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;
- stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl;
- stream << " &scxml_states[scxml_transitions[i].source]," << std::endl;
- stream << " event)) != SCXML_ERR_OK)" << std::endl;
- stream << " return err;" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << "#ifdef SCXML_VERBOSE" << std::endl;
- stream << " printf(\"Entering: \");" << std::endl;
- stream << " printStateNames(entry_set);" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << "// ENTER_STATES:" << std::endl;
- stream << " for (int 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;
- stream << " scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl;
- stream << " scxml_states[i].type == SCXML_STATE_INITIAL)" << std::endl;
- stream << " continue;" << std::endl;
- stream << std::endl;
-
- stream << " SET_BIT(i, ctx->config);" << std::endl;
- stream << std::endl;
-
- stream << " // initialize data" << std::endl;
- stream << " if (!IS_SET(i, ctx->initialized_data)) {" << std::endl;
- stream << " if unlikely(scxml_states[i].data != NULL && ctx->exec_content_init != NULL) {" << std::endl;
- stream << " ctx->exec_content_init(ctx, scxml_states[i].data);" << std::endl;
- stream << " }" << std::endl;
- stream << " SET_BIT(i, ctx->initialized_data);" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << " if (scxml_states[i].on_entry != NULL) {" << std::endl;
- stream << " if unlikely((err = scxml_states[i].on_entry(ctx, &scxml_states[i], event)) != SCXML_ERR_OK)" << std::endl;
- stream << " return err;" << 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;
- stream << " if unlikely(scxml_states[i].ancestors[0] == 0x01) {" << std::endl;
- stream << " ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL;" << std::endl;
- stream << " } else {" << std::endl;
- stream << " // raise done event" << std::endl;
- stream << " size_t parent = 0;" << std::endl;
- stream << " for (int j = SCXML_NUMBER_STATES - 1; j >= 0; j--) {" << std::endl;
- stream << " // we could trade runtime for memory here by saving the parent index" << std::endl;
- stream << " if unlikely(IS_SET(j, scxml_states[i].ancestors)) {" << std::endl;
- stream << " parent = j;" << std::endl;
- stream << " break;" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " // is this raised for toplevel final as well?" << std::endl;
- if (_hasDoneData) {
- 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[parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl;
- } else {
- stream << " ctx->raise_done_event(ctx, &scxml_states[parent], NULL);" << std::endl;
- }
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << " /**" << std::endl;
- stream << " * are we the last final state to leave a parallel state?:" << std::endl;
- stream << " * 1. Gather all parallel states in our ancestor chain" << std::endl;
- stream << " * 2. Find all states for which these parallels are ancestors" << std::endl;
- 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 << " 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 << " 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;
- stream << " } else {" << std::endl;
- stream << " SET_BIT(k, parallel_children);" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " if unlikely(!bit_any_set(parallel_children, " << _stateCharArraySize << ")) {" << std::endl;
- stream << " ctx->raise_done_event(ctx, &scxml_states[parallel], NULL);" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
- stream << "// HISTORY_TRANSITIONS:" << std::endl;
- stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl;
- stream << " if unlikely(IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY)) {" << std::endl;
- stream << " // call executable content in transition" << std::endl;
- stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl;
- stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl;
- stream << " &scxml_states[scxml_transitions[i].source]," << std::endl;
- stream << " event)) != SCXML_ERR_OK)" << std::endl;
- stream << " return err;" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << " }" << std::endl;
- stream << std::endl;
-
-
- stream << " return SCXML_ERR_OK;" << std::endl;
- stream << "}" << std::endl;
- stream << std::endl;
+
+ stream << "SELECT_TRANSITIONS:" << std::endl;
+ stream << " for (int 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_HISTORY))" << std::endl;
+ stream << " continue;" << std::endl;
+ stream << std::endl;
+ stream << " // is the transition active?" << std::endl;
+ stream << " if (IS_SET(scxml_transitions[i].source, ctx->config)) {" << std::endl;
+ stream << " // is it non-conflicting?" << std::endl;
+ stream << " if (!IS_SET(i, conflicts)) {" << std::endl;
+ stream << " // is it enabled?" << std::endl;
+ stream << " if (ctx->is_enabled(ctx, &scxml_transitions[i], event) > 0) {" << std::endl;
+ stream << " // remember that we found a transition" << std::endl;
+ stream << " ctx->flags |= SCXML_CTX_TRANSITION_FOUND;" << std::endl;
+ stream << std::endl;
+
+ stream << " // transitions that are pre-empted" << std::endl;
+ stream << " bit_or(conflicts, scxml_transitions[i].conflicts, " << _transCharArraySize << ");" << std::endl;
+ stream << std::endl;
+ stream << " // states that are directly targeted (resolve as entry-set later)" << std::endl;
+ stream << " bit_or(target_set, scxml_transitions[i].target, " << _stateCharArraySize << ");" << std::endl;
+ stream << std::endl;
+ stream << " // states that will be left" << std::endl;
+ stream << " bit_or(exit_set, scxml_transitions[i].exit_set, " << _stateCharArraySize << ");" << std::endl;
+ stream << std::endl;
+ stream << " SET_BIT(i, trans_set);" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " bit_and(exit_set, ctx->config, " << _stateCharArraySize << ");" << std::endl;
+ stream << std::endl;
+
+ stream << " if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) {" << std::endl;
+ stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS;" << std::endl;
+ stream << " } else {" << std::endl;
+ stream << " ctx->flags &= ~SCXML_CTX_SPONTANEOUS;" << std::endl;
+ stream << " // goto MACRO_STEP;" << std::endl;
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << "#ifdef SCXML_VERBOSE" << std::endl;
+ stream << " printf(\"Targets: \");" << std::endl;
+ stream << " printStateNames(target_set);" << 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].source, 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" << 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 << "#ifdef SCXML_VERBOSE" << std::endl;
+ stream << " printf(\"Exiting: \");" << std::endl;
+ stream << " printStateNames(exit_set);" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << "#ifdef SCXML_VERBOSE" << std::endl;
+ stream << " printf(\"History: \");" << std::endl;
+ stream << " printStateNames(ctx->history);" << std::endl;
+ 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], 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 << "COMPLETE_CONFIG:" << 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 << " if (IS_SET(i, entry_set)) {" << std::endl;
+ stream << " bit_or(entry_set, scxml_states[i].ancestors, " << _stateCharArraySize << ");" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << "// ADD_DESCENDANTS:" << std::endl;
+ stream << " // iterate for descendants" << std::endl;
+ stream << " for (int 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;
+ stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " case SCXML_STATE_HISTORY_SHALLOW:" << std::endl;
+ stream << " case SCXML_STATE_HISTORY_DEEP: {" << std::endl;
+ stream << " char history_targets[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl;
+ stream << " if (!bit_has_and(scxml_states[i].completion, ctx->history, " << _stateCharArraySize << ")) {" << std::endl;
+ stream << " // 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 << " if unlikely(scxml_transitions[j].source == i) {" << std::endl;
+ stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl;
+ stream << " SET_BIT(j, trans_set);" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " // TODO: enter parents default completion here" << std::endl;
+ stream << " } else {" << std::endl;
+ stream << " bit_copy(history_targets, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
+ stream << " bit_and(history_targets, ctx->history, " << _stateCharArraySize << ");" << std::endl;
+ stream << " bit_or(entry_set, history_targets, " << _stateCharArraySize << ");" << std::endl;
+ stream << " }" << std::endl;
+ 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 << " if (scxml_transitions[j].source == i) {" << std::endl;
+ stream << " SET_BIT(j, trans_set);" << std::endl;
+ stream << " CLEARBIT(i, entry_set);" << std::endl;
+ stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl;
+ stream << " // one target may have been above, reestablish completion" << std::endl;
+ stream << " // goto ADD_DESCENDANTS; // initial will have to be first!" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ 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 << " {" << std::endl;
+ stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl;
+ stream << " }" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << "#ifdef SCXML_VERBOSE" << std::endl;
+ stream << " printf(\"Transitions: \");" << std::endl;
+ stream << " printBitsetIndices(trans_set, sizeof(char) * 8 * " << _transCharArraySize << ");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << "// TAKE_TRANSITIONS:" << std::endl;
+ stream << " for (int 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;
+ stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl;
+ stream << " &scxml_states[scxml_transitions[i].source]," << std::endl;
+ stream << " event)) != SCXML_ERR_OK)" << std::endl;
+ stream << " return err;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << "#ifdef SCXML_VERBOSE" << std::endl;
+ stream << " printf(\"Entering: \");" << std::endl;
+ stream << " printStateNames(entry_set);" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << "// ENTER_STATES:" << std::endl;
+ stream << " for (int 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;
+ stream << " scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl;
+ stream << " scxml_states[i].type == SCXML_STATE_INITIAL)" << std::endl;
+ stream << " continue;" << std::endl;
+ stream << std::endl;
+
+ stream << " SET_BIT(i, ctx->config);" << std::endl;
+ stream << std::endl;
+
+ stream << " // initialize data" << std::endl;
+ stream << " if (!IS_SET(i, ctx->initialized_data)) {" << std::endl;
+ stream << " if unlikely(scxml_states[i].data != NULL && ctx->exec_content_init != NULL) {" << std::endl;
+ stream << " ctx->exec_content_init(ctx, scxml_states[i].data);" << std::endl;
+ stream << " }" << std::endl;
+ stream << " SET_BIT(i, ctx->initialized_data);" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << " if (scxml_states[i].on_entry != NULL) {" << std::endl;
+ stream << " if unlikely((err = scxml_states[i].on_entry(ctx, &scxml_states[i], event)) != SCXML_ERR_OK)" << std::endl;
+ stream << " return err;" << 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;
+ stream << " if unlikely(scxml_states[i].ancestors[0] == 0x01) {" << std::endl;
+ stream << " ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL;" << std::endl;
+ stream << " } else {" << std::endl;
+ stream << " // raise done event" << std::endl;
+ stream << " size_t parent = 0;" << std::endl;
+ stream << " for (int j = SCXML_NUMBER_STATES - 1; j >= 0; j--) {" << std::endl;
+ stream << " // we could trade runtime for memory here by saving the parent index" << std::endl;
+ stream << " if unlikely(IS_SET(j, scxml_states[i].ancestors)) {" << std::endl;
+ stream << " parent = j;" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " // is this raised for toplevel final as well?" << std::endl;
+ if (_hasDoneData) {
+ 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[parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl;
+ } else {
+ stream << " ctx->raise_done_event(ctx, &scxml_states[parent], NULL);" << std::endl;
+ }
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << " /**" << std::endl;
+ stream << " * are we the last final state to leave a parallel state?:" << std::endl;
+ stream << " * 1. Gather all parallel states in our ancestor chain" << std::endl;
+ stream << " * 2. Find all states for which these parallels are ancestors" << std::endl;
+ 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 << " 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 << " 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;
+ stream << " } else {" << std::endl;
+ stream << " SET_BIT(k, parallel_children);" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " if unlikely(!bit_any_set(parallel_children, " << _stateCharArraySize << ")) {" << std::endl;
+ stream << " ctx->raise_done_event(ctx, &scxml_states[parallel], NULL);" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+ stream << "// HISTORY_TRANSITIONS:" << std::endl;
+ stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl;
+ stream << " if unlikely(IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY)) {" << std::endl;
+ stream << " // call executable content in transition" << std::endl;
+ stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl;
+ stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl;
+ stream << " &scxml_states[scxml_transitions[i].source]," << std::endl;
+ stream << " event)) != SCXML_ERR_OK)" << std::endl;
+ stream << " return err;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << " }" << std::endl;
+ stream << std::endl;
+
+
+ stream << " return SCXML_ERR_OK;" << std::endl;
+ stream << "}" << std::endl;
+ stream << std::endl;
}
NodeSet<std::string> ChartToC::inPostFixOrder(const std::set<std::string>& elements, const Element<std::string>& root) {
- NodeSet<std::string> nodes;
- inPostFixOrder(elements, root, nodes);
- return nodes;
+ NodeSet<std::string> nodes;
+ inPostFixOrder(elements, root, nodes);
+ return nodes;
}
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++) {
- 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++) {
- if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- Arabica::DOM::Element<std::string> childElem(children.item(i));
-
- if (elements.find(TAGNAME(childElem)) != elements.end()) {
- nodes.push_back(childElem);
- }
- }
+ NodeList<std::string> children = root.getChildNodes();
+ for (int 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++) {
+ if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ Arabica::DOM::Element<std::string> childElem(children.item(i));
+
+ if (elements.find(TAGNAME(childElem)) != elements.end()) {
+ nodes.push_back(childElem);
+ }
+ }
}
NodeSet<std::string> ChartToC::inDocumentOrder(const std::set<std::string>& elements, const Element<std::string>& root) {
- NodeSet<std::string> nodes;
- inDocumentOrder(elements, root, nodes);
- return nodes;
+ NodeSet<std::string> nodes;
+ inDocumentOrder(elements, root, nodes);
+ return nodes;
}
void ChartToC::inDocumentOrder(const std::set<std::string>& elements, const Element<std::string>& root, NodeSet<std::string>& nodes) {
- if (elements.find(TAGNAME(root)) != elements.end()) {
- nodes.push_back(root);
- }
-
- NodeList<std::string> children = root.getChildNodes();
- for (int 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));
- inDocumentOrder(elements, childElem, nodes);
- }
+ if (elements.find(TAGNAME(root)) != elements.end()) {
+ nodes.push_back(root);
+ }
+
+ NodeList<std::string> children = root.getChildNodes();
+ for (int 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));
+ inDocumentOrder(elements, childElem, nodes);
+ }
}
ChartToC::~ChartToC() {
}
-
+
} \ No newline at end of file
diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h
index 0ee0d3c..6e6bac0 100644
--- a/src/uscxml/transform/ChartToC.h
+++ b/src/uscxml/transform/ChartToC.h
@@ -34,57 +34,57 @@ namespace uscxml {
class USCXML_API ChartToC : public InterpreterRC, public TransformerImpl {
public:
-
- virtual ~ChartToC();
- static Transformer transform(const Interpreter& other);
-
- void writeTo(std::ostream& stream);
-
- static Arabica::XPath::NodeSet<std::string> inPostFixOrder(const std::set<std::string>& elements,
- const Arabica::DOM::Element<std::string>& root);
- static Arabica::XPath::NodeSet<std::string> inDocumentOrder(const std::set<std::string>& elements,
- const Arabica::DOM::Element<std::string>& root);
+
+ virtual ~ChartToC();
+ static Transformer transform(const Interpreter& other);
+
+ void writeTo(std::ostream& stream);
+
+ static Arabica::XPath::NodeSet<std::string> inPostFixOrder(const std::set<std::string>& elements,
+ const Arabica::DOM::Element<std::string>& root);
+ static Arabica::XPath::NodeSet<std::string> inDocumentOrder(const std::set<std::string>& elements,
+ const Arabica::DOM::Element<std::string>& root);
protected:
- ChartToC(const Interpreter& other);
-
- static void inPostFixOrder(const std::set<std::string>& elements,
- const Arabica::DOM::Element<std::string>& root,
- Arabica::XPath::NodeSet<std::string>& nodes);
-
- static void inDocumentOrder(const std::set<std::string>& elements,
- const Arabica::DOM::Element<std::string>& root,
- Arabica::XPath::NodeSet<std::string>& nodes);
-
- void writeIncludes(std::ostream& stream);
- void writeMacros(std::ostream& stream);
- void writeTypes(std::ostream& stream);
- void writeHelpers(std::ostream& stream);
- void writeExecContent(std::ostream& stream);
- void writeElementInfo(std::ostream& stream);
-
- void writeStates(std::ostream& stream);
- void writeTransitions(std::ostream& stream);
- void writeFSM(std::ostream& stream);
- void writeCharArrayInitList(std::ostream& stream, const std::string& boolString);
-
- void writeExecContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0);
-
- Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::DOM::Element<std::string>& transition);
-
- Interpreter interpreter;
-
- Arabica::XPath::NodeSet<std::string> _states;
- std::map<std::string, Arabica::DOM::Element<std::string> > _stateNames;
- Arabica::XPath::NodeSet<std::string> _transitions;
-
- bool _hasGlobalScripts;
- bool _hasDoneData;
-
- size_t _transCharArraySize;
- std::string _transCharArrayInit;
-
- size_t _stateCharArraySize;
- std::string _stateCharArrayInit;
+ ChartToC(const Interpreter& other);
+
+ static void inPostFixOrder(const std::set<std::string>& elements,
+ const Arabica::DOM::Element<std::string>& root,
+ Arabica::XPath::NodeSet<std::string>& nodes);
+
+ static void inDocumentOrder(const std::set<std::string>& elements,
+ const Arabica::DOM::Element<std::string>& root,
+ Arabica::XPath::NodeSet<std::string>& nodes);
+
+ void writeIncludes(std::ostream& stream);
+ void writeMacros(std::ostream& stream);
+ void writeTypes(std::ostream& stream);
+ void writeHelpers(std::ostream& stream);
+ void writeExecContent(std::ostream& stream);
+ void writeElementInfo(std::ostream& stream);
+
+ void writeStates(std::ostream& stream);
+ void writeTransitions(std::ostream& stream);
+ void writeFSM(std::ostream& stream);
+ void writeCharArrayInitList(std::ostream& stream, const std::string& boolString);
+
+ void writeExecContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0);
+
+ Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::DOM::Element<std::string>& transition);
+
+ Interpreter interpreter;
+
+ Arabica::XPath::NodeSet<std::string> _states;
+ std::map<std::string, Arabica::DOM::Element<std::string> > _stateNames;
+ Arabica::XPath::NodeSet<std::string> _transitions;
+
+ bool _hasGlobalScripts;
+ bool _hasDoneData;
+
+ size_t _transCharArraySize;
+ std::string _transCharArrayInit;
+
+ size_t _stateCharArraySize;
+ std::string _stateCharArrayInit;
};
}
diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp
index d55ef24..b78a2dd 100644
--- a/src/uscxml/transform/ChartToFSM.cpp
+++ b/src/uscxml/transform/ChartToFSM.cpp
@@ -97,7 +97,7 @@ std::cerr << ")";
ChartToFSM::ChartToFSM(const Interpreter& other) {
cloneFrom(other.getImpl());
-
+
_transitionsFromTree = true;
_keepInvalidTransitions = false;
_lastTimeStamp = tthread::chrono::system_clock::now();
@@ -116,20 +116,20 @@ ChartToFSM::ChartToFSM(const Interpreter& other) {
if (envVarIEquals("USCXML_TRANSFORM_TRANS_FROM", "powerset"))
_transitionsFromTree = false;
-
+
_start = NULL;
_currGlobalTransition = NULL;
_transTree = NULL;
-
+
_lastStateIndex = 0;
_lastActiveIndex = 0;
_lastTransIndex = 0;
-
+
_maxEventSentChain = 0;
_maxEventRaisedChain = 0;
_doneEventRaiseTolerance = 0;
_skipEventChainCalculations = false;
-
+
addMonitor(this);
}
@@ -144,7 +144,7 @@ ChartToFSM::~ChartToFSM() {
delete confIter->second;
confIter++;
}
-
+
// tear down caches
Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
for (int i = 0; i < allTransitions.size(); i++) {
@@ -180,7 +180,7 @@ InterpreterState ChartToFSM::interpret() {
}
std::map<size_t, size_t> histoGramm = Complexity::getTransitionHistogramm(_scxml);
// abort();
-
+
uint64_t complexity = Complexity::stateMachineComplexity(this) + 1;
std::cerr << "Approximate Complexity: " << complexity << std::endl;
std::cerr << "Approximate Active Complexity: " << Complexity::stateMachineComplexity(this, Complexity::IGNORE_HISTORY | Complexity::IGNORE_NESTED_DATA) + 1 << std::endl;
@@ -224,7 +224,7 @@ InterpreterState ChartToFSM::interpret() {
for (int i = 0; i < histories.size(); i++) {
_historyTargets[ATTR_CAST(histories[i], "id")] = Element<std::string>(histories[i]);
}
-
+
_binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY);
_alreadyFlat = (HAS_ATTR(_scxml, "flat") && stringIsTrue(ATTR(_scxml, "flat")));
@@ -232,7 +232,7 @@ InterpreterState ChartToFSM::interpret() {
reassembleFromFlat();
return _state;
}
-
+
// set invokeid for all invokers to parent state if none given
NodeSet<std::string> invokers = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true);
for (int i = 0; i < invokers.size(); i++) {
@@ -265,14 +265,14 @@ InterpreterState ChartToFSM::interpret() {
_scxml.appendChild(initialElem);
initialTransitions.push_back(transitionElem);
}
-
+
if (!_skipEventChainCalculations)
annotateRaiseAndSend(_scxml);
-
+
// std::cout << _scxml << std::endl;
-
+
indexTransitions();
-
+
// add initial transitions as least prior
for (int i = 0; i < initialTransitions.size() ; i++) {
indexedTransitions.push_back(Element<std::string>(initialTransitions[i]));
@@ -293,7 +293,7 @@ InterpreterState ChartToFSM::interpret() {
// gather and set index attribute o states
NodeSet<std::string> allStates = getAllStates();
allStates.to_document_order();
-
+
indexedStates.resize(allStates.size());
for (int i = 0; i < allStates.size(); i++) {
Element<std::string> state = Element<std::string>(allStates[i]);
@@ -309,9 +309,9 @@ InterpreterState ChartToFSM::interpret() {
// std::cerr << _scxml << std::endl;
- // create a _flatDoc for the FSM
- DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- _flatDoc = domFactory.createDocument(_document.getNamespaceURI(), "", 0);
+ // create a _flatDoc for the FSM
+ DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ _flatDoc = domFactory.createDocument(_document.getNamespaceURI(), "", 0);
GlobalTransition* globalTransition = new GlobalTransition(initialTransitions, _dataModel, this);
globalTransition->index = _lastTransIndex++;
@@ -323,7 +323,7 @@ InterpreterState ChartToFSM::interpret() {
enterStates(initialTransitions);
globalTransition->destination = FlatStateIdentifier::toStateId(_configuration);
globalTransition->activeDestination = globalTransition->destination;
-
+
explode();
DUMP_STATS(0, true);
@@ -363,7 +363,7 @@ void ChartToFSM::executeContent(const Arabica::DOM::Element<std::string>& conten
}
}
return;
-
+
HAS_VALID_CHILDREN:
if (false) {
} else if (TAGNAME(content) == "transition") {
@@ -379,21 +379,21 @@ HAS_VALID_CHILDREN:
}
if (!_skipEventChainCalculations &&
- (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) {
+ (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) {
assert(content.hasAttribute("raise") && content.hasAttribute("send"));
std::string raiseAttr = content.getAttribute("raise");
std::string sendAttr = content.getAttribute("send");
-
+
_currGlobalTransition->eventsRaised = (raiseAttr == "-1" ? UNDECIDABLE : _currGlobalTransition->eventsRaised + strTo<uint32_t>(raiseAttr));
_currGlobalTransition->eventsSent = (sendAttr == "-1" ? UNDECIDABLE : _currGlobalTransition->eventsSent + strTo<uint32_t>(sendAttr));
-
+
if (_currGlobalTransition->eventsRaised > _maxEventRaisedChain)
_maxEventRaisedChain = _currGlobalTransition->eventsRaised;
if (_currGlobalTransition->eventsSent > _maxEventSentChain)
_maxEventSentChain = _currGlobalTransition->eventsSent;
}
-
+
_currGlobalTransition->actions.push_back(action);
_currGlobalTransition->hasExecutableContent = true;
}
@@ -434,19 +434,19 @@ void ChartToFSM::internalDoneSend(const Arabica::DOM::Element<std::string>& stat
onentry.appendChild(raise);
- if (doneData) {
- Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneData);
- if (contents.size() > 0) {
- Node<std::string> imported = _flatDoc.importNode(contents[0], true);
- raise.appendChild(imported);
- }
- Arabica::XPath::NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", doneData);
- if (params.size() > 0) {
- Node<std::string> imported = _flatDoc.importNode(params[0], true);
- raise.appendChild(imported);
- }
- }
-
+ if (doneData) {
+ Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneData);
+ if (contents.size() > 0) {
+ Node<std::string> imported = _flatDoc.importNode(contents[0], true);
+ raise.appendChild(imported);
+ }
+ Arabica::XPath::NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", doneData);
+ if (params.size() > 0) {
+ Node<std::string> imported = _flatDoc.importNode(params[0], true);
+ raise.appendChild(imported);
+ }
+ }
+
raise.setAttribute("event", "done.state." + ATTR_CAST(state, "id")); // parent?!
@@ -455,7 +455,7 @@ void ChartToFSM::internalDoneSend(const Arabica::DOM::Element<std::string>& stat
_currGlobalTransition->actions.push_back(action);
if (!_skipEventChainCalculations &&
- (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE))
+ (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE))
_currGlobalTransition->eventsRaised++;
_currGlobalTransition->hasExecutableContent = true;
@@ -463,13 +463,13 @@ void ChartToFSM::internalDoneSend(const Arabica::DOM::Element<std::string>& stat
static bool isSuperset(const GlobalTransition* t1, const GlobalTransition* t2) {
bool isSuperset = true;
-
+
if (t1->transitionRefs.size() >= t2->transitionRefs.size())
return false;
-
+
NodeSet<std::string> t1Trans = t1->getTransitions();
NodeSet<std::string> t2Trans = t2->getTransitions();
-
+
for (int i = 0; i < t1Trans.size(); i++) {
if (!InterpreterImpl::isMember(t1Trans[i], t2Trans)) {
isSuperset = false;
@@ -515,7 +515,7 @@ static bool filterSameHierarchy(const NodeSet<std::string>& transitions) {
return true;
}
-
+
static bool filterChildEnabled(const NodeSet<std::string>& transitions) {
// drop any transition that is already enabled by a child
NodeSet<std::string> filteredTransitions;
@@ -548,7 +548,7 @@ static bool filterChildEnabled(const NodeSet<std::string>& transitions) {
bool ChartToFSM::hasForeachInBetween(const Arabica::DOM::Node<std::string>& ancestor, const Arabica::DOM::Node<std::string>& child) {
if (!ancestor || !child)
return false;
-
+
Node<std::string> currChild = child;
while(currChild != ancestor) {
if (!currChild.getParentNode())
@@ -580,8 +580,8 @@ void ChartToFSM::annotateRaiseAndSend(const Arabica::DOM::Element<std::string>&
}
execContentElem.setAttribute("raise", toStr(nrRaise));
- DONE_COUNT_RAISE:
-
+DONE_COUNT_RAISE:
+
int nrSend = 0;
NodeSet<std::string> sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", execContent[i], true);
for (int j = 0; j < sends.size(); j++) {
@@ -594,151 +594,151 @@ void ChartToFSM::annotateRaiseAndSend(const Arabica::DOM::Element<std::string>&
}
execContentElem.setAttribute("send", toStr(nrSend));
- DONE_COUNT_SEND:
+DONE_COUNT_SEND:
;
}
}
void ChartToFSM::annotateDomain() {
- Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
- for (int i = 0; i < allTransitions.size(); i++) {
- Element<std::string> transition(allTransitions[i]);
- Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
- if (domain) {
- transition.setAttribute("domain", (HAS_ATTR_CAST(domain, "id") ? ATTR_CAST(domain, "id") : DOMUtils::xPathForNode(domain)));
- } else {
- transition.setAttribute("domain", "#UNDEF");
- }
- }
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> transition(allTransitions[i]);
+ Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
+ if (domain) {
+ transition.setAttribute("domain", (HAS_ATTR_CAST(domain, "id") ? ATTR_CAST(domain, "id") : DOMUtils::xPathForNode(domain)));
+ } else {
+ transition.setAttribute("domain", "#UNDEF");
+ }
+ }
}
-
+
void ChartToFSM::annotateExitSet() {
- Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
- for (int i = 0; i < allTransitions.size(); i++) {
- Element<std::string> transition(allTransitions[i]);
- Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
-
- Arabica::XPath::NodeSet<std::string> allStates = getAllStates();
- std::ostringstream exitSetStr;
- std::string seperator = "";
- for (int j = 0; j < allStates.size(); j++) {
- Element<std::string> state(allStates[j]);
- if (state.getParentNode() == domain) {
- exitSetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
- seperator = ", ";
- }
- }
- transition.setAttribute("exitset", exitSetStr.str());
- }
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> transition(allTransitions[i]);
+ Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
+
+ Arabica::XPath::NodeSet<std::string> allStates = getAllStates();
+ std::ostringstream exitSetStr;
+ std::string seperator = "";
+ for (int j = 0; j < allStates.size(); j++) {
+ Element<std::string> state(allStates[j]);
+ if (state.getParentNode() == domain) {
+ exitSetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
+ seperator = ", ";
+ }
+ }
+ transition.setAttribute("exitset", exitSetStr.str());
+ }
}
-
+
void ChartToFSM::annotateEntrySet() {
- Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
- for (int i = 0; i < allTransitions.size(); i++) {
- Element<std::string> transition(allTransitions[i]);
-
- NodeSet<std::string> tmpTransitions;
- NodeSet<std::string> tmpStatesToEnter;
- NodeSet<std::string> tmpStatesForDefaultEntry;
- std::map<std::string, Arabica::DOM::Node<std::string> > tmpDefaultHistoryContent;
-
- tmpTransitions.push_back(transition);
- computeEntrySet(tmpTransitions, tmpStatesToEnter, tmpStatesForDefaultEntry, tmpDefaultHistoryContent);
-
- std::ostringstream entrySetStr;
- std::string seperator = "";
-
- for (int j = 0; j < tmpStatesToEnter.size(); j++) {
- Element<std::string> state(tmpStatesToEnter[j]);
- entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
- seperator = ", ";
- }
- for (int j = 0; j < tmpStatesForDefaultEntry.size(); j++) {
- Element<std::string> state(tmpStatesForDefaultEntry[j]);
- entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
- seperator = ", ";
- }
- transition.setAttribute("entryset", entrySetStr.str());
-
- }
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> transition(allTransitions[i]);
+
+ NodeSet<std::string> tmpTransitions;
+ NodeSet<std::string> tmpStatesToEnter;
+ NodeSet<std::string> tmpStatesForDefaultEntry;
+ std::map<std::string, Arabica::DOM::Node<std::string> > tmpDefaultHistoryContent;
+
+ tmpTransitions.push_back(transition);
+ computeEntrySet(tmpTransitions, tmpStatesToEnter, tmpStatesForDefaultEntry, tmpDefaultHistoryContent);
+
+ std::ostringstream entrySetStr;
+ std::string seperator = "";
+
+ for (int j = 0; j < tmpStatesToEnter.size(); j++) {
+ Element<std::string> state(tmpStatesToEnter[j]);
+ entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
+ seperator = ", ";
+ }
+ for (int j = 0; j < tmpStatesForDefaultEntry.size(); j++) {
+ Element<std::string> state(tmpStatesForDefaultEntry[j]);
+ entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
+ seperator = ", ";
+ }
+ transition.setAttribute("entryset", entrySetStr.str());
+
+ }
}
void ChartToFSM::annotateConflicts() {
- Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
- Arabica::XPath::NodeSet<std::string> allStates = getAllStates();
-
- for (int i = 0; i < allTransitions.size(); i++) {
- Element<std::string> t1(allTransitions[i]);
- if (!isState(Element<std::string>(t1.getParentNode())))
- continue;
-
- Arabica::DOM::Node<std::string> d1 = getTransitionDomain(t1);
-
- Arabica::XPath::NodeSet<std::string> exitSet1;
- for (int k = 0; k < allStates.size(); k++) {
- Element<std::string> state(allStates[k]);
- if (isDescendant(state, d1)) {
- exitSet1.push_back(state);
- }
- }
-
- std::ostringstream preemptionStr;
- std::string seperator = "";
-
- for (int j = 0; j < allTransitions.size(); j++) {
- if ( i == j)
- continue;
-
- Element<std::string> t2(allTransitions[j]);
- if (!isState(Element<std::string>(t2.getParentNode())))
- continue;
-
- Arabica::DOM::Node<std::string> d2 = getTransitionDomain(t2);
-
- Arabica::XPath::NodeSet<std::string> exitSet2;
- for (int k = 0; k < allStates.size(); k++) {
- Element<std::string> state(allStates[k]);
- if (isDescendant(state, d2)) {
- exitSet2.push_back(state);
- }
- }
-
- if (hasIntersection(exitSet1, exitSet2)) {
- preemptionStr << seperator << (HAS_ATTR(t2, "priority") ? ATTR(t2, "priority") : DOMUtils::xPathForNode(t2));
- seperator = ", ";
- }
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ Arabica::XPath::NodeSet<std::string> allStates = getAllStates();
+
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> t1(allTransitions[i]);
+ if (!isState(Element<std::string>(t1.getParentNode())))
+ continue;
+
+ Arabica::DOM::Node<std::string> d1 = getTransitionDomain(t1);
+
+ Arabica::XPath::NodeSet<std::string> exitSet1;
+ for (int k = 0; k < allStates.size(); k++) {
+ Element<std::string> state(allStates[k]);
+ if (isDescendant(state, d1)) {
+ exitSet1.push_back(state);
+ }
+ }
+
+ std::ostringstream preemptionStr;
+ std::string seperator = "";
+
+ for (int j = 0; j < allTransitions.size(); j++) {
+ if ( i == j)
+ continue;
+
+ Element<std::string> t2(allTransitions[j]);
+ if (!isState(Element<std::string>(t2.getParentNode())))
+ continue;
+
+ Arabica::DOM::Node<std::string> d2 = getTransitionDomain(t2);
+
+ Arabica::XPath::NodeSet<std::string> exitSet2;
+ for (int k = 0; k < allStates.size(); k++) {
+ Element<std::string> state(allStates[k]);
+ if (isDescendant(state, d2)) {
+ exitSet2.push_back(state);
+ }
+ }
+
+ if (hasIntersection(exitSet1, exitSet2)) {
+ preemptionStr << seperator << (HAS_ATTR(t2, "priority") ? ATTR(t2, "priority") : DOMUtils::xPathForNode(t2));
+ seperator = ", ";
+ }
// if (isDescendant(d1, d2) || isDescendant(d2, d1) || d1 == d2) {
// preemptionStr << seperator << ATTR(t2, "priority");
// seperator = ", ";
// }
- }
- if (preemptionStr.str().size() > 0)
- t1.setAttribute("conflicts", preemptionStr.str());
+ }
+ if (preemptionStr.str().size() > 0)
+ t1.setAttribute("conflicts", preemptionStr.str());
- }
+ }
}
void ChartToFSM::indexTransitions() {
- indexedTransitions.clear();
- indexTransitions(_scxml);
-
+ indexedTransitions.clear();
+ indexTransitions(_scxml);
+
#if 1
- size_t index = indexedTransitions.size() - 1;
- for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
- transIter->setAttribute("priority", toStr(index));
- index--;
- }
+ size_t index = indexedTransitions.size() - 1;
+ for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
+ transIter->setAttribute("priority", toStr(index));
+ index--;
+ }
#else
- size_t index = 0;
- for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
- transIter->setAttribute("priority", toStr(index));
- index++;
- }
+ size_t index = 0;
+ for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
+ transIter->setAttribute("priority", toStr(index));
+ index++;
+ }
#endif
- // reverse indices for most prior to be in front
- //std::reverse(indexedTransitions.begin(), indexedTransitions.end());
+ // reverse indices for most prior to be in front
+ //std::reverse(indexedTransitions.begin(), indexedTransitions.end());
}
#if 0
@@ -757,30 +757,30 @@ void ChartToFSM::indexTransitions(const Arabica::DOM::Element<std::string>& root
indexTransitions(stateElem);
}
}
-
+
#else
-
+
void ChartToFSM::indexTransitions(const Arabica::DOM::Element<std::string>& root) {
- // Post-order traversal of transitions
- Arabica::XPath::NodeSet<std::string> childStates = getChildStates(root);
- for (int i = 0; i < childStates.size(); i++) {
- Element<std::string> childElem(childStates[i]);
- indexTransitions(childElem);
- }
-
- Arabica::XPath::NodeSet<std::string> levelTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", root);
- for (int i = 0; i < levelTransitions.size(); i++) {
- // push into index starting with least prior
- indexedTransitions.push_back(Element<std::string>(levelTransitions[i]));
- }
+ // Post-order traversal of transitions
+ Arabica::XPath::NodeSet<std::string> childStates = getChildStates(root);
+ for (int i = 0; i < childStates.size(); i++) {
+ Element<std::string> childElem(childStates[i]);
+ indexTransitions(childElem);
+ }
+
+ Arabica::XPath::NodeSet<std::string> levelTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", root);
+ for (int i = 0; i < levelTransitions.size(); i++) {
+ // push into index starting with least prior
+ indexedTransitions.push_back(Element<std::string>(levelTransitions[i]));
+ }
}
-
+
#endif
bool GlobalTransition::operator< (const GlobalTransition& other) const {
const std::vector<Arabica::DOM::Element<std::string> >& indexedTransitions = interpreter->indexedTransitions;
NodeSet<std::string> transitions = getTransitions();
-
+
for (std::vector<Element<std::string> >::const_iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
const Element<std::string>& refTrans = *transIter;
NodeSet<std::string> otherTransitions = other.getTransitions();
@@ -807,10 +807,10 @@ bool hasUnconditionalSuperset(GlobalTransition* first, GlobalTransition* second)
NodeSet<std::string> firstTransitions = first->getTransitions();
NodeSet<std::string> secondTransitions = second->getTransitions();
-
+
// if (first->condition.size() > 0)
// return false;
-
+
if (isSuperset(second, first)) {
for (int i = 0; i < firstTransitions.size(); i++) {
if (!InterpreterImpl::isMember(firstTransitions[i], secondTransitions)) {
@@ -839,11 +839,11 @@ std::list<GlobalTransition*> redundantRemove(std::list<GlobalTransition*> list)
#if 1
std::list<GlobalTransition*>::iterator outerIter;
std::list<GlobalTransition*>::iterator innerIter;
-
+
outerIter = list.begin();
while(outerIter != list.end()) {
innerIter = outerIter;
-
+
while(innerIter != list.end()) {
if (innerIter == outerIter) {
innerIter++;
@@ -866,25 +866,25 @@ std::list<GlobalTransition*> redundantRemove(std::list<GlobalTransition*> list)
}
innerIter++;
}
-
+
outerIter++;
}
-
+
#else
for (std::list<GlobalTransition*>::iterator outerIter = list.begin();
- outerIter != list.end();
- outerIter++) {
+ outerIter != list.end();
+ outerIter++) {
for (std::list<GlobalTransition*>::iterator innerIter = outerIter;
- innerIter != list.end();
- innerIter++) {
-
+ innerIter != list.end();
+ innerIter++) {
+
if (innerIter == outerIter)
continue;
-
+
GlobalTransition* t1 = *outerIter;
GlobalTransition* t2 = *innerIter;
-
+
if (hasUnconditionalSuperset(t1, t2)) {
innerIter = list.erase(innerIter);
continue;
@@ -906,20 +906,20 @@ std::list<GlobalTransition*> redundantMark(std::list<GlobalTransition*> list) {
#if 1
std::list<GlobalTransition*>::iterator outerIter;
std::list<GlobalTransition*>::iterator innerIter;
-
+
outerIter = list.begin();
while(outerIter != list.end()) {
innerIter = outerIter;
-
+
while(innerIter != list.end()) {
if (innerIter == outerIter) {
innerIter++;
continue;
}
-
+
GlobalTransition* t1 = *outerIter;
GlobalTransition* t2 = *innerIter;
-
+
if (!t1->isValid || !t2->isValid) {
innerIter++;
continue;
@@ -947,28 +947,28 @@ std::list<GlobalTransition*> redundantMark(std::list<GlobalTransition*> list) {
}
innerIter++;
}
-
+
outerIter++;
}
-
+
#else
for (std::list<GlobalTransition*>::iterator outerIter = list.begin();
- outerIter != list.end();
- outerIter++) {
+ outerIter != list.end();
+ outerIter++) {
for (std::list<GlobalTransition*>::iterator innerIter = outerIter;
- innerIter != list.end();
- innerIter++) {
-
+ innerIter != list.end();
+ innerIter++) {
+
if (innerIter == outerIter)
continue;
-
+
GlobalTransition* t1 = *outerIter;
GlobalTransition* t2 = *innerIter;
-
+
if (!t1->isValid || !t2->isValid)
continue;
-
+
if (hasUnconditionalSuperset(t1, t2)) {
t2->isValid = false;
t2->invalidMsg = "Unconditional superset";
@@ -992,7 +992,7 @@ std::list<GlobalTransition*> redundantMark(std::list<GlobalTransition*> list) {
return list;
}
-
+
void TransitionTreeNode::dump(int indent) {
std::string padding;
for (int i = 0; i + 1 < indent; i++) {
@@ -1000,23 +1000,27 @@ void TransitionTreeNode::dump(int indent) {
}
if (indent > 0)
padding += "|-";
-
+
std::string typeString;
switch (type) {
- case TYPE_NESTED:
- typeString = "NESTED"; break;
- case TYPE_PARALLEL:
- typeString = "PARALLEL"; break;
- case TYPE_TRANSITION:
- typeString = "TRANSITION"; break;
- case TYPE_UNDEFINED:
- typeString = "UNDEFINED"; break;
- break;
- default:
- break;
+ case TYPE_NESTED:
+ typeString = "NESTED";
+ break;
+ case TYPE_PARALLEL:
+ typeString = "PARALLEL";
+ break;
+ case TYPE_TRANSITION:
+ typeString = "TRANSITION";
+ break;
+ case TYPE_UNDEFINED:
+ typeString = "UNDEFINED";
+ break;
+ break;
+ default:
+ break;
}
-
+
if (transition) {
std::cerr << padding << "t" << ATTR(transition, "index") << " " << typeString << ": ";
// std::cerr << (prevTransition != NULL ? " (" + prevTransition->nodeId + ") <-" : "");
@@ -1028,7 +1032,7 @@ void TransitionTreeNode::dump(int indent) {
// std::cerr << (firstTransition != NULL ? " -> " + firstTransition->nodeId : "");
std::cerr << std::endl;
}
-
+
for (std::list<TransitionTreeNode*>::iterator childIter = children.begin(); childIter != children.end(); childIter++) {
(*childIter)->dump(indent + 1);
}
@@ -1047,27 +1051,27 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
// recursion start
std::set<TransitionTreeNode*> transLeafs;
- for (int i = 0; i < conf.size(); i++) {
- DUMP_STATS(conf.size(), false);
-
- Element<std::string> confElem(conf[i]);
- assert(_stateToTransTreeNode.find(confElem) != _stateToTransTreeNode.end());
- TransitionTreeNode* node = _stateToTransTreeNode[confElem];
- if (node->firstState == NULL) { // a leaf - ignore intermediates
- // ascend to the first parent with transitions but stop at parallel nodes
- while(node != NULL && node->firstTransition == NULL) {
- if (node->parent && node->parent->type == TransitionTreeNode::TYPE_PARALLEL)
- break;
- node = node->parent;
- }
- if (node != NULL) {
- transLeafs.insert(node);
- } else {
- //std::cerr << ATTR(confElem, "id") << " does not cause transitions" << std::endl;
- }
+ for (int i = 0; i < conf.size(); i++) {
+ DUMP_STATS(conf.size(), false);
+
+ Element<std::string> confElem(conf[i]);
+ assert(_stateToTransTreeNode.find(confElem) != _stateToTransTreeNode.end());
+ TransitionTreeNode* node = _stateToTransTreeNode[confElem];
+ if (node->firstState == NULL) { // a leaf - ignore intermediates
+ // ascend to the first parent with transitions but stop at parallel nodes
+ while(node != NULL && node->firstTransition == NULL) {
+ if (node->parent && node->parent->type == TransitionTreeNode::TYPE_PARALLEL)
+ break;
+ node = node->parent;
+ }
+ if (node != NULL) {
+ transLeafs.insert(node);
+ } else {
+ //std::cerr << ATTR(confElem, "id") << " does not cause transitions" << std::endl;
}
}
-
+ }
+
std::list<std::set<TransitionTreeNode*> > stack;
stack.push_back(transLeafs); // push follow-up configurations onto stack
@@ -1075,7 +1079,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
// pop from front of stack
std::set<TransitionTreeNode*> stateList = stack.front();
stack.pop_front();
-
+
DUMP_STATS(conf.size(), false);
#if 0
@@ -1087,40 +1091,40 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
}
std::cerr << std::endl;
#endif
-
+
/*
* TransNodes contains a set of lists of transitions.
- * In the inner stack we build every possible combination
+ * In the inner stack we build every possible combination
* of picking at-most one from each list.
*/
-
+
/* create global transitions for every n-tuple in current set of lists */
std::list<std::pair<std::set<TransitionTreeNode*>, std::set<TransitionTreeNode*> > > innerStack;
innerStack.push_back(std::make_pair(std::set<TransitionTreeNode*>(), stateList));
-
+
while(innerStack.size() > 0) {
// picking at-most one from each list
std::set<TransitionTreeNode*> remainingStates = innerStack.front().second;
std::set<TransitionTreeNode*> fixedTransitions = innerStack.front().first;
innerStack.pop_front();
-
+
if (remainingStates.size() > 0) {
// iterate for each first element fixed
TransitionTreeNode* firstRemainingState = *remainingStates.begin();
remainingStates.erase(remainingStates.begin());
-
+
if (firstRemainingState->firstTransition == NULL) {
// no transitions at this state - reenqueue with NULL selection from this
innerStack.push_back(std::make_pair(fixedTransitions, remainingStates));
continue;
}
-
+
TransitionTreeNode* currTrans = firstRemainingState->firstTransition;
-
+
// choose none from firstList
innerStack.push_back(std::make_pair(fixedTransitions, remainingStates));
-
+
while(currTrans != NULL) {
std::set<TransitionTreeNode*> fixedAndThis(fixedTransitions);
fixedAndThis.insert(currTrans);
@@ -1136,7 +1140,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
_perfTransProcessed++;
NodeSet<std::string> fixed;
-
+
#if 0
seperator = "";
for (std::set<TransitionTreeNode*>::iterator itemIter = fixedTransitions.begin(); itemIter != fixedTransitions.end(); itemIter++) {
@@ -1146,7 +1150,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
}
std::cerr << " ## ";
#endif
-
+
seperator = "";
for (std::set<TransitionTreeNode*>::iterator itemIter = fixedTransitions.begin(); itemIter != fixedTransitions.end(); itemIter++) {
TransitionTreeNode* currItem = *itemIter;
@@ -1165,7 +1169,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
// std::cerr << " - PREEMPTS" << std::endl;
continue;
}
-
+
GlobalTransition* transition = new GlobalTransition(fixed, _dataModel, this);
transition->index = _lastTransIndex++;
@@ -1176,7 +1180,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
// std::cerr << " - INVALID" << std::endl;
continue;
}
-
+
_perfTransUsed++;
outMap[transition->transitionId] = transition;
@@ -1184,31 +1188,31 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No
}
}
}
-
+
// create new set of transition lists by moving to parent states
for (std::set<TransitionTreeNode*>::iterator stateIter = stateList.begin(); stateIter != stateList.end(); stateIter++) {
TransitionTreeNode* origState = *stateIter;
TransitionTreeNode* currState = origState;
TransitionTreeNode* parentState = currState->parent;
-
+
/**
* We ascend the current state via its parent and add the parent with transitions.
- * However, we break if we reached the top or if we passed a parallel state for
+ * However, we break if we reached the top or if we passed a parallel state for
* wich we are not the first child
*/
-
+
while(parentState != NULL) {
if (parentState->type == TransitionTreeNode::TYPE_PARALLEL && parentState->firstState != currState) {
// the first child of the parallel state will continue this transition - we made sure to keep them
break;
}
-
+
if (parentState->firstTransition != NULL) {
// std::cerr << "#### Adding new parent lists for " << origState->nodeId << std::endl;
-
+
std::set<TransitionTreeNode*> newStateList;
newStateList.insert(parentState);
-
+
// add all other states that are not a child of the parent state
for (std::set<TransitionTreeNode*>::iterator newlistIter = stateList.begin(); newlistIter != stateList.end(); newlistIter++) {
TransitionTreeNode* otherState = *newlistIter;
@@ -1234,7 +1238,7 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std::
TransitionTreeNode* stateNode = new TransitionTreeNode();
stateNode->nodeId = nodeId;
stateNode->state = root;
-
+
if (TAGNAME(root) == _nsInfo.xmlNSPrefix + "parallel") {
stateNode->type = TransitionTreeNode::TYPE_PARALLEL;
} else {
@@ -1250,7 +1254,7 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std::
nested.to_document_order();
TransitionTreeNode* lastNode = NULL;
-
+
for (int i = 0; i < nested.size(); i++) {
Element<std::string> nestedElem(nested[i]);
if (TAGNAME(nestedElem) == _nsInfo.xmlNSPrefix + "transition") {
@@ -1259,20 +1263,20 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std::
transNode->parent = stateNode;
transNode->nodeId = nodeId + "-" + toStr(i);
transNode->type = TransitionTreeNode::TYPE_TRANSITION;
-
+
if (stateNode->firstTransition == NULL) {
stateNode->firstTransition = transNode;
}
stateNode->children.push_back(transNode);
stateNode->lastTransition = transNode;
-
+
if (lastNode != NULL) {
lastNode->nextTransition = transNode;
transNode->prevTransition = lastNode;
}
lastNode = transNode;
-
-
+
+
} else {
TransitionTreeNode* deeperNode = buildTransTree(nestedElem, nodeId + "-" + toStr(i));
if (stateNode->firstState == NULL) {
@@ -1283,9 +1287,9 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std::
stateNode->children.push_back(deeperNode);
}
}
-
+
_stateToTransTreeNode[root] = stateNode;
-
+
return stateNode;
}
@@ -1301,42 +1305,42 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath
}
std::cerr << std::endl;
}
-
+
// if (true) {
// outMap = _confToTransitions[""];
// }
-
+
if (allTransitions.size() == 0)
return; // no transitions
-
+
int nrElements = allTransitions.size();
int k = 0;
int* stack = (int*)malloc((nrElements + 1) * sizeof(int));
memset(stack, 0, (nrElements + 1) * sizeof(int));
-
+
/**
* Powerset is too naive and takes too long!
- * We have it up to 500k checks/sec and still 2**30 is
+ * We have it up to 500k checks/sec and still 2**30 is
* 1G+ for 30minutes in a single state out of 50k+!
*/
-
+
while(1) {
// create the power set of all potential transitions - this is expensive!
// see: http://www.programminglogic.com/powerset-algorithm-in-c/
-
+
if (stack[k] < nrElements) {
stack[k+1] = stack[k] + 1;
k++;
}
-
+
else {
stack[k-1]++;
k--;
}
-
+
if (k==0)
break;
-
+
NodeSet<std::string> transitions;
// std::cerr << globalState->stateId << " [" << nrElements << "]: " << std::endl;
for (int i = 1; i <= k; i++) {
@@ -1344,27 +1348,27 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath
transitions.push_back(allTransitions[stack[i] - 1]);
}
// std::cerr << std::endl;
-
+
// transitions.push_back(allTransitions[0]);
// transitions.push_back(allTransitions[4]);
// transitions.push_back(allTransitions[5]);
// transitions.push_back(allTransitions[7]);
-
+
bool dump = false;
-
+
// if (k == 4 && stack[1] == 1 && stack[2] == 5 && stack[3] == 6 && stack[4] == 8) {
// dump = true;
// }
-
+
if (dump) DUMP_TRANSSET("at start");
-
+
_perfTransTotal++;
_perfTransProcessed++;
-
+
DUMP_STATS(nrElements, false);
-
+
GlobalTransition* transition = NULL;
-
+
// reduce to conflict-free subset
// transitions.to_document_order();
if (!_keepInvalidTransitions) {
@@ -1372,18 +1376,18 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath
if(!filterSameState(transitions))
continue;
if (dump) DUMP_TRANSSET("after same state filtered");
-
+
// remove those transitions with a child transition
// if(!filterChildEnabled(transitions))
if(!filterSameHierarchy(transitions))
continue;
if (dump) DUMP_TRANSSET("after child enabled filtered");
-
+
transitions = removeConflictingTransitions(transitions);
if (dump) DUMP_TRANSSET("after conflicting filtered");
// algorithm can never reduce to empty set
assert(transitions.size() > 0);
-
+
// create a GlobalTransition object from the set
transition = new GlobalTransition(transitions, _dataModel, this);
if (!transition->isValid) {
@@ -1393,13 +1397,13 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath
}
} else {
transition = new GlobalTransition(transitions, _dataModel, this);
-
+
// remove transitions in the same state
if(!filterSameState(transitions)) {
transition->isValid = false;
transition->invalidReason = GlobalTransition::SAME_SOURCE_STATE;
transition->invalidMsg = "Same source state";
-
+
// } else if(!filterChildEnabled(transitions)) {
} else if(!filterSameHierarchy(transitions)) {
transition->isValid = false;
@@ -1413,7 +1417,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath
transition->invalidMsg = "Preempting members";
}
}
-
+
}
// two combinations might have projected onto the same conflict-free set
@@ -1425,7 +1429,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath
transition->index = _lastTransIndex++;
_perfTransUsed++;
-
+
// remember this conflict-free set
// std::cerr << "New conflict-free subset: " << transition->transitionId << ":" << transition->eventDesc << std::endl;
outMap[transition->transitionId] = transition;
@@ -1433,12 +1437,12 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath
// _confToTransitions[""] = outMap;
return;
}
-
+
void ChartToFSM::explode() {
std::list<std::pair<GlobalTransition*, GlobalState*> > statesRemaining;
statesRemaining.push_back(std::make_pair(_currGlobalTransition, new GlobalState(_configuration, _alreadyEntered, _historyValue, _nsInfo.xmlNSPrefix, this)));
-
+
// add all invokers for initial transition
for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]);
@@ -1451,7 +1455,7 @@ void ChartToFSM::explode() {
/**
We need this to be a recursion in order not to exhaust the stack
*/
-
+
// append new global states and pop from front
while(statesRemaining.size() > 0) {
_perfStackSize = statesRemaining.size();
@@ -1459,18 +1463,18 @@ void ChartToFSM::explode() {
_perfStatesProcessed++;
DUMP_STATS(0, false);
-
+
GlobalState* globalState = statesRemaining.front().second;
_currGlobalTransition = statesRemaining.front().first;
statesRemaining.pop_front();
-
+
// used to be conditionalized, we will just assume
assert(_currGlobalTransition);
if (_globalConf.find(globalState->stateId) != _globalConf.end()) {
if (_currGlobalTransition->isEventless &&
- !_skipEventChainCalculations &&
- (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) {
+ !_skipEventChainCalculations &&
+ (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) {
// we arrived via a spontaneaous transition, do we need to update?
updateRaisedAndSendChains(_globalConf[globalState->stateId], _currGlobalTransition, std::set<GlobalTransition*>());
}
@@ -1487,7 +1491,7 @@ void ChartToFSM::explode() {
// remember as global configuration
_globalConf[globalState->stateId] = globalState;
_globalConf[globalState->stateId]->index = _lastStateIndex++;
-
+
if(_globalConf[globalState->stateId]->isFinal) {
if (_activeConf.find(globalState->activeId) == _activeConf.end()) {
assert(globalState->activeIndex == -1);
@@ -1522,11 +1526,11 @@ void ChartToFSM::explode() {
// reduce and sort transition sets
for(std::map<std::string, GlobalTransition*>::iterator transSetIter = transitionSets.begin();
- transSetIter != transitionSets.end();
- transSetIter++) {
+ transSetIter != transitionSets.end();
+ transSetIter++) {
globalState->sortedOutgoing.push_back(transSetIter->second);
}
-
+
globalState->sortedOutgoing.sort(PtrComp<GlobalTransition>);
// globalState->sortedOutgoing.unique(hasUnconditionalSuperset);
// globalState->sortedOutgoing.unique(hasEarlierUnconditionalMatch);
@@ -1542,23 +1546,23 @@ void ChartToFSM::explode() {
// globalState->sortedOutgoing = redundantRemove(globalState->sortedOutgoing);
//
// std::cout << globalState->sortedOutgoing.size() << std::endl;
-
+
assert(_activeConf.find(globalState->activeId) == _activeConf.end());
assert(globalState->activeIndex == -1);
globalState->activeIndex = _lastActiveIndex++;
_activeConf[globalState->activeId] = globalState;
}
-
+
// take every transition set and append resulting new state
for(std::list<GlobalTransition*>::iterator transIter = globalState->sortedOutgoing.begin();
- transIter != globalState->sortedOutgoing.end();
- transIter++) {
-
+ transIter != globalState->sortedOutgoing.end();
+ transIter++) {
+
GlobalTransition* incomingTrans = _currGlobalTransition;
GlobalTransition* outgoingTrans = *transIter;
-
+
outgoingTrans->source = globalState->stateId;
-
+
if (_keepInvalidTransitions && !outgoingTrans->isValid)
continue;
@@ -1572,8 +1576,8 @@ void ChartToFSM::explode() {
// if outgoing transition is spontaneous, add number of events to chain
if (outgoingTrans->isEventless &&
- !_skipEventChainCalculations &&
- (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) {
+ !_skipEventChainCalculations &&
+ (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) {
outgoingTrans->eventsChainRaised = MIN(incomingTrans->eventsChainRaised + outgoingTrans->eventsRaised, UNDECIDABLE);
outgoingTrans->eventsChainSent = MIN(incomingTrans->eventsChainSent + outgoingTrans->eventsSent, UNDECIDABLE);
@@ -1585,7 +1589,7 @@ void ChartToFSM::explode() {
}
statesRemaining.push_back(std::make_pair(outgoingTrans, new GlobalState(_configuration, _alreadyEntered, _historyValue, _nsInfo.xmlNSPrefix, this)));
-
+
// add all invokers
for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]);
@@ -1610,13 +1614,13 @@ void ChartToFSM::explode() {
void ChartToFSM::updateRaisedAndSendChains(GlobalState* state, GlobalTransition* source, std::set<GlobalTransition*> visited) {
for (std::list<GlobalTransition*>::iterator transIter = state->sortedOutgoing.begin(); transIter != state->sortedOutgoing.end(); transIter++) {
GlobalTransition* transition = *transIter;
-
+
if (!transition->isEventless)
continue; // we do not care for eventful transitions
-
+
// source leads to spontaneous transition -> update event chains
bool eventChainsNeedUpdated = false;
-
+
if (visited.find(transition) != visited.end()) {
// potential spontaneous transition cycle!
if (transition->eventsChainRaised > 0)
@@ -1625,32 +1629,32 @@ void ChartToFSM::updateRaisedAndSendChains(GlobalState* state, GlobalTransition*
_maxEventSentChain = UNDECIDABLE;
return;
}
-
+
// UNDECIDABLE means "undecidable / endless"
-
+
// will source increase our event chain?
if (transition->eventsChainRaised != UNDECIDABLE &&
- transition->eventsChainRaised < source->eventsChainRaised + transition->eventsRaised) {
+ transition->eventsChainRaised < source->eventsChainRaised + transition->eventsRaised) {
// taking transition after source causes more events in chain
transition->eventsChainRaised = MIN(source->eventsChainRaised + transition->eventsRaised, UNDECIDABLE);
eventChainsNeedUpdated = true;
}
if (transition->eventsChainSent != UNDECIDABLE &&
- transition->eventsChainSent < source->eventsChainSent + transition->eventsSent) {
+ transition->eventsChainSent < source->eventsChainSent + transition->eventsSent) {
// taking transition after source causes more events in chain
transition->eventsChainSent = MIN(source->eventsChainSent + transition->eventsSent, UNDECIDABLE);
eventChainsNeedUpdated = true;
}
if (eventChainsNeedUpdated &&
- transition->destination.length() > 0 &&
- _globalConf.find(transition->destination) != _globalConf.end()) {
+ transition->destination.length() > 0 &&
+ _globalConf.find(transition->destination) != _globalConf.end()) {
visited.insert(transition);
// iterate all spontaneous transitions in destination and update event chains
updateRaisedAndSendChains(_globalConf[transition->destination], transition, visited);
}
-
+
if (transition->eventsChainRaised > _maxEventRaisedChain)
_maxEventRaisedChain = transition->eventsChainRaised;
if (transition->eventsChainSent > _maxEventSentChain)
@@ -1690,7 +1694,7 @@ Arabica::XPath::NodeSet<std::string> ChartToFSM::refsToTransitions(const std::se
}
return transitions;
}
-
+
void ChartToFSM::beforeMicroStep(Interpreter interpreter) {
}
void ChartToFSM::onStableConfiguration(Interpreter interpreter) {
@@ -1732,7 +1736,7 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeState
const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates_, // we need to remember for binding=late
const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates_,
const std::string& xmlNSPrefix,
- ChartToFSM* flattener) {
+ ChartToFSM* flattener) {
interpreter = flattener;
activeIndex = -1;
@@ -1778,13 +1782,13 @@ GlobalTransition* GlobalTransition::copyWithoutExecContent(GlobalTransition* oth
GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitionSet, DataModel dataModel, ChartToFSM* flattener) {
interpreter = flattener;
-
+
eventsRaised = 0;
eventsSent = 0;
eventsChainRaised = 0;
eventsChainSent = 0;
historyBase = NULL;
-
+
for (int i = 0; i < transitionSet.size(); i++) {
transitionRefs.insert(strTo<int>(ATTR_CAST(transitionSet[i], "index")));
}
@@ -1800,7 +1804,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t
hasExecutableContent = false;
isValid = true;
isEventless = true;
-
+
#if 0
std::cerr << "################" << std::endl;
for (int i = 0; i < transitions.size(); i++) {
@@ -1910,7 +1914,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t
if (HAS_ATTR(transElem, "cond")) {
conditions.push_back(boost::trim_copy(ATTR(transElem, "cond")));
}
-
+
std::list<std::string> targets = InterpreterImpl::tokenizeIdRefs(ATTR(transElem, "target"));
std::list<std::string>::iterator targetIter = targets.begin();
while(targetIter != targets.end()) {
@@ -1922,7 +1926,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t
}
// std::cout << std::endl << std::endl;
}
-
+
seperator = "";
for (std::vector<Element<std::string> >::iterator transIter = interpreter->indexedTransitions.begin(); transIter != interpreter->indexedTransitions.end(); transIter++) {
const Element<std::string>& refTrans = *transIter;
@@ -1938,7 +1942,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t
}
seperator = " ";
}
-
+
// if (members == " 4 6 7 ")
// std::cout << "asdfadf";
@@ -1968,7 +1972,7 @@ std::map<std::string, Arabica::XPath::NodeSet<std::string> > GlobalState::getHis
return historyValue;
}
-
+
Arabica::XPath::NodeSet<std::string> GlobalTransition::getTransitions() const {
return interpreter->refsToTransitions(transitionRefs);
}
diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h
index f7e00c5..ab4aed4 100644
--- a/src/uscxml/transform/ChartToFSM.h
+++ b/src/uscxml/transform/ChartToFSM.h
@@ -43,12 +43,12 @@ public:
const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates, // we need to remember for binding=late
const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates,
const std::string& xmlNSPrefix,
- ChartToFSM* flattener);
+ ChartToFSM* flattener);
std::set<int> activeStatesRefs;
std::set<int> alreadyEnteredStatesRefs;
std::map<std::string, std::set<int> > historyStatesRefs;
-
+
std::list<GlobalTransition*> sortedOutgoing;
std::string stateId;
std::string activeId;
@@ -56,9 +56,9 @@ public:
unsigned long activeIndex;
unsigned long index;
bool isFinal;
-
+
ChartToFSM* interpreter;
-
+
Arabica::XPath::NodeSet<std::string> getActiveStates();
Arabica::XPath::NodeSet<std::string> getAlreadyEnteredStates();
std::map<std::string, Arabica::XPath::NodeSet<std::string> > getHistoryStates();
@@ -98,7 +98,7 @@ public:
return true;
if ((uninvoke && !other.uninvoke) || (!uninvoke && other.uninvoke))
return true;
-
+
if (onEntry < other.onEntry)
return onEntry < other.onEntry;
if (raiseDone < other.raiseDone)
@@ -124,11 +124,11 @@ public:
bool operator!=(const Action& other) const {
return !operator==(other);
}
-
+
friend USCXML_API std::ostream& operator<< (std::ostream& os, const Action& action);
typedef std::list<GlobalTransition::Action>::iterator iter_t;
-
+
Arabica::DOM::Element<std::string> onEntry;
Arabica::DOM::Element<std::string> onExit;
Arabica::DOM::Element<std::string> transition;
@@ -137,12 +137,12 @@ public:
Arabica::DOM::Element<std::string> invoke;
Arabica::DOM::Element<std::string> uninvoke;
Arabica::DOM::Element<std::string> raiseDone;
-
+
};
GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitions, DataModel dataModel, ChartToFSM* flattener);
static GlobalTransition* copyWithoutExecContent(GlobalTransition* other);
-
+
bool isValid; // constructor will determine, calling code will delete if not
std::string invalidMsg;
InvalidReason invalidReason;
@@ -151,17 +151,17 @@ public:
bool isTargetless; // whether or not all our transitions are eventless
bool isSubset; // there is a superset to this set
bool hasExecutableContent;
-
+
uint32_t eventsRaised; // internal events this transition will raise
uint32_t eventsSent; // external events this transition will send
uint32_t eventsChainRaised; // maximum number of internal events raised when taking this transition in a chain
uint32_t eventsChainSent; // maximum number of external events raised when taking this transition in a chain
-
+
std::set<int> startTransitionRefs; // indices of eventful transitions that might trigger this transition
-
+
std::set<int> transitionRefs; // indizes of constituting transitions
Arabica::XPath::NodeSet<std::string> getTransitions() const;
-
+
std::list<std::string> eventNames; // the list of longest event names that will enable this set
std::string eventDesc; // space-seperated eventnames for convenience
std::string condition; // conjunction of all the set's conditions
@@ -198,15 +198,15 @@ public:
TYPE_NESTED,
TYPE_TRANSITION
};
-
+
TransitionTreeNode()
- : prevTransition(NULL),
- nextTransition(NULL),
- firstTransition(NULL),
- firstState(NULL),
- parent(NULL),
- type(TYPE_UNDEFINED) {}
-
+ : prevTransition(NULL),
+ nextTransition(NULL),
+ firstTransition(NULL),
+ firstState(NULL),
+ parent(NULL),
+ type(TYPE_UNDEFINED) {}
+
virtual ~TransitionTreeNode() {
for (std::list<TransitionTreeNode*>::iterator childIter = children.begin(); childIter != children.end(); childIter++) {
delete(*childIter);
@@ -229,7 +229,7 @@ public:
std::string nodeId;
TransitionTreeNodeType type;
-
+
bool operator<(const TransitionTreeNode& other) const {
return nodeId < other.nodeId;
}
@@ -242,16 +242,16 @@ public:
virtual ~ChartToFSM();
void indexTransitions();
- void annotateDomain();
- void annotateExitSet();
- void annotateEntrySet();
- void annotateConflicts();
+ void annotateDomain();
+ void annotateExitSet();
+ void annotateEntrySet();
+ void annotateConflicts();
Arabica::DOM::Document<std::string> getDocument() const; // overwrite to return flat FSM
protected:
InterpreterState interpret();
-
+
GlobalState* _start;
Arabica::DOM::Document<std::string> _flatDoc;
std::map<std::string, GlobalState*> _globalConf;
@@ -270,7 +270,7 @@ protected:
private:
Arabica::XPath::NodeSet<std::string> refsToStates(const std::set<int>&);
Arabica::XPath::NodeSet<std::string> refsToTransitions(const std::set<int>&);
-
+
// gather executable content per microstep
void executeContent(const Arabica::DOM::Element<std::string>& content, bool rethrow = false);
@@ -301,12 +301,12 @@ private:
void updateRaisedAndSendChains(GlobalState* state, GlobalTransition* source, std::set<GlobalTransition*> visited);
void reassembleFromFlat();
-
+
std::list<GlobalTransition*> sortTransitions(std::list<GlobalTransition*> list);
// we need this static as we use it in a sort function
static std::map<Arabica::DOM::Node<std::string>, Arabica::DOM::Node<std::string> > _transParents;
-
+
static bool filterSameState(const Arabica::XPath::NodeSet<std::string>& transitions);
uint64_t _perfTransProcessed;
@@ -334,13 +334,13 @@ private:
size_t _maxEventSentChain;
size_t _maxEventRaisedChain;
size_t _doneEventRaiseTolerance;
-
+
GlobalTransition* _currGlobalTransition;
std::map<std::string, std::map<std::string, GlobalTransition*> > _confToTransitions;
-
+
TransitionTreeNode* _transTree;
std::map<Arabica::DOM::Element<std::string>, TransitionTreeNode*> _stateToTransTreeNode;
-
+
friend class GlobalTransition;
friend class GlobalState;
};
diff --git a/src/uscxml/transform/ChartToFlatSCXML.cpp b/src/uscxml/transform/ChartToFlatSCXML.cpp
index c554218..2905444 100644
--- a/src/uscxml/transform/ChartToFlatSCXML.cpp
+++ b/src/uscxml/transform/ChartToFlatSCXML.cpp
@@ -52,7 +52,7 @@ ChartToFlatSCXML::operator Interpreter() {
return Interpreter::fromClone(shared_from_this());
}
-
+
Transformer ChartToFlatSCXML::transform(const Interpreter& other) {
return boost::shared_ptr<TransformerImpl>(new ChartToFlatSCXML(other));
}
@@ -79,10 +79,10 @@ void ChartToFlatSCXML::writeTo(std::ostream& stream) {
if (HAS_ATTR(element, "final-target"))
element.removeAttribute("final-target");
}
-
+
if (envVarIsTrue("USCXML_FLAT_FSM_METRICS_ONLY"))
return;
-
+
stream << _scxml;
}
@@ -90,7 +90,7 @@ void ChartToFlatSCXML::createDocument() {
if (HAS_ATTR(_scxml, "flat") && stringIsTrue(ATTR(_scxml, "flat")))
return;
-
+
{
NodeSet<std::string> allElements = filterChildType(Node_base::ELEMENT_NODE, _scxml, true);
size_t nrElements = 0;
@@ -100,36 +100,36 @@ void ChartToFlatSCXML::createDocument() {
}
std::cerr << "Number of elements before flattening: " << nrElements + 1 << std::endl;
}
-
+
if (_start == NULL)
interpret(); // only if not already flat!
-
+
if (envVarIsTrue("USCXML_FLAT_FSM_METRICS_ONLY"))
return;
-
+
Element<std::string> _origSCXML = _scxml;
-
+
_scxml = _flatDoc.createElementNS(_nsInfo.nsURL, "scxml");
_nsInfo.setPrefix(_scxml);
-
+
_scxml.setAttribute("flat", "true");
_flatDoc.appendChild(_scxml);
-
+
if (HAS_ATTR(_origSCXML, "datamodel")) {
_scxml.setAttribute("datamodel", ATTR(_origSCXML, "datamodel"));
}
-
+
if (HAS_ATTR(_origSCXML, "name")) {
_scxml.setAttribute("name", ATTR(_origSCXML, "name"));
}
-
+
if (HAS_ATTR(_origSCXML, "binding")) {
_scxml.setAttribute("binding", ATTR(_origSCXML, "binding"));
}
-
+
_scxml.setAttribute("initial", _start->stateId);
-
+
NodeSet<std::string> datas;
if (_binding == InterpreterImpl::LATE) {
// with late binding, just copy direct datamodel childs
@@ -144,34 +144,34 @@ void ChartToFlatSCXML::createDocument() {
Node<std::string> imported = _flatDoc.importNode(datas[i], true);
_scxml.appendChild(imported);
}
-
-
+
+
NodeSet<std::string> scripts = filterChildElements(_nsInfo.xmlNSPrefix + "script", _origSCXML);
for (int i = 0; i < scripts.size(); i++) {
Node<std::string> imported = _flatDoc.importNode(scripts[i], true);
_scxml.appendChild(imported);
}
-
+
NodeSet<std::string> comments = filterChildType(Node_base::COMMENT_NODE, _origSCXML);
for (int i = 0; i < comments.size(); i++) {
Node<std::string> imported = _flatDoc.importNode(comments[i], true);
_scxml.appendChild(imported);
}
-
+
std::vector<std::pair<std::string,GlobalState*> > sortedStates;
sortedStates.insert(sortedStates.begin(), _globalConf.begin(), _globalConf.end());
std::sort(sortedStates.begin(), sortedStates.end(), sortStatesByIndex);
-
+
// int index = 0;
// for (std::vector<Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
// const Element<std::string>& refTrans = *transIter;
// std::cerr << index++ << ": " << refTrans << std::endl;
// }
// std::cerr << std::endl;
-
+
for (std::vector<std::pair<std::string,GlobalState*> >::iterator confIter = sortedStates.begin();
- confIter != sortedStates.end();
- confIter++) {
+ confIter != sortedStates.end();
+ confIter++) {
appendGlobalStateNode(confIter->second);
}
@@ -181,7 +181,7 @@ void ChartToFlatSCXML::createDocument() {
if (scxmls.size() > 0) {
_scxml = Element<std::string>(scxmls[0]);
}
-
+
{
NodeSet<std::string> allElements = filterChildType(Node_base::ELEMENT_NODE, _scxml, true);
size_t nrElements = 0;
@@ -191,29 +191,29 @@ void ChartToFlatSCXML::createDocument() {
}
std::cerr << "Number of elements after flattening: " << nrElements + 1 << std::endl;
}
-
+
}
void ChartToFlatSCXML::appendGlobalStateNode(GlobalState* globalState) {
Element<std::string> state = _flatDoc.createElementNS(_nsInfo.nsURL, "state");
_nsInfo.setPrefix(state);
-
+
state.setAttribute("step", toStr(globalState->index));
state.setAttribute("id", globalState->stateId);
-
+
if (globalState->isFinal)
state.setAttribute("final", "true");
-
+
std::list<GlobalTransition*>& transitionList = globalState->sortedOutgoing;
-
+
// apend here, for transient state chains to trail the state
_scxml.appendChild(state);
-
+
size_t index = 0;
for (std::list<GlobalTransition*>::iterator outIter = transitionList.begin();
- outIter != transitionList.end();
- outIter++) {
+ outIter != transitionList.end();
+ outIter++) {
// (*outIter)->index = globalState->index + ":" + toStr(index);
state.appendChild(globalTransitionToNode(*outIter));
index++;
@@ -226,48 +226,48 @@ void ChartToFlatSCXML::appendGlobalStateNode(GlobalState* globalState) {
Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* globalTransition) {
Element<std::string> transition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition");
_nsInfo.setPrefix(transition);
-
+
// transition.setAttribute("ref", globalTransition->index);
-
+
#if 1
transition.setAttribute("members", globalTransition->members);
#endif
// transition.setAttribute("priority", toStr(globalTransition->priority));
-
+
if (!globalTransition->isEventless) {
transition.setAttribute("event", globalTransition->eventDesc);
}
-
+
if (globalTransition->condition.size() > 0) {
transition.setAttribute("cond", globalTransition->condition);
}
-
+
if (globalTransition->destination.size() > 0) {
transition.setAttribute("final-target", globalTransition->destination);
}
-
+
NodeSet<std::string> transientStateChain;
-
+
// current active state set
FlatStateIdentifier flatId(globalTransition->source);
std::list<std::string> currActiveStates = flatId.getActive();
-
+
// std::cerr << "From " << globalTransition->source << " to " << globalTransition->destination << ":" << std::endl;
-
+
// gather content for new transient state
NodeSet<std::string> childs;
-
+
// aggregated entering / exiting to avoid states without childs while still labeling
std::list<Arabica::DOM::Comment<std::string> > pendingComments;
-
+
// iterate all actions taken during the transition
for (std::list<GlobalTransition::Action>::iterator actionIter = globalTransition->actions.begin();
- actionIter != globalTransition->actions.end();
- actionIter++) {
-
+ actionIter != globalTransition->actions.end();
+ actionIter++) {
+
if (actionIter->transition) {
// DETAIL_EXEC_CONTENT(transition, actionIter);
-
+
Element<std::string> onexit = _flatDoc.createElementNS(_nsInfo.nsURL, "onexit");
_nsInfo.setPrefix(onexit);
Node<std::string> child = actionIter->transition.getFirstChild();
@@ -286,7 +286,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
if (HAS_ATTR(actionIter->transition, "target"))
commentSS << " to target '" << ATTR(actionIter->transition, "target") << "'";
commentSS << " ";
-
+
if (onexit.hasChildNodes()) {
if (envVarIsTrue("USCXML_ANNOTATE_VERBOSE_COMMENTS"))
childs.push_back(_flatDoc.createComment(commentSS.str()));
@@ -295,16 +295,16 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
if (envVarIsTrue("USCXML_ANNOTATE_VERBOSE_COMMENTS"))
pendingComments.push_back(_flatDoc.createComment(commentSS.str()));
}
-
+
continue;
}
-
+
if (actionIter->onExit) {
// DETAIL_EXEC_CONTENT(onExit, actionIter);
childs.push_back(actionIter->onExit);
continue;
}
-
+
if (actionIter->onEntry) {
// DETAIL_EXEC_CONTENT(onEntry, actionIter);
childs.push_back(actionIter->onEntry);
@@ -324,12 +324,12 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
childs.push_back(invokeElem);
continue;
}
-
+
if (actionIter->uninvoke) {
// DETAIL_EXEC_CONTENT(uninvoke, actionIter);
Element<std::string> uninvokeElem = _flatDoc.createElementNS(_nsInfo.nsURL, "uninvoke");
_nsInfo.setPrefix(uninvokeElem);
-
+
if (HAS_ATTR(actionIter->uninvoke, "type")) {
uninvokeElem.setAttribute("type", ATTR(actionIter->uninvoke, "type"));
}
@@ -345,7 +345,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
childs.push_back(uninvokeElem);
continue;
}
-
+
if (actionIter->exited) {
currActiveStates.remove(ATTR_CAST(actionIter->exited, "id"));
if (childs.size() > 0) {
@@ -358,7 +358,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
pendingComments.push_back(_flatDoc.createComment(" Exiting " + ATTR_CAST(actionIter->exited, "id") + " "));
}
}
-
+
if (actionIter->entered) {
if (childs.size() > 0) {
if (envVarIsTrue("USCXML_ANNOTATE_VERBOSE_COMMENTS"))
@@ -369,7 +369,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
pendingComments.push_back(_flatDoc.createComment(" Entering " + ATTR_CAST(actionIter->entered, "id") + " "));
}
currActiveStates.push_back(ATTR_CAST(actionIter->entered, "id"));
-
+
// we entered a new child - check if it has a datamodel and we entered for the first time
if (_binding == InterpreterImpl::LATE) {
NodeSet<std::string> datamodel = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", actionIter->entered);
@@ -379,35 +379,35 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
}
}
}
-
+
CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates))
-
+
if (transientStateChain.size() > 0) {
Element<std::string> prevExitTransitionElem;
-
+
for (int i = 0; i < transientStateChain.size(); i++) {
Element<std::string> transientStateElem = Element<std::string>(transientStateChain[i]);
transientStateElem.setAttribute("id", transientStateElem.getAttribute("id") + "-via-" + toStr(_lastTransientStateId++));
-
+
Element<std::string> exitTransition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition");
_nsInfo.setPrefix(exitTransition);
-
+
if (prevExitTransitionElem) {
// point previous to this one
prevExitTransitionElem.setAttribute("target", transientStateElem.getAttribute("id"));
} else {
// update globalTransition->source target
}
-
+
transientStateElem.appendChild(exitTransition);
prevExitTransitionElem = exitTransition;
-
+
if (i == 0)
transition.setAttribute("target", transientStateElem.getAttribute("id"));
-
+
_scxml.appendChild(transientStateElem);
}
-
+
// last one points to actual target
assert(prevExitTransitionElem);
prevExitTransitionElem.setAttribute("target", globalTransition->destination);
@@ -415,11 +415,11 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
} else if (transientStateChain.size() == 1) {
Element<std::string> transientStateElem = Element<std::string>(transientStateChain[0]);
transientStateElem.setAttribute("onlyOne", "yes!");
-
+
Element<std::string> exitTransition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition");
_nsInfo.setPrefix(exitTransition);
exitTransition.setAttribute("target", globalTransition->destination);
-
+
transientStateElem.appendChild(exitTransition);
_scxml.appendChild(transientStateElem);
@@ -428,7 +428,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo
} else {
transition.setAttribute("target", globalTransition->destination);
}
-
+
assert(HAS_ATTR_CAST(transition, "target"));
return transition;
}
diff --git a/src/uscxml/transform/ChartToFlatSCXML.h b/src/uscxml/transform/ChartToFlatSCXML.h
index 7afe3c5..a278721 100644
--- a/src/uscxml/transform/ChartToFlatSCXML.h
+++ b/src/uscxml/transform/ChartToFlatSCXML.h
@@ -33,17 +33,17 @@ public:
operator Interpreter();
Arabica::DOM::Document<std::string> getDocument() const {
- if (_flatDoc)
- return _flatDoc;
- return _document;
+ if (_flatDoc)
+ return _flatDoc;
+ return _document;
}
protected:
void writeTo(std::ostream& stream);
-
+
ChartToFlatSCXML(const Interpreter& other) : TransformerImpl(), ChartToFSM(other), _lastTransientStateId(0) {}
void createDocument();
-
+
void appendGlobalStateNode(GlobalState* globalState);
Arabica::DOM::Node<std::string> globalTransitionToNode(GlobalTransition* globalTransition);
static bool sortStatesByIndex(const std::pair<std::string,GlobalState*>& s1, const std::pair<std::string,GlobalState*>& s2);
diff --git a/src/uscxml/transform/ChartToMinimalSCXML.cpp b/src/uscxml/transform/ChartToMinimalSCXML.cpp
index ecfa12b..69ac9cb 100644
--- a/src/uscxml/transform/ChartToMinimalSCXML.cpp
+++ b/src/uscxml/transform/ChartToMinimalSCXML.cpp
@@ -38,7 +38,7 @@ Transformer ChartToMinimalSCXML::transform(const Interpreter& other) {
ChartToMinimalSCXML::ChartToMinimalSCXML(const Interpreter& other) : TransformerImpl(), _retainAsComments(false), _step(1) {
cloneFrom(other.getImpl());
-
+
// a bit messy but needed for SCXML IO Processor with session id target
_selfPtr = boost::shared_ptr<InterpreterImpl>(this, Deleter());
Interpreter::addInstance(_selfPtr);
@@ -47,7 +47,7 @@ ChartToMinimalSCXML::ChartToMinimalSCXML(const Interpreter& other) : Transformer
void ChartToMinimalSCXML::writeTo(std::ostream& stream) {
addMonitor(this);
-
+
{
NodeSet<std::string> allElements = filterChildType(Node_base::ELEMENT_NODE, _scxml, true);
size_t nrElements = 0;
@@ -57,7 +57,7 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) {
}
std::cerr << "Number of elements before reduction: " << nrElements + 1 << std::endl;
}
-
+
// test 278 - move embedded datas to topmost datamodel
if (_binding == EARLY) {
// move all data elements into topmost datamodel element
@@ -75,7 +75,7 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) {
while(topMostDatamodel.hasChildNodes())
topMostDatamodel.removeChild(topMostDatamodel.getFirstChild());
-
+
for (int i = 0; i < datas.size(); i++) {
if (!isInEmbeddedDocument(datas[i])) {
topMostDatamodel.appendChild(datas[i]);
@@ -83,10 +83,10 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) {
}
}
}
-
+
char* waitForEnv = getenv("USCXML_MINIMIZE_WAIT_MS");
_retainAsComments = envVarIsTrue("USCXML_MINIMIZE_RETAIN_AS_COMMENTS");
-
+
long waitFor = -1;
if (waitForEnv != NULL) {
@@ -114,7 +114,7 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) {
}
}
stop();
-
+
removeUnvisited(_scxml);
{
@@ -140,11 +140,11 @@ void ChartToMinimalSCXML::removeUnvisited(Arabica::DOM::Node<std::string>& node)
Element<std::string> elem(node);
if (isInEmbeddedDocument(elem) ||
- (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "param") ||
- (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "donedata") ||
- (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "datamodel") ||
- (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "data") ||
- (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "content")) {
+ (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "param") ||
+ (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "donedata") ||
+ (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "datamodel") ||
+ (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "data") ||
+ (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "content")) {
return;
}
@@ -168,14 +168,14 @@ void ChartToMinimalSCXML::removeUnvisited(Arabica::DOM::Node<std::string>& node)
}
}
}
-
+
// test344
if (_dmCopy &&
- TAGNAME(elem) == _nsInfo.xmlNSPrefix + "transition" &&
- HAS_ATTR(elem, "cond") &&
- !_dmCopy.isValidSyntax(ATTR(elem, "cond")))
+ TAGNAME(elem) == _nsInfo.xmlNSPrefix + "transition" &&
+ HAS_ATTR(elem, "cond") &&
+ !_dmCopy.isValidSyntax(ATTR(elem, "cond")))
return;
-
+
// detach unvisited nodes from DOM
if (_visited.find(node) == _visited.end()) {
std::cerr << DOMUtils::xPathForNode(node) << std::endl;
@@ -198,13 +198,13 @@ void ChartToMinimalSCXML::removeUnvisited(Arabica::DOM::Node<std::string>& node)
removeUnvisited(child);
}
}
-
+
void ChartToMinimalSCXML::markAsVisited(const Arabica::DOM::Element<std::string>& element) {
if (_visited.find(element) != _visited.end())
return;
-
+
Arabica::DOM::Element<std::string> elem = const_cast<Arabica::DOM::Element<std::string>&>(element);
-
+
_visited.insert(element);
Node<std::string> parent = element.getParentNode();
if (parent && parent.getNodeType() == Node_base::ELEMENT_NODE) {
@@ -212,7 +212,7 @@ void ChartToMinimalSCXML::markAsVisited(const Arabica::DOM::Element<std::string>
markAsVisited(parentElem);
}
}
-
+
void ChartToMinimalSCXML::beforeExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element) {
markAsVisited(element);
StateTransitionMonitor::beforeExecutingContent(interpreter, element);
@@ -229,7 +229,7 @@ void ChartToMinimalSCXML::beforeTakingTransition(Interpreter interpreter, const
markAsVisited(Arabica::DOM::Element<std::string>(targets[i]));
}
markAsVisited(transition);
-
+
std::stringstream commentSS;
if (HAS_ATTR(transition, "event")) {
commentSS << " Step #" << _step++ << " - transition taken for event '" << _currEvent.name << "' ";
@@ -244,10 +244,10 @@ void ChartToMinimalSCXML::beforeTakingTransition(Interpreter interpreter, const
void ChartToMinimalSCXML::beforeEnteringState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) {
markAsVisited(state);
-
+
std::stringstream commentSS;
commentSS << " Step #" << _step++ << " - state entered ";
-
+
Arabica::DOM::Element<std::string> ncState = const_cast<Arabica::DOM::Element<std::string>&>(state);
if (envVarIsTrue("USCXML_ANNOTATE_PROGRESS"))
ncState.insertBefore(_document.createComment(commentSS.str()), ncState.getFirstChild());
diff --git a/src/uscxml/transform/ChartToMinimalSCXML.h b/src/uscxml/transform/ChartToMinimalSCXML.h
index 3cdab54..0260ee1 100644
--- a/src/uscxml/transform/ChartToMinimalSCXML.h
+++ b/src/uscxml/transform/ChartToMinimalSCXML.h
@@ -37,7 +37,7 @@ class USCXML_API ChartToMinimalSCXML : public InterpreterRC, public StateTransit
public:
virtual ~ChartToMinimalSCXML() {}
static Transformer transform(const Interpreter& other);
-
+
// InterpreterMonitor
virtual void beforeExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element);
virtual void beforeUninvoking(Interpreter interpreter, const Arabica::DOM::Element<std::string>& invokeElem, const std::string& invokeid);
@@ -49,33 +49,35 @@ public:
// gather executable content per microstep
void executeContent(const Arabica::DOM::Element<std::string>& content, bool rethrow = false);
-
+
// invoke and uninvoke
virtual void invoke(const Arabica::DOM::Element<std::string>& element);
virtual void cancelInvoke(const Arabica::DOM::Element<std::string>& element);
protected:
void writeTo(std::ostream& stream);
-
+
ChartToMinimalSCXML(const Interpreter& other);
-
+
void markAsVisited(const Arabica::DOM::Element<std::string>& element);
void removeUnvisited(Arabica::DOM::Node<std::string>& node);
std::set<Arabica::DOM::Node<std::string> > _visited;
DataModel _dmCopy;
bool _retainAsComments;
-
+
private:
size_t _step;
-
+
// we need this to register as an instance at Interpreter::_instances
boost::shared_ptr<InterpreterImpl> _selfPtr;
-
+
// prevent deletion from shared_ptr
class Deleter {
public:
- void operator()(ChartToMinimalSCXML* p) { /* do nothing */ }
+ void operator()(ChartToMinimalSCXML* p) {
+ /* do nothing */
+ }
};
};
diff --git a/src/uscxml/transform/ChartToPromela.cpp b/src/uscxml/transform/ChartToPromela.cpp
index 03178f0..4e3a990 100644
--- a/src/uscxml/transform/ChartToPromela.cpp
+++ b/src/uscxml/transform/ChartToPromela.cpp
@@ -109,7 +109,7 @@ for (std::set<int>::iterator transRefIter = transList->transitionRefs.begin(); \
stream << padding << _prefix << "transitions[" << *transRefIter << "] = "#value"; " << std::endl; \
} \
} \
-
+
#define DUMP_STATS(disregardTime) \
uint64_t now = tthread::chrono::system_clock::now(); \
@@ -142,11 +142,11 @@ void ChartToPromela::writeTo(std::ostream& stream) {
writeProgram(stream);
}
-
+
void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* interpreter) {
PromelaParser parser(code);
// parser.dump();
-
+
// find all strings
std::list<PromelaParserNode*> astNodes;
astNodes.push_back(parser.ast);
@@ -160,7 +160,7 @@ void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* inter
bool hasValue = false;
int assignedValue = 0;
-
+
switch (node->type) {
case PML_STRING: {
std::string unquoted = node->value;
@@ -193,8 +193,8 @@ void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* inter
std::list<PromelaParserNode*>::iterator opIter = node->operands.begin();
if ((*opIter)->type != PML_NAME) {
node->dump();
- return;
- assert(false);
+ return;
+ assert(false);
}
PromelaTypedef* td = &_typeDefs;
@@ -249,14 +249,14 @@ void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* inter
}
opIter++;
}
-
+
if (hasValue) {
if (td->maxValue < assignedValue)
td->maxValue = assignedValue;
if (td->minValue > assignedValue)
td->minValue = assignedValue;
}
-
+
continue; // skip processing nested AST nodes
}
case PML_NAME: {
@@ -300,7 +300,7 @@ void PromelaCodeAnalyzer::addOrigState(const std::string& stateName) {
createMacroName(stateName);
}
}
-
+
void PromelaCodeAnalyzer::addState(const std::string& stateName) {
if (_states.find(stateName) != _states.end())
return;
@@ -367,7 +367,7 @@ std::string PromelaCodeAnalyzer::createMacroName(const std::string& literal) {
macroName = "_EMPTY_STRING";
if(macroName.length() < 2 && macroName[0] == '_')
macroName = "_WEIRD_CHARS";
-
+
unsigned int index = 2;
while (_macroNameSet.find(macroName) != _macroNameSet.end()) {
std::string suffix = toStr(index);
@@ -384,45 +384,45 @@ std::string PromelaCodeAnalyzer::createMacroName(const std::string& literal) {
return macroName;
}
- std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding) {
- std::stringstream assignment;
-
- std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
- while(typeIter != type.types.end()) {
- const PromelaTypedef& innerType = typeIter->second;
- if (innerType.arraySize > 0) {
- for (int i = 0; i < innerType.arraySize; i++) {
- assignment << padding << var << "." << typeIter->first << "[" << i << "] = 0;" << std::endl;
- }
- } else if (innerType.types.size() > 0) {
- assignment << getTypeReset(var + "." + typeIter->first, typeIter->second, padding);
- } else {
- assignment << padding << var << "." << typeIter->first << " = 0;" << std::endl;
- }
- typeIter++;
- }
- return assignment.str();
+std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding) {
+ std::stringstream assignment;
+
+ std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
+ while(typeIter != type.types.end()) {
+ const PromelaTypedef& innerType = typeIter->second;
+ if (innerType.arraySize > 0) {
+ for (int i = 0; i < innerType.arraySize; i++) {
+ assignment << padding << var << "." << typeIter->first << "[" << i << "] = 0;" << std::endl;
+ }
+ } else if (innerType.types.size() > 0) {
+ assignment << getTypeReset(var + "." + typeIter->first, typeIter->second, padding);
+ } else {
+ assignment << padding << var << "." << typeIter->first << " = 0;" << std::endl;
+ }
+ typeIter++;
+ }
+ return assignment.str();
}
std::string PromelaCodeAnalyzer::getTypeAssignment(const std::string& varTo, const std::string& varFrom, const PromelaTypedef& type, const std::string padding) {
- std::stringstream assignment;
-
- std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
- while(typeIter != type.types.end()) {
- const PromelaTypedef& innerType = typeIter->second;
- if (innerType.arraySize > 0) {
- for (int i = 0; i < innerType.arraySize; i++) {
- assignment << padding << varTo << "." << typeIter->first << "[" << i << "] = " << varFrom << "." << typeIter->first << "[" << i << "];" << std::endl;
- }
- } else if (innerType.types.size() > 0) {
- assignment << getTypeAssignment(varTo + "." + typeIter->first, varFrom + "." + typeIter->first, typeIter->second, padding);
- } else {
- assignment << padding << varTo << "." << typeIter->first << " = " << varFrom << "." << typeIter->first << ";" << std::endl;
- }
- typeIter++;
- }
- return assignment.str();
+ std::stringstream assignment;
+
+ std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
+ while(typeIter != type.types.end()) {
+ const PromelaTypedef& innerType = typeIter->second;
+ if (innerType.arraySize > 0) {
+ for (int i = 0; i < innerType.arraySize; i++) {
+ assignment << padding << varTo << "." << typeIter->first << "[" << i << "] = " << varFrom << "." << typeIter->first << "[" << i << "];" << std::endl;
+ }
+ } else if (innerType.types.size() > 0) {
+ assignment << getTypeAssignment(varTo + "." + typeIter->first, varFrom + "." + typeIter->first, typeIter->second, padding);
+ } else {
+ assignment << padding << varTo << "." << typeIter->first << " = " << varFrom << "." << typeIter->first << ";" << std::endl;
+ }
+ typeIter++;
+ }
+ return assignment.str();
}
std::string PromelaCodeAnalyzer::macroForLiteral(const std::string& literal) {
@@ -464,14 +464,14 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s
posList.sort();
posIter = posList.begin();
lastPos = 0;
-
+
while (posIter != posList.end()) {
processedStr << code.substr(lastPos, posIter->first - lastPos) << prefix;
lastPos = posIter->first;
posIter++;
}
processedStr << processed.substr(lastPos, processed.size() - lastPos);
-
+
processed = processedStr.str();
processedStr.clear();
processedStr.str("");
@@ -494,12 +494,12 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s
posIter++;
}
processedStr << processed.substr(lastPos, processed.size() - lastPos);
-
+
processed = processedStr.str();
processedStr.clear();
processedStr.str("");
}
-
+
return processed;
}
@@ -507,7 +507,7 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s
// PromelaParser parsed(expr);
// std::list<size_t> posList = getTokenPositions(expr, PML_NAME, parsed.ast);
// posList.sort();
-//
+//
// std::stringstream prefixed;
// std::list<size_t>::iterator posIter = posList.begin();
// size_t lastPos = 0;
@@ -516,18 +516,18 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s
// lastPos = *posIter;
// posIter++;
// }
-//
+//
// prefixed << expr.substr(lastPos, expr.size() - lastPos);
// return prefixed.str();
//}
-
+
std::list<std::pair<size_t, size_t> > PromelaCodeAnalyzer::getTokenPositions(const std::string& expr, int type, PromelaParserNode* ast) {
std::list<std::pair<size_t, size_t> > posList;
if (ast->type == type && ast->loc != NULL) {
// ast->dump();
if (type == PML_NAME && ast->parent &&
- ((ast->parent->type == PML_CMPND && ast->parent->operands.front() != ast) ||
- (ast->parent->parent && ast->parent->type == PML_VAR_ARRAY && ast->parent->parent->type == PML_CMPND))) {
+ ((ast->parent->type == PML_CMPND && ast->parent->operands.front() != ast) ||
+ (ast->parent->parent && ast->parent->type == PML_VAR_ARRAY && ast->parent->parent->type == PML_CMPND))) {
// field in a compound
} else {
if (ast->loc->firstLine == 0) {
@@ -549,7 +549,7 @@ std::list<std::pair<size_t, size_t> > PromelaCodeAnalyzer::getTokenPositions(con
}
return posList;
}
-
+
std::set<std::string> PromelaCodeAnalyzer::getEventsWithPrefix(const std::string& prefix) {
std::set<std::string> eventNames;
std::list<TrieNode*> trieNodes = _eventTrie.getWordsWithPrefix(prefix);
@@ -588,14 +588,14 @@ void ChartToPromela::writeEvents(std::ostream& stream) {
void ChartToPromela::writeStates(std::ostream& stream) {
stream << "/* state name identifiers */" << std::endl;
-
+
std::map<std::string, GlobalState*>::iterator stateIter = _activeConf.begin();
while(stateIter != _activeConf.end()) {
stream << "#define " << "s" << stateIter->second->activeIndex << " " << stateIter->second->activeIndex;
stream << " /* from \"" << stateIter->first << "\" */" << std::endl;
stateIter++;
}
-
+
// for (int i = 0; i < _globalConf.size(); i++) {
// stream << "#define " << "s" << i << " " << i;
// stream << " /* from \"" << ATTR_CAST(_globalStates[i], "id") << "\" */" << std::endl;
@@ -637,7 +637,7 @@ void ChartToPromela::writeHistoryArrays(std::ostream& stream) {
histNameIter++;
}
}
-
+
void ChartToPromela::writeTypeDefs(std::ostream& stream) {
stream << "/* type definitions */" << std::endl;
PromelaCodeAnalyzer::PromelaTypedef typeDefs = _analyzer->getTypes();
@@ -672,7 +672,7 @@ void ChartToPromela::writeTypeDefs(std::ostream& stream) {
stream << " int delay;" << std::endl;
#if NEW_DELAY_RESHUFFLE
#else
- stream << " int seqNr;" << std::endl;
+ stream << " int seqNr;" << std::endl;
#endif
}
stream << " int name;" << std::endl;
@@ -682,9 +682,9 @@ void ChartToPromela::writeTypeDefs(std::ostream& stream) {
}
for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator tIter = currDef.types.begin(); tIter != currDef.types.end(); tIter++) {
if (currDef.name.compare("_event_t") == 0 && (tIter->first.compare("name") == 0 ||
- tIter->first.compare("seqNr") == 0 ||
- tIter->first.compare("invokeid") == 0 ||
- tIter->first.compare("delay") == 0)) { // special treatment for _event
+ tIter->first.compare("seqNr") == 0 ||
+ tIter->first.compare("invokeid") == 0 ||
+ tIter->first.compare("delay") == 0)) { // special treatment for _event
continue;
}
if (currDef.name.compare("_x_t") == 0 && tIter->first.compare("states") == 0) {
@@ -729,7 +729,7 @@ std::string ChartToPromela::declForRange(const std::string& identifier, long min
return "int " + identifier;
return "short " + identifier;
}
-
+
// type is definitely positive
if (nativeOnly) {
if (maxValue > 32767)
@@ -768,7 +768,7 @@ std::string ChartToPromela::conditionForHistoryTransition(const GlobalTransition
FlatStateIdentifier flatSource(transition->source);
FlatStateIdentifier flatTarget(transition->destination);
std::string condition;
-
+
return condition;
}
@@ -777,22 +777,22 @@ std::string ChartToPromela::conditionalizeForHist(GlobalTransition* transition,
transitions.insert(transition);
return conditionalizeForHist(transitions);
}
-
+
std::string ChartToPromela::conditionalizeForHist(const std::set<GlobalTransition*>& transitions, int indent) {
std::stringstream condition;
std::string memberSep;
-
+
std::set<std::map<std::string, std::list<std::string> > > histSeen;
-
+
for (std::set<GlobalTransition*>::const_iterator transIter = transitions.begin(); transIter != transitions.end(); transIter++) {
if ((*transIter)->histTargets.size() == 0) // there are no history transitions in here!
continue;
-
+
std::map<std::string, std::list<std::string> > relevantHist;
std::map<std::string, std::list<std::string> > currentHist;
FlatStateIdentifier flatSource((*transIter)->source);
currentHist = flatSource.getHistory();
-
+
std::set<std::string>::iterator histTargetIter = (*transIter)->histTargets.begin();
while(histTargetIter != (*transIter)->histTargets.end()) {
if (currentHist.find(*histTargetIter) != currentHist.end()) {
@@ -802,17 +802,17 @@ std::string ChartToPromela::conditionalizeForHist(const std::set<GlobalTransitio
}
if (relevantHist.size() == 0)
continue;
-
+
if (histSeen.find(relevantHist) != histSeen.end())
continue;
histSeen.insert(relevantHist);
-
+
std::string itemSep;
std::map<std::string, std::list<std::string> >::iterator relevanthistIter = relevantHist.begin();
if (relevantHist.size() > 0)
condition << memberSep;
-
+
while(relevanthistIter != relevantHist.end()) {
std::list<std::string>::iterator histItemIter = relevanthistIter->second.begin();
while(histItemIter != relevanthistIter->second.end()) {
@@ -849,7 +849,7 @@ std::string ChartToPromela::conditionalizeForHist(const std::set<GlobalTransitio
// NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState);
// currState = _globalConf[ATTR_CAST(transitions[0], "target")];
// }
-//
+//
// return content;
//}
@@ -859,53 +859,53 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
padding += " ";
}
std::list<GlobalTransition*>::const_iterator histIter;
-
- if (envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
- stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## */ " << std::endl;
-
- } else {
-
- stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## " << std::endl;
- FlatStateIdentifier flatActiveSource(transition->source);
- stream << " from state: ";
- PRETTY_PRINT_LIST(stream, flatActiveSource.getActive());
- stream << std::endl;
- // stream << " with history: " << flatActiveSource.getFlatHistory() << std::endl;
- stream << " ----- on event: " << (transition->eventDesc.size() > 0 ? transition->eventDesc : "SPONTANEOUS") << " --" << std::endl;
- stream << " to state: ";
- std::set<FlatStateIdentifier> destinations;
- destinations.insert(FlatStateIdentifier(transition->destination));
- histIter = transition->historyTrans.begin();
- while(histIter != transition->historyTrans.end()) {
- destinations.insert(FlatStateIdentifier((*histIter)->destination));
- histIter++;
- }
- std::string seperator = "";
- for (std::set<FlatStateIdentifier>::iterator destIter = destinations.begin(); destIter != destinations.end(); destIter++) {
- stream << seperator;
- PRETTY_PRINT_LIST(stream, destIter->getActive());
- stream << " with " << (destIter->getFlatHistory().size() > 0 ? destIter->getFlatHistory() : "no history");
- seperator = "\n ";
- }
- stream << std::endl;
-
- stream << "############################### */" << std::endl;
- }
- stream << std::endl;
+
+ if (envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
+ stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## */ " << std::endl;
+
+ } else {
+
+ stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## " << std::endl;
+ FlatStateIdentifier flatActiveSource(transition->source);
+ stream << " from state: ";
+ PRETTY_PRINT_LIST(stream, flatActiveSource.getActive());
+ stream << std::endl;
+ // stream << " with history: " << flatActiveSource.getFlatHistory() << std::endl;
+ stream << " ----- on event: " << (transition->eventDesc.size() > 0 ? transition->eventDesc : "SPONTANEOUS") << " --" << std::endl;
+ stream << " to state: ";
+ std::set<FlatStateIdentifier> destinations;
+ destinations.insert(FlatStateIdentifier(transition->destination));
+ histIter = transition->historyTrans.begin();
+ while(histIter != transition->historyTrans.end()) {
+ destinations.insert(FlatStateIdentifier((*histIter)->destination));
+ histIter++;
+ }
+ std::string seperator = "";
+ for (std::set<FlatStateIdentifier>::iterator destIter = destinations.begin(); destIter != destinations.end(); destIter++) {
+ stream << seperator;
+ PRETTY_PRINT_LIST(stream, destIter->getActive());
+ stream << " with " << (destIter->getFlatHistory().size() > 0 ? destIter->getFlatHistory() : "no history");
+ seperator = "\n ";
+ }
+ stream << std::endl;
+
+ stream << "############################### */" << std::endl;
+ }
+ stream << std::endl;
stream << padding << "skip;" << std::endl;
stream << padding << "d_step {" << std::endl;
if (_writeTransitionPrintfs)
stream << padding << " printf(\"Taking Transition " << _prefix << "t" << transition->index << "\\n\");" << std::endl;
-
+
padding += " ";
indent++;
-
+
// iterators of history transitions executable content
std::map<GlobalTransition*, std::pair<GlobalTransition::Action::iter_t, GlobalTransition::Action::iter_t> > actionIters;
std::map<GlobalTransition*, std::set<GlobalTransition::Action> > actionsInTransition;
typedef std::map<GlobalTransition*, std::pair<GlobalTransition::Action::iter_t, GlobalTransition::Action::iter_t> > actionIters_t;
-
+
histIter = transition->historyTrans.begin();
while(histIter != transition->historyTrans.end()) {
actionIters.insert(std::make_pair((*histIter), std::make_pair((*histIter)->actions.begin(), (*histIter)->actions.end())));
@@ -922,16 +922,16 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
}
// std::copy(transition->actions.begin(), transition->actions.end(), std::inserter(actionsInTransition[transition], actionsInTransition[transition].begin()));
-
+
// GlobalTransition::Action action;
std::set<GlobalTransition*> allBut;
std::list<ExecContentSeqItem> ecSeq;
-
+
for (std::list<GlobalTransition::Action>::const_iterator actionIter = transition->actions.begin(); actionIter != transition->actions.end(); actionIter++) {
// for every executable content in base transition
const GlobalTransition::Action& baseAction = *actionIter;
allBut.clear();
-
+
for (actionIters_t::iterator histActionIter = actionIters.begin(); histActionIter != actionIters.end(); histActionIter++) {
// iterate every history transition
GlobalTransition* histTrans = histActionIter->first;
@@ -945,7 +945,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
if (baseAction != histAction && !baseAction.raiseDone) {
// std::cout << baseAction << std::endl;
// std::cout << histAction << std::endl;
-
+
// executable content differs - will given executable content appear later in history?
if (actionsInTransition[histTrans].find(baseAction) != actionsInTransition[histTrans].end()) {
// yes -> write all exec content exclusive to this history transition until base executable content
@@ -964,7 +964,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
histActionIter->second.first++;
}
}
-
+
if (allBut.empty()) {
// everyone has the current actionIter one behind the base action
ecSeq.push_back(ExecContentSeqItem(ExecContentSeqItem::EXEC_CONTENT_EVERY, NULL, baseAction));
@@ -973,7 +973,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
ecSeq.push_back(ExecContentSeqItem(ExecContentSeqItem::EXEC_CONTENT_ALL_BUT, allBut, baseAction));
}
}
-
+
// see what remains in history transitions and add as exclusive
for (actionIters_t::iterator histActionIter = actionIters.begin(); histActionIter != actionIters.end(); histActionIter++) {
GlobalTransition* histTrans = histActionIter->first;
@@ -987,7 +987,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
bool isConditionalized = false;
bool wroteHistoryAssignments = false;
-
+
for (std::list<ExecContentSeqItem>::const_iterator ecIter = ecSeq.begin(); ecIter != ecSeq.end(); ecIter++) {
const GlobalTransition::Action& action = ecIter->action;
@@ -998,11 +998,11 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
wroteHistoryAssignments = true;
}
}
-
+
if (!_analyzer->usesInPredicate() && (action.entered || action.exited)) {
continue;
}
-
+
if (!isConditionalized && ecIter->type == ExecContentSeqItem::EXEC_CONTENT_ONLY_FOR) {
// assert(!wroteHistoryAssignments); // we need to move assignments after dispatching?
stream << padding << "if" << std::endl;
@@ -1031,18 +1031,18 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
case ExecContentSeqItem::EXEC_CONTENT_ONLY_FOR:
std::cout << "ONLY_FOR" << std::endl;
break;
-
- default:
- break;
+
+ default:
+ break;
}
#endif
-
+
if (action.exited) {
// we left a state
stream << padding << _prefix << "_x.states[" << _analyzer->macroForLiteral(ATTR(action.exited, "id")) << "] = false; " << std::endl;
// continue;
}
-
+
if (action.entered) {
// we entered a state
stream << padding << _prefix << "_x.states[" << _analyzer->macroForLiteral(ATTR(action.entered, "id")) << "] = true; " << std::endl;
@@ -1055,7 +1055,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
writeExecutableContent(stream, action.transition, indent);
// continue;
}
-
+
if (action.onExit) {
// std::cout<< action.onExit << std::endl;
// executable content from an onexit element
@@ -1064,7 +1064,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
writeExecutableContent(stream, action.onExit, indent);
// continue;
}
-
+
if (action.onEntry) {
// executable content from an onentry element
if (action.onEntry.getParentNode()) // this should not be necessary?
@@ -1083,7 +1083,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
if (action.invoke) {
// an invoke element
-
+
if (_machines.find(action.invoke) != _machines.end()) {
stream << padding << _prefix << "start!" << _analyzer->macroForLiteral(_machines[action.invoke]->_invokerid) << ";" << std::endl;
} else {
@@ -1093,7 +1093,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
}
}
-
+
if (action.uninvoke) {
if (_machines.find(action.uninvoke) != _machines.end()) {
stream << padding << "do" << std::endl;
@@ -1111,7 +1111,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
}
}
}
-
+
if (isConditionalized) {
// peek into next content and see if same conditions apply -> keep conditionalization
bool sameCondition = false;
@@ -1120,7 +1120,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
if (nextIter != ecSeq.end() && ecIter->type == nextIter->type && ecIter->transitions == nextIter->transitions) {
sameCondition = true;
}
-
+
if (!sameCondition) {
padding = padding.substr(2);
indent--;
@@ -1137,7 +1137,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
}
}
}
-
+
if (!wroteHistoryAssignments) {
writeHistoryAssignments(stream, transition, indent);
wroteHistoryAssignments = true;
@@ -1158,42 +1158,42 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
origNewState = _activeConf[transition->activeDestination];
bool hasHistoryTarget = false;
-
+
for (std::map<GlobalState*, std::set<GlobalTransition*> >::const_iterator histTargetIter = histTargets.begin(); histTargetIter != histTargets.end(); histTargetIter++) {
GlobalState* histNewState = histTargetIter->first;
if (histNewState == origNewState)
continue;
stream << padding << "if" << std::endl;
- if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
- stream << "/* to state ";
- FlatStateIdentifier flatActiveDest(histNewState->activeId);
- PRETTY_PRINT_LIST(stream, flatActiveDest.getActive());
- stream << " via history */" << std::endl;
- }
+ if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
+ stream << "/* to state ";
+ FlatStateIdentifier flatActiveDest(histNewState->activeId);
+ PRETTY_PRINT_LIST(stream, flatActiveDest.getActive());
+ stream << " via history */" << std::endl;
+ }
- stream << padding << ":: " << conditionalizeForHist(histTargetIter->second) << " -> " << _prefix << "s = s" << histNewState->activeIndex << ";" << std::endl;
+ stream << padding << ":: " << conditionalizeForHist(histTargetIter->second) << " -> " << _prefix << "s = s" << histNewState->activeIndex << ";" << std::endl;
// writeTransitionClosure(stream, *histTargetIter->second.begin(), histNewState, indent + 1); // is this correct for everyone in set?
hasHistoryTarget = true;
}
-
+
origNewState = _activeConf[transition->activeDestination];
FlatStateIdentifier flatActiveDest(transition->activeDestination);
assert(origNewState != NULL);
-
- if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
- stream << "/* to state ";
- PRETTY_PRINT_LIST(stream, flatActiveDest.getActive());
- stream << " */" << std::endl;
- }
+
+ if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
+ stream << "/* to state ";
+ PRETTY_PRINT_LIST(stream, flatActiveDest.getActive());
+ stream << " */" << std::endl;
+ }
if (hasHistoryTarget) {
stream << padding << ":: else -> ";
padding += " ";
indent++;
}
-
+
stream << padding << _prefix << "s = s" << origNewState->activeIndex << ";" << std::endl;
@@ -1204,17 +1204,17 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra
stream << padding << "fi;" << std::endl;
}
- TRANSITION_TRACE(transition, false);
-
+ TRANSITION_TRACE(transition, false);
+
padding = padding.substr(2);
- stream << padding << "}" << std::endl;
+ stream << padding << "}" << std::endl;
- // moved up here for goto from d_step
+ // moved up here for goto from d_step
writeTransitionClosure(stream, transition, origNewState, indent-1);
_perfTransProcessed++;
_perfTransTotal++;
-
+
DUMP_STATS(false);
}
@@ -1224,30 +1224,30 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit
for (int i = 0; i < indent; i++) {
padding += " ";
}
-
+
if (transition->historyTrans.size() == 0)
return;
-
+
// GlobalState to *changed* history configuration
std::list<HistoryTransitionClass> histClasses;
std::set<GlobalTransition*> allTrans;
allTrans.insert(transition);
allTrans.insert(transition->historyTrans.begin(), transition->historyTrans.end());
-
+
// iterate all transitions
std::set<GlobalTransition*>::iterator transIter = allTrans.begin();
while(transIter != allTrans.end()) {
histClasses.push_back(HistoryTransitionClass(*transIter));
transIter++;
}
-
+
// nothing to do here
if (histClasses.size() == 0)
return;
-
+
// std::cout << histClasses.size() << " / ";
-
+
// now sort into equivalence classes
std::list<HistoryTransitionClass>::iterator outerHistClassIter = histClasses.begin();
std::list<HistoryTransitionClass>::iterator innerHistClassIter = histClasses.begin();
@@ -1257,11 +1257,11 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit
// iterate inner iter for every outer iter and see if we can merge
innerHistClassIter = outerHistClassIter;
innerHistClassIter++;
-
+
while(innerHistClassIter != histClasses.end()) {
// can we merge the inner class into the outer one?
HistoryTransitionClass& innerClass = *innerHistClassIter;
-
+
if (outerClass.matches(innerClass)) {
outerClass.merge(innerClass);
histClasses.erase(innerHistClassIter++);
@@ -1269,7 +1269,7 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit
innerHistClassIter++;
}
}
-
+
_perfHistoryProcessed++;
_perfHistoryTotal++;
@@ -1316,7 +1316,7 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit
forgetIter++;
}
}
-
+
{
std::map<std::string, std::set<std::string> >::iterator rememberIter = histClassIter->toRemember.begin();
while(rememberIter != histClassIter->toRemember.end()) {
@@ -1338,11 +1338,11 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit
if (histClassIter == defaultHistClassIter) {
break;
}
-
+
histClassIter++;
}
assert(nrMembers == allTrans.size());
-
+
}
HistoryTransitionClass::HistoryTransitionClass(GlobalTransition* transition) {
@@ -1357,13 +1357,13 @@ HistoryTransitionClass::HistoryTransitionClass(const std::string& from, const st
void HistoryTransitionClass::init(const std::string& from, const std::string& to) {
if (from == to)
return;
-
+
FlatStateIdentifier flatSource(from);
FlatStateIdentifier flatTarget(to);
-
+
std::map<std::string, std::set<std::string> > activeBefore = flatSource.getHistorySets();
std::map<std::string, std::set<std::string> > activeAfter = flatTarget.getHistorySets();
-
+
std::map<std::string, std::set<std::string> >::const_iterator targetHistIter = activeAfter.begin();
while(targetHistIter != activeAfter.end()) {
// for every history state in target, see if it existed in source
@@ -1387,7 +1387,7 @@ void HistoryTransitionClass::init(const std::string& from, const std::string& to
}
sourceHistMemberIter++;
}
-
+
std::set<std::string>::const_iterator targetHistMemberIter = activeAfter.at(targetHistIter->first).begin();
while(targetHistMemberIter != activeAfter.at(targetHistIter->first).end()) {
// iterate member of target history and see if it is new
@@ -1401,7 +1401,7 @@ void HistoryTransitionClass::init(const std::string& from, const std::string& to
targetHistIter++;
}
}
-
+
bool HistoryTransitionClass::matches(const HistoryTransitionClass& other) {
/* does the given transition match this one?:
@@ -1409,12 +1409,12 @@ bool HistoryTransitionClass::matches(const HistoryTransitionClass& other) {
2. everything forgot has to be forgotten as well or already disabled
and vice versa
*/
-
+
std::map<std::string, std::set<std::string> > tmp;
-
+
typedef std::map<std::string, std::set<std::string> >::const_iterator histIter_t;
typedef std::set<std::string>::const_iterator histMemberIter_t;
-
+
// we will remember these - will the other try to forget them?
INTERSECT_MAPS(toRemember, other.toForget, tmp);
if (tmp.size() > 0)
@@ -1438,9 +1438,9 @@ bool HistoryTransitionClass::matches(const HistoryTransitionClass& other) {
void HistoryTransitionClass::merge(const HistoryTransitionClass& other) {
members.insert(other.members.begin(), other.members.end());
-
+
std::map<std::string, std::set<std::string> >::const_iterator histIter;
-
+
histIter = other.toRemember.begin();
while(histIter != other.toRemember.end()) {
toRemember[histIter->first].insert(histIter->second.begin(), histIter->second.end());
@@ -1460,7 +1460,7 @@ void HistoryTransitionClass::merge(const HistoryTransitionClass& other) {
}
}
-
+
void ChartToPromela::writeTransitionClosure(std::ostream& stream, GlobalTransition* transition, GlobalState* state, int indent) {
std::string padding;
for (int i = 0; i < indent; i++) {
@@ -1491,12 +1491,12 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
for (int i = 0; i < indent; i++) {
padding += " ";
}
-
+
if (node.getNodeType() == Node_base::TEXT_NODE) {
if (boost::trim_copy(node.getNodeValue()).length() > 0)
stream << beautifyIndentation(ADAPT_SRC(node.getNodeValue()), indent) << std::endl;
}
-
+
if (node.getNodeType() != Node_base::ELEMENT_NODE)
return; // skip anything not an element
@@ -1515,17 +1515,17 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
for (int i = 0; i < scriptText.size(); i++) {
stream << ADAPT_SRC(beautifyIndentation(scriptText[i].getNodeValue(), indent)) << std::endl;
}
-
+
} else if(TAGNAME(nodeElem) == "log") {
std::string label = (HAS_ATTR(nodeElem, "label") ? ATTR(nodeElem, "label") : "");
std::string expr = (HAS_ATTR(nodeElem, "expr") ? ADAPT_SRC(ATTR(nodeElem, "expr")) : "");
std::string trimmedExpr = boost::trim_copy(expr);
bool isStringLiteral = (boost::starts_with(trimmedExpr, "\"") || boost::starts_with(trimmedExpr, "'"));
-
+
std::string formatString;
std::string varString;
std::string seperator;
-
+
if (label.size() > 0) {
if (expr.size() > 0) {
formatString += label + ": ";
@@ -1533,20 +1533,20 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
formatString += label;
}
}
-
+
if (isStringLiteral) {
formatString += expr;
} else if (expr.size() > 0) {
formatString += "%d";
varString += seperator + expr;
}
-
+
if (varString.length() > 0) {
stream << padding << "printf(\"" + formatString + "\", " + varString + ");" << std::endl;
} else {
stream << padding << "printf(\"" + formatString + "\");" << std::endl;
}
-
+
} else if(TAGNAME(nodeElem) == "foreach") {
stream << padding << "for (" << _prefix << (HAS_ATTR(nodeElem, "index") ? ATTR(nodeElem, "index") : "_index") << " in " << _prefix << ATTR(nodeElem, "array") << ") {" << std::endl;
if (HAS_ATTR(nodeElem, "item")) {
@@ -1560,23 +1560,23 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
// if (HAS_ATTR(nodeElem, "index"))
// stream << padding << " " << _prefix << ATTR(nodeElem, "index") << "++;" << std::endl;
stream << padding << "}" << std::endl;
-
+
} else if(TAGNAME(nodeElem) == "if") {
NodeSet<std::string> condChain;
condChain.push_back(node);
condChain.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "elseif", node));
condChain.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "else", node));
-
+
writeIfBlock(stream, condChain, indent);
-
+
} else if(TAGNAME(nodeElem) == "assign") {
NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, nodeElem, true);
assert(assignTexts.size() > 0);
stream << beautifyIndentation(ADAPT_SRC(boost::trim_copy(assignTexts[0].getNodeValue())), indent) << std::endl;
-
+
} else if(TAGNAME(nodeElem) == "send" || TAGNAME(nodeElem) == "raise") {
std::string targetQueue;
- std::string insertOp = "!";
+ std::string insertOp = "!";
if (TAGNAME(nodeElem) == "raise") {
targetQueue = _prefix + "iQ";
} else if (!HAS_ATTR(nodeElem, "target")) {
@@ -1595,7 +1595,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
if (targetQueue.length() > 0) {
// this is for our external queue
std::string event;
-
+
if (HAS_ATTR(nodeElem, "event")) {
event = _analyzer->macroForLiteral(ATTR(nodeElem, "event"));
} else if (HAS_ATTR(nodeElem, "eventexpr")) {
@@ -1603,10 +1603,10 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
}
if (_analyzer->usesComplexEventStruct()) {
stream << padding << "{" << std::endl;
- std::string typeReset = _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), padding + " ");
- std::stringstream typeAssignSS;
- typeAssignSS << padding << " tmpE.name = " << event << ";" << std::endl;
-
+ std::string typeReset = _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), padding + " ");
+ std::stringstream typeAssignSS;
+ typeAssignSS << padding << " tmpE.name = " << event << ";" << std::endl;
+
if (HAS_ATTR(nodeElem, "idlocation")) {
typeAssignSS << padding << " /* idlocation */" << std::endl;
typeAssignSS << padding << " _lastSendId = _lastSendId + 1;" << std::endl;
@@ -1619,11 +1619,11 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
} else if (HAS_ATTR(nodeElem, "id")) {
typeAssignSS << padding << " tmpE.sendid = " << _analyzer->macroForLiteral(ATTR(nodeElem, "id")) << ";" << std::endl;
}
-
+
if (_invokerid.length() > 0) { // do not send invokeid if we send / raise to ourself
typeAssignSS << padding << " tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl;
}
-
+
if (_analyzer->usesEventField("origintype") && !boost::ends_with(targetQueue, "iQ")) {
typeAssignSS << padding << " tmpE.origintype = " << _analyzer->macroForLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor") << ";" << std::endl;
}
@@ -1631,7 +1631,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
if (_analyzer->usesEventField("delay")) {
#if NEW_DELAY_RESHUFFLE
#else
- insertOp += "!";
+ insertOp += "!";
typeAssignSS << padding << " _lastSeqId = _lastSeqId + 1;" << std::endl;
#endif
if (HAS_ATTR_CAST(nodeElem, "delay")) {
@@ -1643,7 +1643,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
}
#if NEW_DELAY_RESHUFFLE
#else
- typeAssignSS << padding << " tmpE.seqNr = _lastSeqId;" << std::endl;
+ typeAssignSS << padding << " tmpE.seqNr = _lastSeqId;" << std::endl;
#endif
}
@@ -1651,7 +1651,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
std::string eventType = (targetQueue.compare("iQ!") == 0 ? _analyzer->macroForLiteral("internal") : _analyzer->macroForLiteral("external"));
typeAssignSS << padding << " tmpE.type = " << eventType << ";" << std::endl;
}
-
+
NodeSet<std::string> sendParams = filterChildElements(_nsInfo.xmlNSPrefix + "param", nodeElem);
NodeSet<std::string> sendContents = filterChildElements(_nsInfo.xmlNSPrefix + "content", nodeElem);
std::string sendNameList = ATTR(nodeElem, "namelist");
@@ -1669,7 +1669,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
nameIter++;
}
}
-
+
if (sendParams.size() == 0 && sendNameList.size() == 0 && sendContents.size() > 0) {
Element<std::string> contentElem = Element<std::string>(sendContents[0]);
if (contentElem.hasChildNodes() && contentElem.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
@@ -1683,8 +1683,8 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
typeAssignSS << padding << " tmpE.data = " << ADAPT_SRC(ATTR(contentElem, "expr")) << ";" << std::endl;
}
}
-
- // remove all fields from typeReset that are indeed set by typeAssign
+
+ // remove all fields from typeReset that are indeed set by typeAssign
// for (std::string assigned; std::getline(typeAssignSS, assigned); ) {
// assigned = assigned.substr(0, assigned.find('='));
// assigned = assigned.substr(assigned.find('.'));
@@ -1697,28 +1697,28 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
// }
// stream << typeAssignSS.str();
- std::istringstream typeResetSS (typeReset);
- for (std::string reset; std::getline(typeResetSS, reset); ) {
- std::string resetField = reset.substr(0, reset.find('='));
- resetField = resetField.substr(resetField.find('.'));
- for (std::string assigned; std::getline(typeAssignSS, assigned); ) {
- if (boost::find_first(resetField, assigned)) {
- break;
- }
- }
- stream << reset << std::endl;
- }
- stream << typeAssignSS.str();
-
-
+ std::istringstream typeResetSS (typeReset);
+ for (std::string reset; std::getline(typeResetSS, reset); ) {
+ std::string resetField = reset.substr(0, reset.find('='));
+ resetField = resetField.substr(resetField.find('.'));
+ for (std::string assigned; std::getline(typeAssignSS, assigned); ) {
+ if (boost::find_first(resetField, assigned)) {
+ break;
+ }
+ }
+ stream << reset << std::endl;
+ }
+ stream << typeAssignSS.str();
+
+
stream << padding << " " << targetQueue << insertOp <<"tmpE;" << std::endl;
-
+
#if NEW_DELAY_RESHUFFLE
- if (_analyzer->usesEventField("delay") && !boost::ends_with(targetQueue, "iQ")) {
- stream << padding << " insertWithDelay(" << targetQueue << ");" << std::endl;
- }
+ if (_analyzer->usesEventField("delay") && !boost::ends_with(targetQueue, "iQ")) {
+ stream << padding << " insertWithDelay(" << targetQueue << ");" << std::endl;
+ }
#endif
-
+
stream << padding << "}" << std::endl;
} else {
stream << padding << targetQueue << insertOp << event << ";" << std::endl;
@@ -1742,7 +1742,7 @@ PromelaInlines::~PromelaInlines() {
std::list<PromelaInline*> PromelaInlines::getRelatedTo(const Arabica::DOM::Node<std::string>& node, PromelaInline::PromelaInlineType type) {
std::list<PromelaInline*> related;
-
+
std::map<Arabica::DOM::Node<std::string>, std::list<PromelaInline*> >::iterator inlIter = inlines.begin();
while (inlIter != inlines.end()) {
std::list<PromelaInline*>::iterator pmlIter = inlIter->second.begin();
@@ -1761,7 +1761,7 @@ std::list<PromelaInline*> PromelaInlines::getRelatedTo(const Arabica::DOM::Node<
std::list<PromelaInline*> PromelaInlines::getAllOfType(uint32_t type) {
std::list<PromelaInline*> related;
-
+
std::map<Arabica::DOM::Node<std::string>, std::list<PromelaInline*> >::iterator inlIter = inlines.begin();
while (inlIter != inlines.end()) {
std::list<PromelaInline*>::iterator pmlIter = inlIter->second.begin();
@@ -1782,7 +1782,7 @@ PromelaInline::PromelaInline(const Arabica::DOM::Node<std::string>& node) : prev
std::stringstream ssLine(node.getNodeValue());
std::string line;
-
+
while(std::getline(ssLine, line)) {
// skip to first promela line
boost::trim(line);
@@ -1812,13 +1812,13 @@ PromelaInline::PromelaInline(const Arabica::DOM::Node<std::string>& node) : prev
std::stringstream contentSS;
size_t endType = line.find_first_of(": \n");
-
+
std::string seperator;
if (endType != std::string::npos && endType + 1 < line.size()) {
contentSS << line.substr(endType + 1, line.size() - endType + 1);
seperator = "\n";
}
-
+
while(std::getline(ssLine, line)) {
boost::trim(line);
if (boost::starts_with(line, "promela")) {
@@ -1835,14 +1835,14 @@ PromelaInline::PromelaInline(const Arabica::DOM::Node<std::string>& node) : prev
PromelaInlines::PromelaInlines(const Arabica::DOM::Node<std::string>& node) {
NodeSet<std::string> levelNodes;
levelNodes.push_back(node);
-
+
size_t level = 0;
while(levelNodes.size() > 0) {
PromelaInline* predecessor = NULL;
// iterate all nodes at given level
for (int i = 0; i < levelNodes.size(); i++) {
-
+
// get all comments
NodeSet<std::string> comments = InterpreterImpl::filterChildType(Node_base::COMMENT_NODE, levelNodes[i]);
for (int j = 0; j < comments.size(); j++) {
@@ -1863,7 +1863,7 @@ PromelaInlines::PromelaInlines(const Arabica::DOM::Node<std::string>& node) {
allInlines.push_back(tmp);
}
}
-
+
levelNodes = InterpreterImpl::filterChildType(Node_base::ELEMENT_NODE, levelNodes);
level++;
}
@@ -1872,32 +1872,32 @@ PromelaInlines::PromelaInlines(const Arabica::DOM::Node<std::string>& node) {
void PromelaInline::dump() {
#if 0
switch(type) {
- case PROMELA_NIL:
- std::cerr << "PROMELA_NIL" << std::endl;
- break;
- case PROMELA_CODE:
- std::cerr << "PROMELA_CODE" << std::endl;
- break;
- case PROMELA_EVENT_SOURCE_ALL:
- std::cerr << "PROMELA_EVENT_SOURCE" << std::endl;
- break;
- case PROMELA_INVOKER:
- std::cerr << "PROMELA_INVOKER" << std::endl;
- break;
- case PROMELA_PROGRESS_LABEL:
- std::cerr << "PROMELA_PROGRESS_LABEL" << std::endl;
- break;
- case PROMELA_ACCEPT_LABEL:
- std::cerr << "PROMELA_ACCEPT_LABEL" << std::endl;
- break;
- case PROMELA_END_LABEL:
- std::cerr << "PROMELA_END_LABEL" << std::endl;
- break;
+ case PROMELA_NIL:
+ std::cerr << "PROMELA_NIL" << std::endl;
+ break;
+ case PROMELA_CODE:
+ std::cerr << "PROMELA_CODE" << std::endl;
+ break;
+ case PROMELA_EVENT_SOURCE_ALL:
+ std::cerr << "PROMELA_EVENT_SOURCE" << std::endl;
+ break;
+ case PROMELA_INVOKER:
+ std::cerr << "PROMELA_INVOKER" << std::endl;
+ break;
+ case PROMELA_PROGRESS_LABEL:
+ std::cerr << "PROMELA_PROGRESS_LABEL" << std::endl;
+ break;
+ case PROMELA_ACCEPT_LABEL:
+ std::cerr << "PROMELA_ACCEPT_LABEL" << std::endl;
+ break;
+ case PROMELA_END_LABEL:
+ std::cerr << "PROMELA_END_LABEL" << std::endl;
+ break;
}
#endif
}
-
+
void ChartToPromela::writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& condChain, int indent) {
if (condChain.size() == 0)
return;
@@ -2014,10 +2014,10 @@ void ChartToPromela::writeStrings(std::ostream& stream) {
void ChartToPromela::writeDeclarations(std::ostream& stream) {
stream << "/* global variables " << (_prefix.size() > 0 ? "for " + _prefix : "") << " */" << std::endl;
-
+
// we cannot know our event queue with nested invokers? Adding some for test422
size_t tolerance = 6;
-
+
if (_analyzer->usesComplexEventStruct()) {
// event is defined with the typedefs
stream << "_event_t " << _prefix << "_event; /* current event */" << std::endl;
@@ -2038,7 +2038,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) {
if (_machines.size() > 0) {
stream << "chan " << _prefix << "start = [" << _machines.size() << "] of {int} /* nested machines to start at next macrostep */" << std::endl;
}
-
+
if (_hasIndexLessLoops)
stream << "hidden int " << _prefix << "_index; /* helper for indexless foreach loops */" << std::endl;
@@ -2054,7 +2054,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) {
stream << "hidden _ioprocessors_t " << _prefix << "_ioprocessors;" << std::endl;
_varInitializers.push_front("_ioprocessors.scxml.location = " + (_invokerid.size() > 0 ? _analyzer->macroForLiteral(_invokerid) : "1") + ";");
}
-
+
if (_prefix.size() == 0 || _prefix == "MAIN_") {
if (_analyzer->usesEventField("sendid")) {
// stream << "chan sendIdQ = [" << MAX(_externalQueueLength + 1, 1) << "] of {_event_t} /* temporary queue to cancel events per sendidexpr */" << std::endl;
@@ -2087,33 +2087,33 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) {
// get all data elements
NodeSet<std::string> datas = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet();
-
+
// write their text content
stream << "/* data model variables" << (_prefix.size() > 0 ? " for " + _prefix : "") << " */" << std::endl;
std::set<std::string> processedIdentifiers;
-
+
// automatic types
PromelaCodeAnalyzer::PromelaTypedef allTypes = _analyzer->getTypes();
for (int i = 0; i < datas.size(); i++) {
-
+
Node<std::string> data = datas[i];
if (isInEmbeddedDocument(data))
continue;
-
+
std::string identifier = (HAS_ATTR_CAST(data, "id") ? ATTR_CAST(data, "id") : "");
std::string type = boost::trim_copy(HAS_ATTR_CAST(data, "type") ? ATTR_CAST(data, "type") : "");
-
+
_dataModelVars.insert(identifier);
if (processedIdentifiers.find(identifier) != processedIdentifiers.end())
continue;
-
+
processedIdentifiers.insert(identifier);
-
+
if (boost::starts_with(type, "string")) {
type = "int" + type.substr(6, type.length() - 6);
}
-
+
if (type.length() == 0 || type == "auto") {
if (allTypes.types.find(identifier) != allTypes.types.end()) {
type = allTypes.types[identifier].name;
@@ -2122,7 +2122,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) {
continue;
}
}
-
+
std::string arrSize;
size_t bracketPos = type.find("[");
if (bracketPos != std::string::npos) {
@@ -2133,8 +2133,8 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) {
stream << decl << ";" << std::endl;
}
-
-
+
+
// implicit and dynamic types
std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = allTypes.types.begin();
while(typeIter != allTypes.types.end()) {
@@ -2142,23 +2142,23 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) {
typeIter++;
continue;
}
-
+
if (processedIdentifiers.find(typeIter->first) != processedIdentifiers.end()) {
typeIter++;
continue;
}
-
+
if (typeIter->first == "_event" ||
- typeIter->first == "_x" ||
- typeIter->first == "_ioprocessors" ||
- typeIter->first == "_SESSIONID" ||
- typeIter->first == "_NAME") {
+ typeIter->first == "_x" ||
+ typeIter->first == "_ioprocessors" ||
+ typeIter->first == "_SESSIONID" ||
+ typeIter->first == "_NAME") {
typeIter++;
continue;
}
-
+
processedIdentifiers.insert(typeIter->first);
-
+
if (typeIter->second.types.size() == 0) {
stream << "hidden " << declForRange(_prefix + typeIter->first, typeIter->second.minValue, typeIter->second.maxValue) << ";" << std::endl;
} else {
@@ -2168,7 +2168,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) {
}
stream << std::endl;
-
+
}
void ChartToPromela::writeEventSources(std::ostream& stream) {
@@ -2189,7 +2189,7 @@ void ChartToPromela::writeStartInvoker(std::ostream& stream, const Arabica::DOM:
}
}
}
-
+
// set from params
NodeSet<std::string> invokeParams = filterChildElements(_nsInfo.xmlNSPrefix + "param", node);
for (int i = 0; i < invokeParams.size(); i++) {
@@ -2199,7 +2199,7 @@ void ChartToPromela::writeStartInvoker(std::ostream& stream, const Arabica::DOM:
stream << padding << invoker->_prefix << identifier << " = " << ADAPT_SRC(expression) << ";" << std::endl;
}
}
-
+
stream << padding << "run " << invoker->_prefix << "run() priority 20;" << std::endl;
if (HAS_ATTR_CAST(node, "idlocation")) {
stream << padding << ADAPT_SRC(ATTR_CAST(node, "idlocation")) << " = " << _analyzer->macroForLiteral(invoker->_invokerid) << ";" << std::endl;
@@ -2211,12 +2211,12 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
NodeSet<std::string> transitions;
stream << "proctype " << (_prefix.size() == 0 ? "machine_" : _prefix) << "run() {" << std::endl;
- stream << " d_step {" << std::endl;
- stream << " " << _prefix << "done = false;" << std::endl;
+ stream << " d_step {" << std::endl;
+ stream << " " << _prefix << "done = false;" << std::endl;
stream << " " << _prefix << "canceled = false;" << std::endl;
stream << " " << _prefix << "spontaneous = true;" << std::endl;
stream << " " << _prefix << "procid = _pid;" << std::endl;
- stream << " }" << std::endl;
+ stream << " }" << std::endl;
// write initial transition
// transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _startState);
// assert(transitions.size() == 1);
@@ -2229,13 +2229,13 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
}
stream << std::endl;
}
-
+
stream << std::endl << "/* transition to initial state */" << std::endl;
assert(_start->sortedOutgoing.size() == 1);
// initial transition has to be first one for control flow at start
writeTransition(stream, _start->sortedOutgoing.front(), 1);
stream << std::endl;
-
+
// every other transition
for (std::map<std::string, GlobalState*>::iterator stateIter = _activeConf.begin(); stateIter != _activeConf.end(); stateIter++) {
for (std::list<GlobalTransition*>::iterator transIter = stateIter->second->sortedOutgoing.begin(); transIter != stateIter->second->sortedOutgoing.end(); transIter++) {
@@ -2255,7 +2255,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
}
_perfStatesProcessed++;
_perfStatesTotal++;
-
+
DUMP_STATS(false);
}
DUMP_STATS(true);
@@ -2269,15 +2269,15 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
#if NEW_DELAY_RESHUFFLE
stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!" << _prefix << "_event; insertWithDelay(" << _prefix << "eQ); }" << std::endl;
#else
- stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!!" << _prefix << "_event }" << std::endl;
+ stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!!" << _prefix << "_event }" << std::endl;
#endif
- } else {
+ } else {
stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!" << _prefix << "_event }" << std::endl;
}
stream << " :: else -> break;" << std::endl;
stream << " od;" << std::endl << std::endl;
}
-
+
if (_machines.size() > 0) {
stream << " /* start pending invokers */" << std::endl;
stream << " int invokerId;" << std::endl;
@@ -2295,15 +2295,15 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
stream << " :: else -> break;" << std::endl;
stream << " od" << std::endl << std::endl;
}
-
+
if (_analyzer->usesEventField("delay") && _machinesAll->size() > 1) {
stream << "/* Determine machines with smallest delay and set their process priority */" << std::endl;
stream << " scheduleMachines();" << std::endl << std::endl;
}
-
+
std::list<PromelaInline*> eventSources = pmlInlines.getAllOfType(PromelaInline::PROMELA_EVENT_ALL_BUT |
- PromelaInline::PROMELA_EVENT_ONLY);
-
+ PromelaInline::PROMELA_EVENT_ONLY);
+
stream << " atomic {" << std::endl;
stream << "/* pop an event */" << std::endl;
stream << " if" << std::endl;
@@ -2318,7 +2318,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
PromelaEventSource es(**esIter);
std::string condition = "true";
-
+
if (LOCALNAME(es.container) == "invoke") {
if (HAS_ATTR_CAST(es.container, "id")) {
condition = _prefix + ATTR_CAST(es.container, "id") + "Running";
@@ -2329,13 +2329,13 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
condition = _prefix + "_x.states[" + _analyzer->macroForLiteral(ATTR(es.container, "id")) + "]";
}
stream << " :: " << condition << " -> {" << std::endl;
-
+
if (es.type == PromelaInline::PROMELA_EVENT_ALL_BUT) {
std::string excludeEventDescs;
for (std::list<Data>::iterator evIter = es.events.array.begin(); evIter != es.events.array.end(); evIter++) {
excludeEventDescs += " " + evIter->atom;
}
-
+
NodeSet<std::string> transitions = filterChildElements("transition", es.container, true);
std::set<std::string> eventNames;
for (int i = 0; i < transitions.size(); i++) {
@@ -2365,7 +2365,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
}
stream << " fi " << std::endl;
}
-
+
} else if (es.type == PromelaInline::PROMELA_EVENT_ONLY) {
if (es.events.array.size() > 0) {
stream << " if " << std::endl;
@@ -2383,7 +2383,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
}
stream << " }" << std::endl;
}
-
+
stream << " fi" << std::endl;
stream << " }" << std::endl;
} else {
@@ -2391,7 +2391,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
}
stream << " fi;" << std::endl << std::endl;
-
+
stream << "/* terminate if we are stopped */" << std::endl;
stream << " if" << std::endl;
stream << " :: " << _prefix << "done -> goto " << _prefix << "terminate;" << std::endl;
@@ -2425,7 +2425,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
stream << " fi;" << std::endl << std::endl;
}
}
-
+
for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator invIter = _machines.begin(); invIter != _machines.end(); invIter++) {
if (invIter->second == this) {
continue;
@@ -2437,16 +2437,16 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
stream << " :: " << invIter->second->_prefix << "done -> skip;" << std::endl;
stream << " :: " << invIter->second->_prefix << "canceled -> skip;" << std::endl;
#if NEW_DELAY_RESHUFFLE
- stream << " :: else -> { " << invIter->second->_prefix << "eQ!" << _prefix << "_event" << "; insertWithDelay(" << invIter->second->_prefix << "eQ" << "); }" << std::endl;
+ stream << " :: else -> { " << invIter->second->_prefix << "eQ!" << _prefix << "_event" << "; insertWithDelay(" << invIter->second->_prefix << "eQ" << "); }" << std::endl;
#else
- stream << " :: else -> { " << invIter->second->_prefix << "eQ!!" << _prefix << "_event" << " }" << std::endl;
+ stream << " :: else -> { " << invIter->second->_prefix << "eQ!!" << _prefix << "_event" << " }" << std::endl;
#endif
stream << " fi;" << std::endl << std::endl;
}
}
stream << std::endl;
-
+
stream << _prefix << "microStep:" << std::endl;
stream << "/* event dispatching per state */" << std::endl;
stream << " if" << std::endl;
@@ -2461,22 +2461,22 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
if (_parent != NULL) {
stream << " {" << std::endl;
- stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
+ stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
stream << " tmpE.name = " << _analyzer->macroForLiteral("done.invoke." + _invokerid) << ";" << std::endl;
if (_invokerid.length() > 0) {
stream << " tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl;
}
if (_analyzer->usesEventField("delay")) {
#if NEW_DELAY_RESHUFFLE
- stream << " " << _parent->_prefix << "eQ!tmpE;" << std::endl;
- stream << " insertWithDelay(" << _parent->_prefix << "eQ);" << std::endl;
-
+ stream << " " << _parent->_prefix << "eQ!tmpE;" << std::endl;
+ stream << " insertWithDelay(" << _parent->_prefix << "eQ);" << std::endl;
+
#else
- stream << " _lastSeqId = _lastSeqId + 1;" << std::endl;
- stream << " tmpE.seqNr = _lastSeqId;" << std::endl;
- stream << " " << _parent->_prefix << "eQ!!tmpE;" << std::endl;
+ stream << " _lastSeqId = _lastSeqId + 1;" << std::endl;
+ stream << " tmpE.seqNr = _lastSeqId;" << std::endl;
+ stream << " " << _parent->_prefix << "eQ!!tmpE;" << std::endl;
#endif
- } else {
+ } else {
stream << " " << _parent->_prefix << "eQ!tmpE;" << std::endl;
}
stream << " }" << std::endl;
@@ -2484,7 +2484,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
if (_analyzer->usesEventField("delay"))
stream << " removePendingEventsForInvoker(" << _analyzer->macroForLiteral(this->_invokerid) << ")" << std::endl;
}
-
+
stream << " }" << std::endl;
stream << "}" << std::endl;
}
@@ -2525,7 +2525,7 @@ void ChartToPromela::writeRescheduleProcess(std::ostream& stream, int indent) {
stream << padding << " fi;" << std::endl;
stream << padding << " }" << std::endl;
}
-
+
stream << padding << " :: else -> skip;" << std::endl;
stream << padding << " fi;" << std::endl;
stream << padding << " }" << std::endl;
@@ -2555,97 +2555,97 @@ void ChartToPromela::writeDetermineShortestDelay(std::ostream& stream, int inden
}
void ChartToPromela::writeInsertWithDelay(std::ostream& stream, int indent) {
- std::string padding;
- for (int i = 0; i < indent; i++) {
- padding += " ";
- }
-
- uint32_t maxExternalQueueLength = 1;
- std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator machineIter = _machinesAll->begin();
- while(machineIter != _machinesAll->end()) {
- maxExternalQueueLength = MAX(maxExternalQueueLength, machineIter->second->_externalQueueLength);
- machineIter++;
- }
-
- maxExternalQueueLength += 6;
-
- if (maxExternalQueueLength <= 1) {
- stream << padding << "/* noop for external queues with length <= 1 */" << std::endl;
- stream << padding << "inline insertWithDelay(queue) {}" << std::endl;
- }
-
- stream << padding << "hidden _event_t _iwdQ[" << maxExternalQueueLength - 1 << "];" << std::endl;
- stream << padding << "hidden int _iwdQLength = 0;" << std::endl;
- stream << padding << "hidden int _iwdIdx1 = 0;" << std::endl;
- stream << padding << "hidden int _iwdIdx2 = 0;" << std::endl;
- stream << padding << "hidden _event_t _iwdTmpE;" << std::endl;
- stream << padding << "hidden _event_t _iwdLastE;" << std::endl;
- stream << padding << "bool _iwdInserted = false;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << "/* last event in given queue is potentially at wrong position */" << std::endl;
- stream << padding << "inline insertWithDelay(queue) {" << std::endl;
- stream << padding << " d_step {" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " /* only process for non-trivial queues */" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: len(queue) > 1 -> {" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " /* move all events but last over and remember the last one */" << std::endl;
- stream << padding << " _iwdIdx1 = 0;" << std::endl;
- stream << padding << " _iwdQLength = len(queue) - 1;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " do" << std::endl;
- stream << padding << " :: _iwdIdx1 < _iwdQLength -> {" << std::endl;
- stream << padding << " queue?_iwdTmpE;" << std::endl;
- stream << padding << " _iwdQ[_iwdIdx1].name = _iwdTmpE.name;" << std::endl;
-
- stream << _analyzer->getTypeAssignment("_iwdQ[_iwdIdx1]", "_iwdTmpE", _analyzer->getType("_event"), padding + " ");
-
- stream << padding << " _iwdIdx1++;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> break;" << std::endl;
- stream << padding << " od" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " queue?_iwdLastE;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " /* _iwdQ now contains all but last item in _iwdLastE */" << std::endl;
- stream << padding << " assert(len(queue) == 0);" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " /* reinsert into queue and place _iwdLastE correctly */" << std::endl;
- stream << padding << " _iwdInserted = false;" << std::endl;
- stream << padding << " _iwdIdx2 = 0;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " do" << std::endl;
- stream << padding << " :: _iwdIdx2 < _iwdIdx1 -> {" << std::endl;
- stream << padding << " _iwdTmpE.name = _iwdQ[_iwdIdx2].name;" << std::endl;
-
- stream << _analyzer->getTypeAssignment("_iwdTmpE", "_iwdQ[_iwdIdx2]", _analyzer->getType("_event"), padding + " ");
-
- stream << padding << "" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: _iwdTmpE.delay > _iwdLastE.delay -> {" << std::endl;
- stream << padding << " queue!_iwdLastE;" << std::endl;
- stream << padding << " _iwdInserted = true;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> skip" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " queue!_iwdTmpE;" << std::endl;
- stream << padding << " _iwdIdx2++;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> break;" << std::endl;
- stream << padding << " od" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: !_iwdInserted -> queue!_iwdLastE;" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << "}" << std::endl;
+ std::string padding;
+ for (int i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+ uint32_t maxExternalQueueLength = 1;
+ std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator machineIter = _machinesAll->begin();
+ while(machineIter != _machinesAll->end()) {
+ maxExternalQueueLength = MAX(maxExternalQueueLength, machineIter->second->_externalQueueLength);
+ machineIter++;
+ }
+
+ maxExternalQueueLength += 6;
+
+ if (maxExternalQueueLength <= 1) {
+ stream << padding << "/* noop for external queues with length <= 1 */" << std::endl;
+ stream << padding << "inline insertWithDelay(queue) {}" << std::endl;
+ }
+
+ stream << padding << "hidden _event_t _iwdQ[" << maxExternalQueueLength - 1 << "];" << std::endl;
+ stream << padding << "hidden int _iwdQLength = 0;" << std::endl;
+ stream << padding << "hidden int _iwdIdx1 = 0;" << std::endl;
+ stream << padding << "hidden int _iwdIdx2 = 0;" << std::endl;
+ stream << padding << "hidden _event_t _iwdTmpE;" << std::endl;
+ stream << padding << "hidden _event_t _iwdLastE;" << std::endl;
+ stream << padding << "bool _iwdInserted = false;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << "/* last event in given queue is potentially at wrong position */" << std::endl;
+ stream << padding << "inline insertWithDelay(queue) {" << std::endl;
+ stream << padding << " d_step {" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " /* only process for non-trivial queues */" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: len(queue) > 1 -> {" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " /* move all events but last over and remember the last one */" << std::endl;
+ stream << padding << " _iwdIdx1 = 0;" << std::endl;
+ stream << padding << " _iwdQLength = len(queue) - 1;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " do" << std::endl;
+ stream << padding << " :: _iwdIdx1 < _iwdQLength -> {" << std::endl;
+ stream << padding << " queue?_iwdTmpE;" << std::endl;
+ stream << padding << " _iwdQ[_iwdIdx1].name = _iwdTmpE.name;" << std::endl;
+
+ stream << _analyzer->getTypeAssignment("_iwdQ[_iwdIdx1]", "_iwdTmpE", _analyzer->getType("_event"), padding + " ");
+
+ stream << padding << " _iwdIdx1++;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> break;" << std::endl;
+ stream << padding << " od" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " queue?_iwdLastE;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " /* _iwdQ now contains all but last item in _iwdLastE */" << std::endl;
+ stream << padding << " assert(len(queue) == 0);" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " /* reinsert into queue and place _iwdLastE correctly */" << std::endl;
+ stream << padding << " _iwdInserted = false;" << std::endl;
+ stream << padding << " _iwdIdx2 = 0;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " do" << std::endl;
+ stream << padding << " :: _iwdIdx2 < _iwdIdx1 -> {" << std::endl;
+ stream << padding << " _iwdTmpE.name = _iwdQ[_iwdIdx2].name;" << std::endl;
+
+ stream << _analyzer->getTypeAssignment("_iwdTmpE", "_iwdQ[_iwdIdx2]", _analyzer->getType("_event"), padding + " ");
+
+ stream << padding << "" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: _iwdTmpE.delay > _iwdLastE.delay -> {" << std::endl;
+ stream << padding << " queue!_iwdLastE;" << std::endl;
+ stream << padding << " _iwdInserted = true;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> skip" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " queue!_iwdTmpE;" << std::endl;
+ stream << padding << " _iwdIdx2++;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> break;" << std::endl;
+ stream << padding << " od" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: !_iwdInserted -> queue!_iwdLastE;" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << "}" << std::endl;
}
void ChartToPromela::writeAdvanceTime(std::ostream& stream, int indent) {
@@ -2653,7 +2653,7 @@ void ChartToPromela::writeAdvanceTime(std::ostream& stream, int indent) {
for (int i = 0; i < indent; i++) {
padding += " ";
}
-
+
stream << padding << "inline advanceTime(increment, queue) {" << std::endl;
stream << padding << " tmpIndex = 0;" << std::endl;
stream << padding << " do" << std::endl;
@@ -2676,7 +2676,7 @@ void ChartToPromela::writeRemovePendingEventsFromInvoker(std::ostream& stream, i
queues.push_back("eQ");
if (_allowEventInterleaving)
queues.push_back("tmpQ");
-
+
stream << "inline removePendingEventsForInvoker(invokeIdentifier) {" << std::endl;
for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator queueIter = _machinesAll->begin(); queueIter != _machinesAll->end(); queueIter++) {
for (std::list<std::string>::iterator qIter = queues.begin(); qIter != queues.end(); qIter++) {
@@ -2741,42 +2741,42 @@ void ChartToPromela::writeScheduleMachines(std::ostream& stream, int indent) {
for (int i = 0; i < indent; i++) {
padding += " ";
}
-
+
stream << padding << "inline scheduleMachines() {" << std::endl;
std::list<std::string> queues;
queues.push_back("eQ");
if (_allowEventInterleaving)
queues.push_back("tmpQ");
-
+
stream << " /* schedule state-machines with regard to their event's delay */" << std::endl;
stream << " skip;" << std::endl;
stream << " d_step {" << std::endl;
-
+
stream << std::endl << "/* determine smallest delay */" << std::endl;
stream << " int smallestDelay = 2147483647;" << std::endl;
-
+
for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator queueIter = _machinesAll->begin(); queueIter != _machinesAll->end(); queueIter++) {
for (std::list<std::string>::iterator qIter = queues.begin(); qIter != queues.end(); qIter++) {
stream << " determineSmallestDelay(smallestDelay, " << queueIter->second->_prefix << *qIter << ");" << std::endl;
}
}
// stream << " printf(\"======= Lowest delay is %d\\n\", smallestDelay);" << std::endl;
-
+
stream << std::endl << "/* prioritize processes with lowest delay or internal events */" << std::endl;
-
+
for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator queueIter = _machinesAll->begin(); queueIter != _machinesAll->end(); queueIter++) {
stream << " rescheduleProcess(smallestDelay, "
- << queueIter->second->_prefix << "procid, "
- << queueIter->second->_prefix << "iQ, "
- << queueIter->second->_prefix << "eQ";
+ << queueIter->second->_prefix << "procid, "
+ << queueIter->second->_prefix << "iQ, "
+ << queueIter->second->_prefix << "eQ";
if (_allowEventInterleaving) {
stream << ", " << queueIter->second->_prefix << "tmpQ);" << std::endl;
} else {
stream << ");" << std::endl;
}
}
-
+
stream << std::endl << "/* advance time by subtracting the smallest delay from all event delays */" << std::endl;
stream << " if" << std::endl;
stream << " :: (smallestDelay > 0) -> {" << std::endl;
@@ -2792,13 +2792,13 @@ void ChartToPromela::writeScheduleMachines(std::ostream& stream, int indent) {
stream << " set_priority(_pid, 10);" << std::endl << std::endl;
stream << padding << "}" << std::endl;
}
-
+
void ChartToPromela::writeEventDispatching(std::ostream& stream) {
for (std::map<std::string, GlobalState*>::iterator stateIter = _activeConf.begin(); stateIter != _activeConf.end(); stateIter++) {
-
+
const std::string& stateId = stateIter->first;
const GlobalState* state = stateIter->second;
-
+
stream << std::endl << "/* ### current state ";
FlatStateIdentifier flatActiveSource(stateId);
PRETTY_PRINT_LIST(stream, flatActiveSource.getActive());
@@ -2810,7 +2810,7 @@ void ChartToPromela::writeEventDispatching(std::ostream& stream) {
stream << " }" << std::endl;
}
}
-
+
void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<GlobalTransition*> transitions, int indent) {
std::string padding;
for (int i = 0; i < indent; i++) {
@@ -2840,7 +2840,7 @@ void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<Globa
stream << _prefix << "spontaneous";
} else {
std::string eventDescs = currTrans->eventDesc;
-
+
std::list<std::string> eventNames = tokenizeIdRefs(eventDescs);
std::set<std::string> eventPrefixes;
std::list<std::string>::iterator eventNameIter = eventNames.begin();
@@ -2868,7 +2868,7 @@ void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<Globa
if (eventPrefixes.size() > 1)
stream << " (";
-
+
std::string seperator;
std::set<std::string>::iterator eventIter = eventPrefixes.begin();
while(eventIter != eventPrefixes.end()) {
@@ -2892,37 +2892,37 @@ void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<Globa
}
if (currTrans->hasExecutableContent || currTrans->historyTrans.size() > 0) {
stream << " -> { " << std::endl;
- if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
- stream << "/* transition to ";
- FlatStateIdentifier flatActiveSource(currTrans->activeDestination);
- PRETTY_PRINT_LIST(stream, flatActiveSource.getActive());
- stream << " */" << std::endl;
- }
-
+ if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
+ stream << "/* transition to ";
+ FlatStateIdentifier flatActiveSource(currTrans->activeDestination);
+ PRETTY_PRINT_LIST(stream, flatActiveSource.getActive());
+ stream << " */" << std::endl;
+ }
+
if (_traceTransitions) {
for (std::set<int>::iterator transRefIter = currTrans->transitionRefs.begin(); transRefIter != currTrans->transitionRefs.end(); transRefIter++) {
stream << padding << " " << _prefix << "transitions[" << *transRefIter << "] = true; " << std::endl;
}
}
-
+
stream << padding << " goto " << _prefix << "t" << currTrans->index << ";" << std::endl;
stream << padding << "}" << std::endl;
} else {
-
+
stream << " -> {" << std::endl;
GlobalState* newState = _activeConf[currTrans->activeDestination];
assert(newState != NULL);
- if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
- stream << "/* new state ";
- FlatStateIdentifier flatActiveDest(currTrans->activeDestination);
- PRETTY_PRINT_LIST(stream, flatActiveDest.getActive());
- stream << " */" << std::endl;
- }
+ if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) {
+ stream << "/* new state ";
+ FlatStateIdentifier flatActiveDest(currTrans->activeDestination);
+ PRETTY_PRINT_LIST(stream, flatActiveDest.getActive());
+ stream << " */" << std::endl;
+ }
stream << padding << " " << _prefix << "s = s" << newState->activeIndex << ";" << std::endl;
- TRANSITION_TRACE(currTrans, false);
+ TRANSITION_TRACE(currTrans, false);
writeTransitionClosure(stream, currTrans, newState, indent + 1);
stream << padding << "}" << std::endl;
}
@@ -2947,7 +2947,7 @@ void ChartToPromela::writeMain(std::ostream& stream) {
}
stream << std::endl;
}
-
+
stream << " run " << (_prefix.size() == 0 ? "machine_" : _prefix) << "run() priority 10;" << std::endl;
stream << "}" << std::endl;
@@ -2958,18 +2958,18 @@ void ChartToPromela::initNodes() {
// some things we share with our invokers
if (_analyzer == NULL)
_analyzer = new PromelaCodeAnalyzer();
-
+
if (_machinesAll == NULL) {
_machinesAll = new std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>();
(*_machinesAll)[_scxml] = this;
}
-
+
if (_machinesAllPerId == NULL)
_machinesAllPerId = new std::map<std::string, Arabica::DOM::Node<std::string> >();
if (_parentTopMost == NULL)
_parentTopMost = this;
-
+
_internalQueueLength = getMinInternalQueueLength(MSG_QUEUE_LENGTH);
_externalQueueLength = getMinExternalQueueLength(MSG_QUEUE_LENGTH);
@@ -2984,7 +2984,7 @@ void ChartToPromela::initNodes() {
_analyzer->addEvent("done.state." + ATTR(stateElem, "id"));
}
}
-
+
{
// shorten UUID ids at invokers for readability
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true);
@@ -3003,18 +3003,18 @@ void ChartToPromela::initNodes() {
}
}
-
+
// are there nestes SCXML invokers?
{
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true);
for (int i = 0; i < invokes.size(); i++) {
if (!HAS_ATTR_CAST(invokes[i], "type") ||
- ATTR_CAST(invokes[i], "type") == "scxml" ||
- ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/#SCXMLEventProcessor" ||
- ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/") {
+ ATTR_CAST(invokes[i], "type") == "scxml" ||
+ ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/#SCXMLEventProcessor" ||
+ ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/") {
assert(HAS_ATTR_CAST(invokes[i], "id"));
Element<std::string>(invokes[i]).setAttribute("name", ATTR_CAST(invokes[i], "id"));
-
+
_prefix = "MAIN_";
Interpreter nested;
if (HAS_ATTR_CAST(invokes[i], "src")) {
@@ -3032,12 +3032,12 @@ void ChartToPromela::initNodes() {
Document<std::string> nestedDoc = domFactory.createDocument(_scxml.getOwnerDocument().getNamespaceURI(), "", 0);
Node<std::string> importRoot = nestedDoc.importNode(nestedRoot[0], true);
nestedDoc.appendChild(importRoot);
-
+
nested = Interpreter::fromDOM(nestedDoc, _nsInfo, _sourceURL);
}
-
+
// std::cout << invokes[i] << std::endl;
-
+
// we found machines but have no prefix
if (_prefix.length() == 0)
_prefix = "MAIN_";
@@ -3048,13 +3048,13 @@ void ChartToPromela::initNodes() {
_machines[invokes[i]]->_parentTopMost = _parentTopMost;
_machines[invokes[i]]->_machinesAll = _machinesAll;
(*_machinesAll)[invokes[i]] = _machines[invokes[i]];
-
+
_machines[invokes[i]]->_invokerid = ATTR_CAST(invokes[i], "id");
_machines[invokes[i]]->_prefix = ATTR_CAST(invokes[i], "id") + "_";
-
+
_analyzer->addLiteral(_machines[invokes[i]]->_invokerid);
_analyzer->addEvent("done.invoke." + _machines[invokes[i]]->_invokerid);
-
+
_machinesPerId[ATTR_CAST(invokes[i], "id")] = invokes[i];
(*_machinesAllPerId)[ATTR_CAST(invokes[i], "id")] = invokes[i];
}
@@ -3064,7 +3064,7 @@ void ChartToPromela::initNodes() {
if (_machines.size() > 0) {
_analyzer->addCode("_event.invokeid", this);
}
-
+
// gather all potential members per history
std::map<std::string, Arabica::DOM::Element<std::string> >::iterator histIter = _historyTargets.begin();
while(histIter != _historyTargets.end()) {
@@ -3079,7 +3079,7 @@ void ChartToPromela::initNodes() {
}
histIter++;
}
-
+
// initialize event trie with all events that might occur
NodeSet<std::string> internalEventNames;
internalEventNames.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet());
@@ -3105,7 +3105,7 @@ void ChartToPromela::initNodes() {
// _analyzer->addCode("bumpDownArrow = 1; _event.foo = 3; forgetSelectedServer = 1;", this);
// exit(0);
-
+
// transform data / assign json into PROMELA statements
{
NodeSet<std::string> asgn;
@@ -3115,19 +3115,19 @@ void ChartToPromela::initNodes() {
for (int i = 0; i < asgn.size(); i++) {
if (isInEmbeddedDocument(asgn[i]))
continue;
-
+
Element<std::string> asgnElem(asgn[i]);
-
+
std::string key;
if (HAS_ATTR(asgnElem, "id")) {
key = ATTR(asgnElem, "id");
} else if (HAS_ATTR(asgnElem, "location")) {
key = ATTR(asgnElem, "location");
}
-
+
if (key.length() == 0)
continue;
-
+
std::string value;
if (HAS_ATTR(asgnElem, "expr")) {
value = ATTR(asgnElem, "expr");
@@ -3143,15 +3143,15 @@ void ChartToPromela::initNodes() {
}
}
}
-
+
boost::trim(value);
if (value.size() == 0)
continue;
-
+
// remove all children, we will replae by suitable promela statements
while(asgnElem.hasChildNodes())
asgnElem.removeChild(asgnElem.getFirstChild());
-
+
std::string newValue;
Data json = Data::fromJSON(value);
if (!json.empty()) {
@@ -3161,24 +3161,24 @@ void ChartToPromela::initNodes() {
}
newValue = sanitizeCode(newValue);
_analyzer->addCode(newValue, this);
-
+
if (asgnElem.getLocalName() == "data")
_varInitializers.push_back(newValue);
Text<std::string> newText = _document.createTextNode(newValue);
asgnElem.insertBefore(newText, Node<std::string>());
}
}
-
+
// do we need sendid / invokeid?
{
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true);
NodeSet<std::string> sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", _scxml, true);
NodeSet<std::string> cancels = filterChildElements(_nsInfo.xmlNSPrefix + "cancel", _scxml, true);
-
+
if (cancels.size() > 0) {
_analyzer->addCode("_event.invokeid", this);
}
-
+
for (int i = 0; i < sends.size(); i++) {
if (HAS_ATTR_CAST(sends[i], "idlocation")) {
_analyzer->addCode("_event.sendid", this);
@@ -3195,12 +3195,12 @@ void ChartToPromela::initNodes() {
_analyzer->addCode("_event.delay", this);
#if NEW_DELAY_RESHUFFLE
#else
- _analyzer->addCode("_event.seqNr", this);
+ _analyzer->addCode("_event.seqNr", this);
#endif
}
}
}
-
+
{
// string literals for raise / send content
NodeSet<std::string> withContent;
@@ -3217,30 +3217,30 @@ void ChartToPromela::initNodes() {
}
}
}
-
+
{
// gather all inline promela comments
pmlInlines = PromelaInlines(_scxml);
if (pmlInlines.getAllOfType(PromelaInline::PROMELA_EVENT_ONLY).size() > 0)
_analyzer->addCode("_x.states", this);
-
+
// register events and string literals
for (std::list<PromelaInline*>::iterator inlIter = pmlInlines.allInlines.begin(); inlIter != pmlInlines.allInlines.end(); inlIter++) {
if ((*inlIter)->type != (PromelaInline::PROMELA_EVENT_ONLY))
continue;
-
+
Data json = Data::fromJSON((*inlIter)->content);
if (!json.empty()) {
std::list<std::string> eventNames = PromelaInlines::getEventNames(json);
for (std::list<std::string>::iterator evIter = eventNames.begin(); evIter != eventNames.end(); evIter++) {
_analyzer->addEvent(*evIter);
}
-
+
std::list<std::string> stringLiterals = PromelaInlines::getStringLiterals(json);
for (std::list<std::string>::iterator strIter = stringLiterals.begin(); strIter != stringLiterals.end(); strIter++) {
_analyzer->addLiteral(*strIter);
}
-
+
if (json.array.size() > 0) {
for (int i = 0; i < json.array.size(); i++) {
std::string expr = dataToAssignments("_event", json.item(i));
@@ -3249,7 +3249,7 @@ void ChartToPromela::initNodes() {
} else {
std::string expr = dataToAssignments("_event", json);
_analyzer->addCode(expr, this);
-
+
}
}
@@ -3449,7 +3449,7 @@ void ChartToPromela::writeProgram(std::ostream& stream) {
_traceTransitions = envVarIsTrue("USCXML_PROMELA_TRANSITION_TRACE");
_writeTransitionPrintfs = envVarIsTrue("USCXML_PROMELA_TRANSITION_DEBUG");
-
+
if (!HAS_ATTR(_scxml, "datamodel") || ATTR(_scxml, "datamodel") != "promela") {
LOG(ERROR) << "Can only convert SCXML documents with \"promela\" datamodel";
return;
@@ -3470,7 +3470,7 @@ void ChartToPromela::writeProgram(std::ostream& stream) {
stream << std::endl;
initNodes();
-
+
for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator nestedIter = _machines.begin(); nestedIter != _machines.end(); nestedIter++) {
if (nestedIter->second->_start == NULL) {
nestedIter->second->interpret();
@@ -3504,23 +3504,23 @@ void ChartToPromela::writeProgram(std::ostream& stream) {
stream << std::endl << "/* global inline functions */" << std::endl;
- if (_analyzer->usesComplexEventStruct()) {
- stream << "hidden _event_t tmpE;" << std::endl;
- } else {
- stream << "hidden int tmpE;" << std::endl;
- }
- stream << "hidden int tmpIndex;" << std::endl;
+ if (_analyzer->usesComplexEventStruct()) {
+ stream << "hidden _event_t tmpE;" << std::endl;
+ } else {
+ stream << "hidden int tmpE;" << std::endl;
+ }
+ stream << "hidden int tmpIndex;" << std::endl;
+
-
#if NEW_DELAY_RESHUFFLE
- if (_analyzer->usesEventField("delay")) {
- writeInsertWithDelay(stream);
- stream << std::endl;
- }
+ if (_analyzer->usesEventField("delay")) {
+ writeInsertWithDelay(stream);
+ stream << std::endl;
+ }
#endif
-
+
if (_analyzer->usesEventField("delay") && _machines.size() > 0) {
- writeDetermineShortestDelay(stream);
+ writeDetermineShortestDelay(stream);
stream << std::endl;
writeAdvanceTime(stream);
stream << std::endl;
@@ -3557,11 +3557,11 @@ void ChartToPromela::writeProgram(std::ostream& stream) {
nestedIter->second->writeFSM(stream);
stream << std::endl;
}
-
+
// write ltl expression for success
std::stringstream acceptingStates;
std::string seperator;
-
+
for (std::map<std::string, GlobalState*>::iterator stateIter = _activeConf.begin(); stateIter != _activeConf.end(); stateIter++) {
FlatStateIdentifier flatId(stateIter->first);
if (std::find(flatId.getActive().begin(), flatId.getActive().end(), "pass") != flatId.getActive().end()) {
diff --git a/src/uscxml/transform/ChartToPromela.h b/src/uscxml/transform/ChartToPromela.h
index 9c3c99b..d289436 100644
--- a/src/uscxml/transform/ChartToPromela.h
+++ b/src/uscxml/transform/ChartToPromela.h
@@ -52,7 +52,7 @@ public:
PromelaInline(const Arabica::DOM::Node<std::string>& node);
virtual ~PromelaInline() {}
-
+
operator bool() {
return (type != PROMELA_NIL);
}
@@ -60,13 +60,13 @@ public:
std::list<PromelaInline*> children;
PromelaInline* prevSibling;
PromelaInline* nextSibling;
-
+
virtual void dump();
virtual bool relatesTo(const Arabica::DOM::Node<std::string>& node) {
return container == node;
}
-
+
size_t level;
std::string content;
Arabica::DOM::Element<std::string> container;
@@ -78,22 +78,22 @@ protected:
class USCXML_API PromelaInlines {
public:
-
+
PromelaInlines(const Arabica::DOM::Node<std::string>& node);
PromelaInlines() {}
virtual ~PromelaInlines();
-
+
std::list<PromelaInline*> getRelatedTo(const Arabica::DOM::Node<std::string>& node, PromelaInline::PromelaInlineType type);
std::list<PromelaInline*> getAllOfType(uint32_t type);
std::map<Arabica::DOM::Node<std::string>, std::list<PromelaInline*> > inlines;
std::list<PromelaInline*> allInlines;
-
+
static std::list<std::string> getStringLiterals(const Data& data);
static std::list<std::string> getEventNames(const Data& data);
-
+
};
class USCXML_API PromelaEventSource : public PromelaInline {
@@ -104,7 +104,7 @@ public:
content = pmlInline.content;
events = Data::fromJSON(pmlInline.content);
}
-
+
virtual bool relatesTo(const Arabica::DOM::Node<std::string>& node) {
return container == node || InterpreterImpl::isDescendant(node, container);
}
@@ -128,30 +128,30 @@ public:
class USCXML_API PromelaEventSource {
public:
-
+
enum PromelaEventSourceType {
PROMELA_EVENT_SOURCE_INVALID,
PROMELA_EVENT_SOURCE_INVOKER,
PROMELA_EVENT_SOURCE_GLOBAL,
};
-
+
PromelaEventSource();
PromelaEventSource(const PromelaInline& source, PromelaCodeAnalyzer* analyzer = NULL, uint32_t externalQueueLength = 0);
-
+
void writeStart(std::ostream& stream, int indent = 0);
void writeStop(std::ostream& stream, int indent = 0);
void writeDeclarations(std::ostream& stream, int indent = 0);
void writeBody(std::ostream& stream);
-
+
operator bool() {
return type != PROMELA_EVENT_SOURCE_INVALID;
}
-
+
PromelaInline source;
std::string name;
uint32_t externalQueueLength;
uint32_t longestSequence;
-
+
Arabica::DOM::Node<std::string> container;
std::list<std::list<std::string> > sequences;
PromelaEventSourceType type;
@@ -159,7 +159,7 @@ public:
};
#endif
-
+
class USCXML_API PromelaCodeAnalyzer {
public:
class PromelaTypedef {
@@ -172,7 +172,7 @@ public:
size_t maxValue;
std::map<std::string, PromelaTypedef> types;
std::set<ChartToPromela*> occurrences;
-
+
bool operator==(const PromelaTypedef& other) const {
return name == other.name;
}
@@ -199,15 +199,15 @@ public:
bool usesEventDataField(const std::string& fieldName) {
if (usesComplexEventStruct() &&
- _typeDefs.types["_event"].types.find("data") != _typeDefs.types["_event"].types.end() &&
- _typeDefs.types["_event"].types["data"].types.find(fieldName) != _typeDefs.types["_event"].types["data"].types.end())
+ _typeDefs.types["_event"].types.find("data") != _typeDefs.types["_event"].types.end() &&
+ _typeDefs.types["_event"].types["data"].types.find(fieldName) != _typeDefs.types["_event"].types["data"].types.end())
return true;
return false;
}
- std::string getTypeAssignment(const std::string& varTo, const std::string& varFrom, const PromelaTypedef& type, const std::string padding = "");
- std::string getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding = "");
-
+ std::string getTypeAssignment(const std::string& varTo, const std::string& varFrom, const PromelaTypedef& type, const std::string padding = "");
+ std::string getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding = "");
+
bool usesInPredicate() {
return _usesInPredicate;
}
@@ -251,9 +251,9 @@ public:
return _typeDefs;
}
- PromelaTypedef& getType(const std::string& typeName) {
- return _typeDefs.types.at(typeName);
- }
+ PromelaTypedef& getType(const std::string& typeName) {
+ return _typeDefs.types.at(typeName);
+ }
protected:
std::string createMacroName(const std::string& literal);
@@ -266,7 +266,7 @@ protected:
std::map<std::string, int> _states;
std::map<std::string, int> _events;
-
+
PromelaTypedef _typeDefs;
Trie _eventTrie;
@@ -288,12 +288,12 @@ public:
};
ExecContentSeqItem(ExecContentType type, const std::set<GlobalTransition*>& transitions, const GlobalTransition::Action& action)
- : type(type), transitions(transitions), action(action) {}
+ : type(type), transitions(transitions), action(action) {}
ExecContentSeqItem(ExecContentType type, GlobalTransition* transition, const GlobalTransition::Action& action)
- : type(type), action(action) {
+ : type(type), action(action) {
transitions.insert(transition);
}
-
+
ExecContentType type;
std::set<GlobalTransition*> transitions;
GlobalTransition::Action action;
@@ -303,48 +303,48 @@ class HistoryTransitionClass {
public:
HistoryTransitionClass(GlobalTransition* transition);
HistoryTransitionClass(const std::string& from, const std::string& to);
-
+
void init(const std::string& from, const std::string& to);
-
+
std::map<std::string, std::set<std::string> > toRemember;
std::map<std::string, std::set<std::string> > toKeep;
std::map<std::string, std::set<std::string> > toForget;
-
+
std::set<GlobalTransition*> members;
void merge(const HistoryTransitionClass& other);
bool matches(const HistoryTransitionClass& other);
};
-
+
class USCXML_API ChartToPromela : public TransformerImpl, public ChartToFSM {
public:
virtual ~ChartToPromela();
static Transformer transform(const Interpreter& other);
-
+
void writeTo(std::ostream& stream);
-
+
protected:
ChartToPromela(const Interpreter& other)
- : TransformerImpl(),
- ChartToFSM(other),
- _analyzer(NULL),
- _allowEventInterleaving(false),
- _hasIndexLessLoops(false),
- _writeTransitionPrintfs(false),
- _traceTransitions(false),
- _machinesAll(NULL),
- _parent(NULL),
- _parentTopMost(NULL),
- _machinesAllPerId(NULL),
- _perfTransProcessed(0),
- _perfTransTotal(0),
- _perfHistoryProcessed(0),
- _perfHistoryTotal(0),
- _perfStatesProcessed(0),
- _perfStatesTotal(0),
- _lastTimeStamp(0) {}
+ : TransformerImpl(),
+ ChartToFSM(other),
+ _analyzer(NULL),
+ _allowEventInterleaving(false),
+ _hasIndexLessLoops(false),
+ _writeTransitionPrintfs(false),
+ _traceTransitions(false),
+ _machinesAll(NULL),
+ _parent(NULL),
+ _parentTopMost(NULL),
+ _machinesAllPerId(NULL),
+ _perfTransProcessed(0),
+ _perfTransTotal(0),
+ _perfHistoryProcessed(0),
+ _perfHistoryTotal(0),
+ _perfStatesProcessed(0),
+ _perfStatesTotal(0),
+ _lastTimeStamp(0) {}
void initNodes();
@@ -377,10 +377,10 @@ protected:
void writeStartInvoker(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, ChartToPromela* invoker, int indent = 0);
//void writeRemovePendingEventsFromInvoker(std::ostream& stream, ChartToPromela* invoker, int indent = 0, bool atomic = true);
-
+
void writeDetermineShortestDelay(std::ostream& stream, int indent = 0);
- void writeInsertWithDelay(std::ostream& stream, int indent = 0);
- void writeAdvanceTime(std::ostream& stream, int indent = 0);
+ void writeInsertWithDelay(std::ostream& stream, int indent = 0);
+ void writeAdvanceTime(std::ostream& stream, int indent = 0);
void writeRescheduleProcess(std::ostream& stream, int indent = 0);
void writeScheduleMachines(std::ostream& stream, int indent = 0);
void writeCancelEvents(std::ostream& stream, int indent = 0);
@@ -388,7 +388,7 @@ protected:
std::list<GlobalTransition::Action> getTransientContent(GlobalTransition* transition);
//Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Element<std::string>& transition);
-
+
static std::string declForRange(const std::string& identifier, long minValue, long maxValue, bool nativeOnly = false);
static std::string conditionForHistoryTransition(const GlobalTransition* transition);
@@ -396,7 +396,7 @@ protected:
std::string sanitizeCode(const std::string& code);
std::string dataToAssignments(const std::string& prefix, const Data& data);
-
+
// Arabica::XPath::NodeSet<std::string> _globalStates;
// Arabica::DOM::Node<std::string> _startState;
// std::map<std::string, Arabica::DOM::Element<std::string> > _states;
@@ -409,28 +409,28 @@ protected:
bool _hasIndexLessLoops;
bool _writeTransitionPrintfs;
bool _traceTransitions;
-
+
uint32_t _externalQueueLength;
uint32_t _internalQueueLength;
-
+
PromelaInlines pmlInlines;
// std::map<std::string, PromelaEventSource> _invokers;
// PromelaEventSource _globalEventSource;
-
+
std::map<std::string, std::map<std::string, size_t> > _historyMembers; // ids of all history states
std::set<std::string> _dataModelVars;
-
+
Arabica::DOM::Node<std::string> _finalize;
std::map<Arabica::DOM::Node<std::string>, ChartToPromela*> _machines;
std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>* _machinesAll;
ChartToPromela* _parent; // our invoking interpreter
ChartToPromela* _parentTopMost;
-
+
std::map<std::string, Arabica::DOM::Node<std::string> > _machinesPerId;
std::map<std::string, Arabica::DOM::Node<std::string> >* _machinesAllPerId;
std::string _prefix; // our prefix in case of nested SCXML documents
std::string _invokerid;
-
+
uint64_t _perfTransProcessed;
uint64_t _perfTransTotal;
uint64_t _perfHistoryProcessed;
diff --git a/src/uscxml/transform/ChartToTex.cpp b/src/uscxml/transform/ChartToTex.cpp
index 35731a1..f38740a 100644
--- a/src/uscxml/transform/ChartToTex.cpp
+++ b/src/uscxml/transform/ChartToTex.cpp
@@ -53,12 +53,12 @@ void ChartToTex::writeTex(std::ostream& stream) {
bool wroteRowStart = false;
std::string seperator;
-
+
for (std::map<std::string, GlobalState*>::iterator stateIter = _globalConf.begin(); stateIter != _globalConf.end(); stateIter++) {
assert(_indexToState.find(stateIter->second->index) == _indexToState.end());
_indexToState[stateIter->second->index] = stateIter->second;
}
-
+
stream << "% " << _sourceURL.asString() << std::endl;
stream << "%<*provideCommand>" << std::endl;
@@ -84,7 +84,7 @@ void ChartToTex::writeTex(std::ostream& stream) {
stream << "%<*tableRows>" << std::endl;
wroteRowStart = true;
}
-
+
stream << "%<*globalState" << currState->index << ">" << std::endl;
// state index
@@ -95,15 +95,15 @@ void ChartToTex::writeTex(std::ostream& stream) {
stream << "\\globalStateListCell[t]{";
stream << "\\tikzmark{active_" << currState->index << "}";
stream << "$\\widetilde{s}_a(" << currState->index << ")$: " << stateListToTex(flatId.getFlatActive(), flatId.getActive().size() == 0) << "\\\\";
-
+
// already visited states
stream << "\\tikzmark{visited_" << currState->index << "}";
stream << "$\\widetilde{s}_d(" << currState->index << ")$: " << stateListToTex(flatId.getFlatVisited(), flatId.getVisited().size() == 0) << "\\\\";
-
+
// history assignments
stream << "\\tikzmark{history_" << currState->index << "}";
stream << "$\\widetilde{s}_h(" << currState->index << ")$: " << stateListToTex(flatId.getFlatHistory(), flatId.getHistory().size() == 0) << "} & ";
-
+
// all transitions
std::set<std::string> origTransitions;
for (std::list<GlobalTransition*>::iterator transIter = stateIter->second->sortedOutgoing.begin(); transIter != stateIter->second->sortedOutgoing.end(); transIter++) {
@@ -118,7 +118,7 @@ void ChartToTex::writeTex(std::ostream& stream) {
}
}
}
-
+
if (origTransitions.size() > 0) {
stream << "$\\{ ";
seperator = "";
@@ -144,7 +144,7 @@ void ChartToTex::writeTex(std::ostream& stream) {
if (!currTrans->isValid)
stream << "\\sout{";
-
+
Arabica::XPath::NodeSet<std::string> members = currTrans->getTransitions();
if (members.size() > 0) {
stream << "$\\{ ";
@@ -162,28 +162,35 @@ void ChartToTex::writeTex(std::ostream& stream) {
} else {
stream << "$\\emptyset$";
}
- // stream << "& \\sout{$\\{ t_2, t_0 \\}$}, & \\emph{$Inv_4$: nested source states} \\\\" << std::endl;
- // stream << "& $\\{ t_2 \\}$ & & $\\widetilde{s}(2)$ \\\\" << std::endl;
- // stream << "& $\\{ t_0 \\}$ & & $\\widetilde{s}(4)$ \\\\" << std::endl;
+ // stream << "& \\sout{$\\{ t_2, t_0 \\}$}, & \\emph{$Inv_4$: nested source states} \\\\" << std::endl;
+ // stream << "& $\\{ t_2 \\}$ & & $\\widetilde{s}(2)$ \\\\" << std::endl;
+ // stream << "& $\\{ t_0 \\}$ & & $\\widetilde{s}(4)$ \\\\" << std::endl;
if (!currTrans->isValid) {
#if 1
stream << " } & \\emph{";
switch(currTrans->invalidReason) {
- case GlobalTransition::NO_COMMON_EVENT:
- stream << "$Inv_1$: "; break;
- case GlobalTransition::MIXES_EVENT_SPONTANEOUS:
- stream << "$Inv_2$: "; break;
- case GlobalTransition::SAME_SOURCE_STATE:
- stream << "$Inv_3$: "; break;
- case GlobalTransition::CHILD_ENABLED:
- stream << "$Inv_4$: "; break;
- case GlobalTransition::PREEMPTING_MEMBERS:
- stream << "$Inv_5$: "; break;
- case GlobalTransition::UNCONDITIONAL_MATCH:
- stream << "$Opt_1$: "; break;
- case GlobalTransition::UNCONDITIONAL_SUPERSET:
- stream << "$Opt_2$: "; break;
+ case GlobalTransition::NO_COMMON_EVENT:
+ stream << "$Inv_1$: ";
+ break;
+ case GlobalTransition::MIXES_EVENT_SPONTANEOUS:
+ stream << "$Inv_2$: ";
+ break;
+ case GlobalTransition::SAME_SOURCE_STATE:
+ stream << "$Inv_3$: ";
+ break;
+ case GlobalTransition::CHILD_ENABLED:
+ stream << "$Inv_4$: ";
+ break;
+ case GlobalTransition::PREEMPTING_MEMBERS:
+ stream << "$Inv_5$: ";
+ break;
+ case GlobalTransition::UNCONDITIONAL_MATCH:
+ stream << "$Opt_1$: ";
+ break;
+ case GlobalTransition::UNCONDITIONAL_SUPERSET:
+ stream << "$Opt_2$: ";
+ break;
}
stream << currTrans->invalidMsg << "} ";
#endif
@@ -192,7 +199,7 @@ void ChartToTex::writeTex(std::ostream& stream) {
} else {
stream << " & ";
std::stringstream execContentSS;
-
+
seperator = "";
for (std::list<GlobalTransition::Action>::iterator actionIter = currTrans->actions.begin(); actionIter != currTrans->actions.end(); actionIter++) {
Element<std::string> execContent;
@@ -224,7 +231,7 @@ void ChartToTex::writeTex(std::ostream& stream) {
seperator = ", ";
}
}
-
+
if (execContentSS.str().size() > 0) {
stream << "$\\mathcal{X} := (" << execContentSS.str() << ")$";
} else {
@@ -241,7 +248,7 @@ void ChartToTex::writeTex(std::ostream& stream) {
if (stateIter->second->sortedOutgoing.size() == 0) {
stream << " & & & \\\\" << std::endl;
}
-
+
stream << "\\hline" << std::endl;
}
stream << "%</globalState" << currState->index << ">" << std::endl;
@@ -270,7 +277,7 @@ std::string ChartToTex::stateListToTex(const std::string& input, bool isEmpty) {
}
return statesTex;
}
-
+
std::string ChartToTex::texEscape(const std::string& input) {
std::string texString(input);
boost::replace_all(texString, "\\", "\\\\");
diff --git a/src/uscxml/transform/ChartToTex.h b/src/uscxml/transform/ChartToTex.h
index b7542f4..037b55c 100644
--- a/src/uscxml/transform/ChartToTex.h
+++ b/src/uscxml/transform/ChartToTex.h
@@ -39,18 +39,18 @@ public:
virtual ~ChartToTex();
static Transformer transform(const Interpreter& other);
-
+
void writeTo(std::ostream& stream);
-
+
protected:
ChartToTex(const Interpreter& other)
- : TransformerImpl(),
- ChartToFSM(other) {}
+ : TransformerImpl(),
+ ChartToFSM(other) {}
void writeTex(std::ostream& stream);
std::map<unsigned long, GlobalState*> _indexToState;
-
+
private:
static std::string stateListToTex(const std::string& input, bool isEmpty);
static std::string texEscape(const std::string& input);
diff --git a/src/uscxml/transform/FlatStateIdentifier.h b/src/uscxml/transform/FlatStateIdentifier.h
index f082b18..4afd956 100644
--- a/src/uscxml/transform/FlatStateIdentifier.h
+++ b/src/uscxml/transform/FlatStateIdentifier.h
@@ -93,8 +93,8 @@ public:
}
static std::string toStateId(const Arabica::XPath::NodeSet<std::string> activeStates,
- const Arabica::XPath::NodeSet<std::string> alreadyEnteredStates = Arabica::XPath::NodeSet<std::string>(),
- const std::map<std::string, Arabica::XPath::NodeSet<std::string> > historyStates = std::map<std::string, Arabica::XPath::NodeSet<std::string> >()) {
+ const Arabica::XPath::NodeSet<std::string> alreadyEnteredStates = Arabica::XPath::NodeSet<std::string>(),
+ const std::map<std::string, Arabica::XPath::NodeSet<std::string> > historyStates = std::map<std::string, Arabica::XPath::NodeSet<std::string> >()) {
FlatStateIdentifier tmp(activeStates, alreadyEnteredStates, historyStates);
return tmp.getStateId();
}
diff --git a/src/uscxml/transform/Transformer.h b/src/uscxml/transform/Transformer.h
index 9d31b71..16d0a94 100644
--- a/src/uscxml/transform/Transformer.h
+++ b/src/uscxml/transform/Transformer.h
@@ -39,12 +39,12 @@ public:
class USCXML_API Transformer : public boost::enable_shared_from_this<Transformer> {
public:
// Transformer(const Interpreter& source) { _impl = new (source) }
-
+
Transformer() : _impl() {} // the empty, invalid interpreter
Transformer(boost::shared_ptr<TransformerImpl> const impl) : _impl(impl) { }
Transformer(const Transformer& other) : _impl(other._impl) { }
virtual ~Transformer() {};
-
+
operator bool() const {
return (_impl);
}
@@ -68,11 +68,11 @@ public:
operator Interpreter() {
return _impl->operator Interpreter();
}
-
- boost::shared_ptr<TransformerImpl> getImpl() {
- return _impl;
- }
-
+
+ boost::shared_ptr<TransformerImpl> getImpl() {
+ return _impl;
+ }
+
protected:
boost::shared_ptr<TransformerImpl> _impl;