From aba3f7d3560c93aab1b1482c840595e4928f38b5 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Mon, 8 Feb 2016 21:51:15 +0100 Subject: Some polishing for generated ANSI C machines --- README.md | 20 +- src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 5 +- src/uscxml/transform/ChartToC.cpp | 949 +++++++++------- src/uscxml/transform/ChartToC.h | 3 +- test/CMakeLists.txt | 6 +- test/src/test-c-machine.cpp | 166 +-- test/src/test-c-machine.machine.c | 1191 +++++++++++---------- 7 files changed, 1271 insertions(+), 1069 deletions(-) diff --git a/README.md b/README.md index 6ef7f8f..3798be5 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ for SCXML documents and currently implements the following features: ### Test Reports * We continuously run the [W3C IRP tests](http://www.w3.org/Voice/2013/scxml-irp/) for SCXML. -* The manual and XPath specific tests, are [excluded](https://github.com/tklab-tud/uscxml/blob/master/test/ctest/CTestCustom.ctest.in). +* Some tests are [excluded](https://github.com/tklab-tud/uscxml/blob/master/test/ctest/CTestCustom.ctest.in). To run the tests yourself, you need to generate the build environment and pass -DBUILD_TESTS=ON via CMake: @@ -88,18 +88,12 @@ To run the tests yourself, you need to generate the build environment and pass < Afterwards, you can run the various tests. There are more than 3500 tests in total, so maybe restrict yourself to some subset. -| Variant | Data Model | Results | Invoke as | -|---------------|------------|---------|------------------------------------------| -| Plain IRP | ECMAScript | 196/196 | $ ctest -L "^ecma/test" | -| | XPath | 107/211 | $ ctest -L "^xpath/test" | -| | PROMELA | 147/165 | $ ctest -L "^promela/test" | -| | Lua | 165/201 | $ ctest -L "^lua/test" | -| Flattened IRP | ECMAScript | 196/196 | $ ctest -L "^fsm/ecma/test" | -| | XPath | 107/211 | $ ctest -L "^fsm/xpath/test" | -| | PROMELA | 147/165 | $ ctest -L "^fsm/promela/test" | -| | Lua | 165/201 | $ ctest -L "^fsm/lua/test" | -| Generated C | ECMAScript | 180/180 | $ ctest -L "^gen/c/ecma/test" | -| Verification | PROMELA | 130/181 | $ ctest -L "^spin/promela/test" | +| | ECMAScript | XPath | PROMELA | Lua | Invoke as | +|---------------|------------------|------------------|------------------|------------------|------------------| +| Plain IRP | 196/196 | 107/211 | 147/181 | 165/201 | $ ctest -L "^[datamodel]/test" | +| Flattened IRP | 196/196 | 107/211 | 147/181 | 165/201 | $ ctest -L "^fsm/[datamodel]/test" | +| Generated C | 180/196 | 73/211 | 144/181 | 143/201 | $ ctest -L "^gen/c/[datamodel]/test" +| Verification | | | 130/181 | | $ ctest -L "^spin/promela/test" ### License diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index c55e143..c204946 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -160,7 +160,7 @@ boost::shared_ptr LuaDataModel::create(InterpreterInfo* interpret LOG(INFO) << e.what(); } - luabridge::getGlobalNamespace(dm->_luaState).beginClass("Interpreter").endClass(); + luabridge::getGlobalNamespace(dm->_luaState).beginClass("Interpreter").endClass(); luabridge::setGlobal(dm->_luaState, dm->_interpreter, "__interpreter"); luabridge::getGlobalNamespace(dm->_luaState).addCFunction("In", luaInFunction); @@ -315,7 +315,8 @@ void LuaDataModel::setEvent(const Event& event) { } Data LuaDataModel::getStringAsData(const std::string& content) { - Data data = Data::fromJSON(content); +// Data data = Data::fromJSON(content); + Data data; if (data.empty()) { std::string trimmedExpr = boost::trim_copy(content); if (!boost::starts_with(trimmedExpr, "return")) { diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp index 3c92e4a..f9eba98 100644 --- a/src/uscxml/transform/ChartToC.cpp +++ b/src/uscxml/transform/ChartToC.cpp @@ -50,7 +50,7 @@ ChartToC::ChartToC(const Interpreter& other) : TransformerImpl(), _topMostMachin std::stringstream ss; ss << _document; _md5 = md5(ss.str()); - _prefix = "_scxml_" + _md5.substr(0, 8); + _prefix = "_uscxml_" + _md5.substr(0, 8); _allMachines.push_back(this); prepare(); @@ -414,6 +414,8 @@ void ChartToC::writeTo(std::ostream& stream) { writeIncludes(stream); writeMacros(stream); writeTypes(stream); + writeForwardDeclarations(stream); + for (std::list::iterator machIter = _allMachines.begin(); machIter != _allMachines.end(); machIter++) { (*machIter)->writeElementInfo(stream); (*machIter)->writeExecContentFinalize(stream); @@ -430,6 +432,12 @@ void ChartToC::writeTo(std::ostream& stream) { } +void ChartToC::writeForwardDeclarations(std::ostream& stream) { + stream << "/* forward declare machines to allow references */" << std::endl; + stream << "extern const uscxml_machine uscxml_machines[" << toStr(_allMachines.size() + 1) << "];" << std::endl; + stream << std::endl; +} + void ChartToC::findNestedMachines() { NodeSet invokes = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); @@ -480,162 +488,245 @@ void ChartToC::findNestedMachines() { } void ChartToC::writeIncludes(std::ostream& stream) { - stream << "#include // explicit types" << std::endl; - stream << "#include // NULL" << std::endl; + stream << "#include /* explicit types */" << std::endl; + stream << "#include /* NULL */" << std::endl; stream << std::endl; } void ChartToC::writeMacros(std::ostream& stream) { - stream << "#define BIT_HAS(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl; - stream << "#define BIT_SET_AT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl; - stream << "#define BIT_CLEAR(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl; + stream << "#ifndef USCXML_GEN_C_MACROS" << std::endl; + stream << std::endl; + stream << "/**" << std::endl; + stream << " * All macros used for the scxml types and functions" << std::endl; + stream << " * " << std::endl; + stream << " * ** IMPORTANT: Make sure to set the following macros prior to including. **" << std::endl; + stream << " * They are used to represent the machine in the types to follow" << std::endl; + stream << " * and to allocate stack memory during a micro-step function." << std::endl; + stream << " * When in doubt, overprovide." << std::endl; + stream << " * " << std::endl; + stream << " * USCXML_NR_STATES_TYPE" << std::endl; + stream << " * as the smallest type for positive integers that can contain the" << std::endl; + stream << " * largest number of states from an individual state machine. E.g.:" << std::endl; + stream << " * < 2^8 states => uint8_t" << std::endl; + stream << " * < 2^16 states => uint16_t" << std::endl; + stream << " * < 2^32 states => uint32_t" << std::endl; + stream << " */" << std::endl; + stream << std::endl; + + stream << "#ifndef USCXML_NR_STATES_TYPE " << std::endl; + stream << "# define USCXML_NR_STATES_TYPE " << _stateDataType << std::endl; + stream << "#endif " << 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 << " * USCXML_NR_TRANS_TYPE" << std::endl; + stream << " * the same as above but for the number of transitions." << std::endl; + stream << " */" << std::endl; stream << std::endl; - stream << "#ifndef SCXML_NR_STATES_TYPE " << std::endl; - stream << "# define SCXML_NR_STATES_TYPE " << _stateDataType << std::endl; + stream << "#ifndef USCXML_NR_TRANS_TYPE " << std::endl; + stream << "# define USCXML_NR_TRANS_TYPE " << _transDataType << std::endl; stream << "#endif " << std::endl; stream << std::endl; - stream << "#ifndef SCXML_NR_TRANS_TYPE " << std::endl; - stream << "# define SCXML_NR_TRANS_TYPE " << _stateDataType << std::endl; - stream << "#endif " << std::endl; + stream << "/** " << std::endl; + stream << " * USCXML_MAX_NR_STATES_BYTES" << std::endl; + stream << " * the smallest multiple of 8 that, if multiplied by 8," << std::endl; + stream << " * is larger than USCXML_NR_STATES_TYPE, e.g:" << std::endl; + stream << " * 1-8 states => 1" << std::endl; + stream << " * 9-16 states => 2" << std::endl; + stream << " * 17-24 states => 3" << std::endl; + stream << " * 25-32 states => 4" << std::endl; + stream << " * ..." << std::endl; + stream << " */" << std::endl; stream << std::endl; - stream << "#ifndef SCXML_MAX_NR_STATES_BYTES " << std::endl; - stream << "# define SCXML_MAX_NR_STATES_BYTES " << _stateCharArraySize << std::endl; + stream << "#ifndef USCXML_MAX_NR_STATES_BYTES " << std::endl; + stream << "# define USCXML_MAX_NR_STATES_BYTES " << _stateCharArraySize << std::endl; stream << "#endif " << std::endl; stream << std::endl; - stream << "#ifndef SCXML_MAX_NR_TRANS_BYTES " << std::endl; - stream << "# define SCXML_MAX_NR_TRANS_BYTES " << _transCharArraySize << std::endl; + stream << "/**" << std::endl; + stream << " * USCXML_MAX_NR_TRANS_BYTES" << std::endl; + stream << " * same as above but for transitions." << std::endl; + stream << " */" << std::endl; + stream << std::endl; + + stream << "#ifndef USCXML_MAX_NR_TRANS_BYTES " << std::endl; + stream << "# define USCXML_MAX_NR_TRANS_BYTES " << _transCharArraySize << 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 << " * USCXML_NUMBER_STATES / USCXML_NUMBER_TRANS" << std::endl; + stream << " * Per default the number of states / transitions is retrieved from the machine" << std::endl; + stream << " * info in the uscxml_ctx struct, but you can also hard-code it per macro." << std::endl; + stream << " */" << std::endl; stream << std::endl; -// stream << "#define SCXML_NUMBER_STATES " << _states.size() << std::endl; -// stream << "#define SCXML_NUMBER_TRANS " << _transitions.size() << std::endl; + stream << "#ifndef USCXML_NUMBER_STATES" << std::endl; + stream << "# define USCXML_NUMBER_STATES (ctx->machine->nr_states)" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; - stream << "#define SCXML_NUMBER_STATES (ctx->machine->nr_states)" << std::endl; - stream << "#define SCXML_NUMBER_TRANS (ctx->machine->nr_transitions)" << std::endl; + stream << "#ifndef USCXML_NUMBER_TRANS" << std::endl; + stream << "# define USCXML_NUMBER_TRANS (ctx->machine->nr_transitions)" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + stream << "/**" << std::endl; + stream << " * USCXML_GET_STATE / USCXML_GET_TRANS" << std::endl; + stream << " * Per default an individual state or transitions is retrieved from the machine" << std::endl; + stream << " * info in the uscxml_ctx struct, but you can also hard-code it per macro." << std::endl; + stream << " */" << 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 << "#define SCXML_TRANS_INITIAL 0x10" << std::endl; + stream << "#ifndef USCXML_GET_STATE" << std::endl; + stream << "# define USCXML_GET_STATE(i) (ctx->machine->states[i])" << std::endl; + stream << "#endif" << 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 << "#define SCXML_STATE_HAS_HISTORY 0x80 // highest bit" << std::endl; - stream << "#define SCXML_STATE_MASK(t) (t & 0x7F) // mask highest bit" << std::endl; + stream << "#ifndef USCXML_GET_TRANS" << std::endl; + stream << "# define USCXML_GET_TRANS(i) (ctx->machine->transitions[i])" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + stream << std::endl; + stream << "/* Common macros below */"<< std::endl; + stream << 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 << "#define SCXML_CTX_FINISHED 0x10" << std::endl; + stream << "#define BIT_HAS(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl; + stream << "#define BIT_SET_AT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl; + stream << "#define BIT_CLEAR(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl; stream << std::endl; + stream << "#ifdef __GNUC__" << std::endl; + 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 USCXML_ERR_OK 0" << std::endl; + stream << "#define USCXML_ERR_IDLE 1" << std::endl; + stream << "#define USCXML_ERR_DONE 2" << std::endl; + stream << "#define USCXML_ERR_MISSING_CALLBACK 3" << std::endl; + stream << "#define USCXML_ERR_FOREACH_DONE 4" << std::endl; + stream << "#define USCXML_ERR_EXEC_CONTENT 5" << std::endl; + stream << "#define USCXML_ERR_INVALID_TARGET 6" << std::endl; + stream << "#define USCXML_ERR_INVALID_TYPE 7" << std::endl; + stream << "#define USCXML_ERR_UNSUPPORTED 8" << std::endl; + stream << std::endl; + + stream << "#define USCXML_TRANS_SPONTANEOUS 0x01" << std::endl; + stream << "#define USCXML_TRANS_TARGETLESS 0x02" << std::endl; + stream << "#define USCXML_TRANS_INTERNAL 0x04" << std::endl; + stream << "#define USCXML_TRANS_HISTORY 0x08" << std::endl; + stream << "#define USCXML_TRANS_INITIAL 0x10" << std::endl; + stream << std::endl; + stream << "#define USCXML_STATE_ATOMIC 0x01" << std::endl; + stream << "#define USCXML_STATE_PARALLEL 0x02" << std::endl; + stream << "#define USCXML_STATE_COMPOUND 0x03" << std::endl; + stream << "#define USCXML_STATE_FINAL 0x04" << std::endl; + stream << "#define USCXML_STATE_HISTORY_DEEP 0x05" << std::endl; + stream << "#define USCXML_STATE_HISTORY_SHALLOW 0x06" << std::endl; + stream << "#define USCXML_STATE_INITIAL 0x07" << std::endl; + stream << "#define USCXML_STATE_HAS_HISTORY 0x80 /* highest bit */" << std::endl; + stream << "#define USCXML_STATE_MASK(t) (t & 0x7F) /* mask highest bit */" << std::endl; + + stream << "" << std::endl; + stream << "#define USCXML_CTX_PRISTINE 0x00" << std::endl; + stream << "#define USCXML_CTX_SPONTANEOUS 0x01" << std::endl; + stream << "#define USCXML_CTX_INITIALIZED 0x02" << std::endl; + stream << "#define USCXML_CTX_TOP_LEVEL_FINAL 0x04" << std::endl; + stream << "#define USCXML_CTX_TRANSITION_FOUND 0x08" << std::endl; + stream << "#define USCXML_CTX_FINISHED 0x10" << 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 << "#define SCXML_MACHINE_IS_SET(machine) (machine->nr_states > 0)" << std::endl; + stream << "#define USCXML_ELEM_DATA_IS_SET(data) (data->id != NULL)" << std::endl; + stream << "#define USCXML_ELEM_DONEDATA_IS_SET(donedata) (donedata->content != NULL || donedata->contentexpr != NULL || donedata->params != NULL)" << std::endl; + stream << "#define USCXML_ELEM_PARAM_IS_SET(param) (param->name != NULL)" << std::endl; + stream << "#define USCXML_MACHINE_IS_SET(machine) (machine->nr_states > 0)" << std::endl; + stream << std::endl; + stream << "#define USCXML_GEN_C_MACROS" << std::endl; + stream << "#endif" << std::endl; stream << std::endl; } void ChartToC::writeTypes(std::ostream& stream) { stream << std::endl; - stream << "typedef struct scxml_machine scxml_machine;" << 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_elem_invoke scxml_elem_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_t)(const scxml_ctx* ctx);" << std::endl; - stream << "typedef void* (*dequeue_external_t)(const scxml_ctx* ctx);" << std::endl; - stream << "typedef int (*is_enabled_t)(const scxml_ctx* ctx, const scxml_transition* transition, const void* event);" << std::endl; - stream << "typedef int (*is_true_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_elem_invoke* invocation, uint8_t uninvoke);" << 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_elem_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; - -#if 1 - stream << "struct scxml_machine {" << std::endl; - stream << " uint8_t flags;" << std::endl; - stream << " SCXML_NR_STATES_TYPE nr_states;" << std::endl; - stream << " SCXML_NR_TRANS_TYPE nr_transitions;" << std::endl; - stream << " const char* name;" << std::endl; - stream << " const char* datamodel;" << std::endl; - stream << " const char* uuid;" << std::endl; - stream << " const scxml_state* states;" << std::endl; - stream << " const scxml_transition* transitions;" << std::endl; - stream << " const scxml_machine* parent;" << std::endl; - stream << " const scxml_elem_donedata* donedata;" << std::endl; - stream << " const exec_content_t script;" << std::endl; - stream << "};" << std::endl; + stream << "#ifndef USCXML_GEN_C_TYPES" << std::endl; + stream << std::endl; + stream << "/**" << std::endl; + stream << " * All types required to represent an SCXML state chart." << std::endl; + stream << " * Just predefine the USCXML_GEN_C_TYPES macro if you do not need them." << std::endl; + stream << " */" << std::endl; + stream << std::endl; + + stream << "typedef struct uscxml_machine uscxml_machine;" << std::endl; + stream << "typedef struct uscxml_transition uscxml_transition;" << std::endl; + stream << "typedef struct uscxml_state uscxml_state;" << std::endl; + stream << "typedef struct uscxml_ctx uscxml_ctx;" << std::endl; + stream << "typedef struct uscxml_elem_invoke uscxml_elem_invoke;" << std::endl; + stream << std::endl; + + stream << "typedef struct uscxml_elem_send uscxml_elem_send;" << std::endl; + stream << "typedef struct uscxml_elem_param uscxml_elem_param;" << std::endl; + stream << "typedef struct uscxml_elem_data uscxml_elem_data;" << std::endl; + stream << "typedef struct uscxml_elem_donedata uscxml_elem_donedata;" << std::endl; + stream << "typedef struct uscxml_elem_foreach uscxml_elem_foreach;" << std::endl; + stream << std::endl; + + stream << "typedef void* (*dequeue_internal_t)(const uscxml_ctx* ctx);" << std::endl; + stream << "typedef void* (*dequeue_external_t)(const uscxml_ctx* ctx);" << std::endl; + stream << "typedef int (*is_enabled_t)(const uscxml_ctx* ctx, const uscxml_transition* transition, const void* event);" << std::endl; + stream << "typedef int (*is_true_t)(const uscxml_ctx* ctx, const char* expr);" << std::endl; + stream << "typedef int (*exec_content_t)(const uscxml_ctx* ctx, const uscxml_state* state, const void* event);" << std::endl; + stream << "typedef int (*raise_done_event_t)(const uscxml_ctx* ctx, const uscxml_state* state, const uscxml_elem_donedata* donedata);" << std::endl; + stream << "typedef int (*invoke_t)(const uscxml_ctx* ctx, const uscxml_state* s, const uscxml_elem_invoke* invocation, unsigned char uninvoke);" << std::endl; + stream << std::endl; + + stream << "typedef int (*exec_content_log_t)(const uscxml_ctx* ctx, const char* label, const char* expr);" << std::endl; + stream << "typedef int (*exec_content_raise_t)(const uscxml_ctx* ctx, const char* event);" << std::endl; + stream << "typedef int (*exec_content_send_t)(const uscxml_ctx* ctx, const uscxml_elem_send* send);" << std::endl; + stream << "typedef int (*exec_content_foreach_init_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach);" << std::endl; + stream << "typedef int (*exec_content_foreach_next_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach);" << std::endl; + stream << "typedef int (*exec_content_foreach_done_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach);" << std::endl; + stream << "typedef int (*exec_content_assign_t)(const uscxml_ctx* ctx, const char* location, const char* expr);" << std::endl; + stream << "typedef int (*exec_content_init_t)(const uscxml_ctx* ctx, const uscxml_elem_data* data);" << std::endl; + stream << "typedef int (*exec_content_cancel_t)(const uscxml_ctx* ctx, const char* sendid, const char* sendidexpr);" << std::endl; + stream << "typedef int (*exec_content_finalize_t)(const uscxml_ctx* ctx, const uscxml_elem_invoke* invoker, const void* event);" << std::endl; + stream << "typedef int (*exec_content_script_t)(const uscxml_ctx* ctx, const char* src, const char* content);" << std::endl; stream << std::endl; - stream << "// forward declare machines to allow references" << std::endl; - stream << "extern const scxml_machine scxml_machines[" << toStr(_allMachines.size() + 1) << "];" << std::endl; + stream << "/**" << std::endl; + stream << " * A single SCXML state-machine." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_machine {" << std::endl; + stream << " unsigned char flags; /* Unused */" << std::endl; + stream << " USCXML_NR_STATES_TYPE nr_states; /* Make sure to set type per macro! */" << std::endl; + stream << " USCXML_NR_TRANS_TYPE nr_transitions; /* Make sure to set type per macro! */" << std::endl; + stream << " const char* name;" << std::endl; + stream << " const char* datamodel;" << std::endl; + stream << " const char* uuid; /* currently MD5 sum */" << std::endl; + stream << " const uscxml_state* states;" << std::endl; + stream << " const uscxml_transition* transitions;" << std::endl; + stream << " const uscxml_machine* parent;" << std::endl; + stream << " const uscxml_elem_donedata* donedata;" << std::endl; + stream << " const exec_content_t script; /* Global script elements */" << std::endl; + stream << "};" << std::endl; stream << std::endl; -#endif - stream << "struct scxml_elem_data {" << std::endl; + stream << "/**" << std::endl; + stream << " * All information pertaining to a element." << std::endl; + stream << " * With late data binding, blocks of data elements are separated by NULL" << std::endl; + stream << " * use USCXML_ELEM_DATA_IS_SET to test for end of a block." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_elem_data {" << std::endl; stream << " const char* id;" << std::endl; stream << " const char* src;" << std::endl; stream << " const char* expr;" << std::endl; @@ -643,56 +734,76 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << "};" << std::endl; stream << std::endl; - stream << "struct scxml_state {" << std::endl; - stream << " const char* name; // eventual name" << std::endl; - stream << " const " << _stateDataType << " parent; // parent" << std::endl; - stream << " const exec_content_t on_entry; // on entry handlers" << std::endl; - stream << " const exec_content_t on_exit; // on exit handlers" << std::endl; - stream << " const invoke_t invoke; // invocations" << std::endl; - stream << " const char children[SCXML_MAX_NR_STATES_BYTES]; // all children" << std::endl; - stream << " const char completion[SCXML_MAX_NR_STATES_BYTES]; // default completion" << std::endl; - stream << " const char ancestors[SCXML_MAX_NR_STATES_BYTES]; // all ancestors" << std::endl; - stream << " const scxml_elem_data* data;" << std::endl; - stream << " const uint8_t type; // atomic, parallel, compound, final, history" << std::endl; + stream << "/**" << std::endl; + stream << " * All information pertaining to any state element." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_state {" << std::endl; + stream << " const char* name; /* eventual name */" << std::endl; + stream << " const USCXML_NR_STATES_TYPE parent; /* parent */" << std::endl; + stream << " const exec_content_t on_entry; /* on entry handlers */" << std::endl; + stream << " const exec_content_t on_exit; /* on exit handlers */" << std::endl; + stream << " const invoke_t invoke; /* invocations */" << std::endl; + stream << " const char children[USCXML_MAX_NR_STATES_BYTES]; /* all children */" << std::endl; + stream << " const char completion[USCXML_MAX_NR_STATES_BYTES]; /* default completion */" << std::endl; + stream << " const char ancestors[USCXML_MAX_NR_STATES_BYTES]; /* all ancestors */" << std::endl; + stream << " const uscxml_elem_data* data; /* data with late binding */" << std::endl; + stream << " const unsigned char type; /* One of USCXML_STATE_* */" << std::endl; stream << "};" << std::endl; stream << std::endl; - stream << "struct scxml_transition {" << std::endl; - stream << " const " << _stateDataType << " source;" << std::endl; - stream << " const char target[SCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << "/**" << std::endl; + stream << " * All information pertaining to a element." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_transition {" << std::endl; + stream << " const USCXML_NR_STATES_TYPE source;" << std::endl; + stream << " const char target[USCXML_MAX_NR_STATES_BYTES];" << std::endl; stream << " const char* event;" << std::endl; stream << " const char* condition;" << std::endl; stream << " const exec_content_t on_transition;" << std::endl; - stream << " const uint8_t type;" << std::endl; - stream << " const char conflicts[SCXML_MAX_NR_TRANS_BYTES];" << std::endl; - stream << " const char exit_set[SCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " const unsigned char type;" << std::endl; + stream << " const char conflicts[USCXML_MAX_NR_TRANS_BYTES];" << std::endl; + stream << " const char exit_set[USCXML_MAX_NR_STATES_BYTES];" << std::endl; stream << "};" << std::endl; stream << std::endl; - stream << "struct scxml_elem_foreach {" << std::endl; + stream << "/**" << std::endl; + stream << " * All information pertaining to a element." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_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 << "/**" << std::endl; + stream << " * All information pertaining to a element." << std::endl; + stream << " * Blocks of params are separated by NULL params, use" << std::endl; + stream << " * USCXML_ELEM_PARAM_IS_SET to test for end of a block." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_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 << " const " << _stateDataType << " source;" << std::endl; + stream << "/**" << std::endl; + stream << " * All information pertaining to a element." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_elem_donedata {" << std::endl; + stream << " const USCXML_NR_STATES_TYPE source;" << std::endl; stream << " const char* content;" << std::endl; stream << " const char* contentexpr;" << std::endl; - stream << " const scxml_elem_param* params;" << std::endl; + stream << " const uscxml_elem_param* params;" << std::endl; stream << "};" << std::endl; stream << std::endl; - stream << "struct scxml_elem_invoke {" << std::endl; - stream << " const scxml_machine* machine;" << std::endl; + stream << "/**" << std::endl; + stream << " * All information pertaining to an element." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_elem_invoke {" << std::endl; + stream << " const uscxml_machine* machine;" << std::endl; stream << " const char* type;" << std::endl; stream << " const char* typeexpr;" << std::endl; stream << " const char* src;" << std::endl; @@ -701,15 +812,18 @@ void ChartToC::writeTypes(std::ostream& stream) { stream << " const char* idlocation;" << std::endl; stream << " const char* sourcename;" << std::endl; stream << " const char* namelist;" << std::endl; - stream << " const uint8_t autoforward;" << std::endl; - stream << " const scxml_elem_param* params;" << std::endl; + stream << " const unsigned char autoforward;" << std::endl; + stream << " const uscxml_elem_param* params;" << std::endl; stream << " exec_content_finalize_t finalize;" << std::endl; stream << " const char* content;" << std::endl; stream << " const char* contentexpr;" << std::endl; stream << "};" << std::endl; stream << std::endl; - stream << "struct scxml_elem_send {" << std::endl; + stream << "/**" << std::endl; + stream << " * All information pertaining to a element." << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_elem_send {" << std::endl; stream << " const char* event;" << std::endl; stream << " const char* eventexpr;" << std::endl; stream << " const char* target;" << std::endl; @@ -720,54 +834,64 @@ void ChartToC::writeTypes(std::ostream& stream) { 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* namelist; /* not space-separated, still as in attribute value */" << std::endl; stream << " const char* content;" << std::endl; stream << " const char* contentexpr;" << std::endl; - stream << " const scxml_elem_param* params;" << std::endl; + stream << " const uscxml_elem_param* params;" << std::endl; stream << "};" << std::endl; stream << std::endl; - stream << "struct scxml_ctx {" << std::endl; - stream << " uint8_t flags;" << std::endl; - stream << " const scxml_machine* machine;" << std::endl; + stream << "/**" << std::endl; + stream << " * Represents an instance of a state-chart at runtime/" << std::endl; + stream << " */" << std::endl; + stream << "struct uscxml_ctx {" << std::endl; + stream << " unsigned char flags;" << std::endl; + stream << " const uscxml_machine* machine;" << std::endl; stream << std::endl; - stream << " char config[SCXML_MAX_NR_STATES_BYTES];" << std::endl; - stream << " char history[SCXML_MAX_NR_STATES_BYTES];" << std::endl; - stream << " char invocations[SCXML_MAX_NR_STATES_BYTES];" << std::endl; - stream << " char initialized_data[SCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " char config[USCXML_MAX_NR_STATES_BYTES]; /* Make sure these macros specify a sufficient size */" << std::endl; + stream << " char history[USCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " char invocations[USCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " char initialized_data[USCXML_MAX_NR_STATES_BYTES];" << std::endl; stream << std::endl; stream << " void* user_data;" << std::endl; stream << " void* event;" << std::endl; stream << std::endl; stream << " dequeue_internal_t dequeue_internal;" << std::endl; stream << " dequeue_external_t dequeue_external;" << std::endl; - stream << " is_enabled_t is_enabled;" << std::endl; - stream << " is_true_t is_true;" << std::endl; + stream << " is_enabled_t is_enabled;" << std::endl; + stream << " is_true_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_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 << " 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 << std::endl; stream << " invoke_t invoke;" << std::endl; stream << "};" << std::endl; stream << std::endl; + stream << "#define USCXML_GEN_C_TYPES" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; } void ChartToC::writeHelpers(std::ostream& stream) { - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << "static void printStateNames(const scxml_ctx* ctx, const char* a, size_t length) {" << std::endl; + stream << "#ifdef USCXML_VERBOSE" << std::endl; + stream << "/**" << std::endl; + stream << " * Print name of states contained in a (debugging)." << std::endl; + stream << " */" << std::endl; + stream << "static void printStateNames(const uscxml_ctx* ctx, const char* a, size_t length) {" << std::endl; stream << " size_t i;" << std::endl; stream << " const char* seperator = \"\";" << std::endl; stream << " for (i = 0; i < length; i++) {" << std::endl; stream << " if (BIT_HAS(i, a)) {" << std::endl; - stream << " printf(\"%s%s\", seperator, (ctx->machine->states[i].name != NULL ? ctx->machine->states[i].name : \"UNK\"));" << std::endl; + stream << " printf(\"%s%s\", seperator, (USCXML_GET_STATE(i).name != NULL ? USCXML_GET_STATE(i).name : \"UNK\"));" << std::endl; stream << " seperator = \", \";" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; @@ -775,6 +899,9 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "}" << std::endl; stream << std::endl; + stream << "/**" << std::endl; + stream << " * Print bits set in a in a binary representation (debugging)." << std::endl; + stream << " */" << std::endl; stream << "static void printBitsetIndices(const char* a, size_t length) {" << std::endl; stream << " size_t i;" << std::endl; stream << " const char* seperator = \"\";" << std::endl; @@ -790,6 +917,10 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "#endif" << std::endl; stream << std::endl; + stream << "#ifndef USCXML_BIT_OPERATIONS" << std::endl; + stream << "/**" << std::endl; + stream << " * Return true if there is a common bit in a and b." << std::endl; + stream << " */" << std::endl; stream << "static int bit_has_and(const char* a, const char* b, size_t i) {" << std::endl; stream << " while(i--) {" << std::endl; stream << " if (a[i] & b[i])" << std::endl; @@ -799,6 +930,10 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "}" << std::endl; stream << std::endl; + stream << "/**" << std::endl; + stream << " * Set all bits to 0, this corresponds to memset(a, 0, i), " << std::endl; + stream << " * but does not require string.h or cstring." << std::endl; + stream << " */" << std::endl; stream << "static void bit_clear_all(char* a, size_t i) {" << std::endl; stream << " while(i--) {" << std::endl; stream << " a[i] = 0;" << std::endl; @@ -806,6 +941,9 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "}" << std::endl; stream << std::endl; + stream << "/**" << std::endl; + stream << " * Return true if there is any bit set in a." << std::endl; + stream << " */" << std::endl; stream << "static int bit_has_any(const char* a, size_t i) {" << std::endl; stream << " while(i--) {" << std::endl; stream << " if (a[i] > 0)" << std::endl; @@ -815,6 +953,9 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "}" << std::endl; stream << std::endl; + stream << "/**" << std::endl; + stream << " * Set all bits from given mask in dest, this is |= for bit arrays." << std::endl; + stream << " */" << std::endl; stream << "static void bit_or(char* dest, const char* mask, size_t i) {" << std::endl; stream << " while(i--) {" << std::endl; stream << " dest[i] |= mask[i];" << std::endl; @@ -822,6 +963,10 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "}" << std::endl; stream << std::endl; + stream << "/**" << std::endl; + stream << " * Copy all bits from source to dest, this corresponds to memcpy(a, b, i), " << std::endl; + stream << " * but does not require string.h or cstring." << std::endl; + stream << " */" << std::endl; stream << "static void bit_copy(char* dest, const char* source, size_t i) {" << std::endl; stream << " while(i--) {" << std::endl; stream << " dest[i] = source[i];" << std::endl; @@ -829,6 +974,9 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "}" << std::endl; stream << std::endl; + stream << "/**" << std::endl; + stream << " * Unset bits from mask in dest." << std::endl; + stream << " */" << std::endl; stream << "static void bit_and_not(char* dest, const char* mask, size_t i) {" << std::endl; stream << " while(i--) {" << std::endl; stream << " dest[i] &= ~mask[i];" << std::endl; @@ -836,12 +984,18 @@ void ChartToC::writeHelpers(std::ostream& stream) { stream << "}" << std::endl; stream << std::endl; + stream << "/**" << std::endl; + stream << " * Set bits from mask in dest." << std::endl; + stream << " */" << std::endl; stream << "static void bit_and(char* dest, const char* mask, size_t i) {" << std::endl; stream << " while(i--) {" << std::endl; stream << " dest[i] &= mask[i];" << std::endl; stream << " };" << std::endl; stream << "}" << std::endl; stream << std::endl; + stream << "#define USCXML_BIT_OPERATIONS" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; } @@ -853,12 +1007,12 @@ void ChartToC::writeExecContentFinalize(std::ostream& stream) { NodeSet execContent = filterChildType(Node_base::ELEMENT_NODE, finalize); if (execContent.size() > 0) { - stream << "static int " << _prefix << "_" << DOMUtils::idForNode(finalize) << "(const scxml_ctx* ctx, const scxml_elem_invoke* invocation, const void* event) {" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(finalize) << "(const uscxml_ctx* ctx, const uscxml_elem_invoke* invocation, const void* event) {" << std::endl; + stream << " int err = USCXML_ERR_OK;" << std::endl; for (size_t j = 0; j < execContent.size(); j++) { writeExecContent(stream, Element(execContent[j]), 1); } - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; } @@ -875,18 +1029,18 @@ void ChartToC::writeExecContent(std::ostream& stream) { NodeSet globalScripts = filterChildElements(_nsInfo.xmlNSPrefix + "script", state); if (globalScripts.size() > 0) { for (size_t j = 0; j < globalScripts.size(); j++) { - stream << "static int " << _prefix << "_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; + stream << "static int " << _prefix << "_global_script_" << toStr(j) << "(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; + stream << " int err = USCXML_ERR_OK;" << std::endl; writeExecContent(stream, globalScripts[j], 1); - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; } - stream << "static int " << _prefix << "_global_script(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << "static int " << _prefix << "_global_script(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; for (size_t j = 0; j < globalScripts.size(); j++) { stream << " " << _prefix << "_global_script_" << toStr(j) << "(ctx, state, event);" << std::endl; } - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; } @@ -894,20 +1048,20 @@ void ChartToC::writeExecContent(std::ostream& stream) { NodeSet onexit = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state); for (size_t j = 0; j < onexit.size(); j++) { - stream << "static int " << _prefix << "_" << 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; + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; + stream << " int err = USCXML_ERR_OK;" << std::endl; writeExecContent(stream, onexit[j], 1); - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; } if (onexit.size() > 0) { - stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_exit(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_exit(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; for (size_t j = 0; j < onexit.size(); j++) { stream << " " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(ctx, state, event);" << std::endl; } - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; } @@ -915,21 +1069,21 @@ void ChartToC::writeExecContent(std::ostream& stream) { NodeSet onentry = filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state); for (size_t j = 0; j < onentry.size(); j++) { - stream << "static int " << _prefix << "_" << 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; + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; + stream << " int err = USCXML_ERR_OK;" << std::endl; writeExecContent(stream, onentry[j], 1); - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; } if (onentry.size() > 0) { - stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; for (size_t j = 0; j < onentry.size(); j++) { stream << " " << _prefix << "_" << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(ctx, state, event);" << std::endl; } - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; } @@ -937,13 +1091,13 @@ void ChartToC::writeExecContent(std::ostream& stream) { NodeSet invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state); if (invokes.size() > 0) { - stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_invoke(const scxml_ctx* ctx, const scxml_state* s, const scxml_elem_invoke* invocation, uint8_t uninvoke) {" << std::endl; + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(state) << "_invoke(const uscxml_ctx* ctx, const uscxml_state* s, const uscxml_elem_invoke* invocation, unsigned char uninvoke) {" << std::endl; for (size_t j = 0; j < invokes.size(); j++) { Element invoke(invokes[j]); stream << " ctx->invoke(ctx, s, &" << _prefix << "_elem_invokes[" << ATTR(invoke, "documentOrder") << "], uninvoke);" << std::endl; stream << std::endl; } - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; } } @@ -953,12 +1107,12 @@ void ChartToC::writeExecContent(std::ostream& stream) { NodeSet execContent = filterChildType(Node_base::ELEMENT_NODE, transition); if (execContent.size() > 0) { - stream << "static int " << _prefix << "_" << 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; + stream << "static int " << _prefix << "_" << DOMUtils::idForNode(transition) << "_on_trans(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) {" << std::endl; + stream << " int err = USCXML_ERR_OK;" << std::endl; for (size_t j = 0; j < execContent.size(); j++) { writeExecContent(stream, Element(execContent[j]), 1); } - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; } @@ -1013,9 +1167,9 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Nodeexec_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 << ")) != USCXML_ERR_OK) return err;" << std::endl; stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << " return USCXML_ERR_MISSING_CALLBACK;" << std::endl; stream << padding << "}" << std::endl; } else if(TAGNAME(elem) == "foreach") { @@ -1036,17 +1190,17 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Nodeexec_content_foreach_done != NULL) {" << std::endl; stream << std::endl; - stream << padding << " if unlikely((ctx->exec_content_foreach_init(ctx, &" << _prefix << "_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << " while (ctx->exec_content_foreach_next(ctx, &" << _prefix << "_elem_foreachs[" << ATTR(elem, "documentOrder") << "]) == SCXML_ERR_OK) {" << std::endl; + stream << padding << " if unlikely((ctx->exec_content_foreach_init(ctx, &" << _prefix << "_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != USCXML_ERR_OK) return err;" << std::endl; + stream << padding << " while (ctx->exec_content_foreach_next(ctx, &" << _prefix << "_elem_foreachs[" << ATTR(elem, "documentOrder") << "]) == USCXML_ERR_OK) {" << std::endl; Arabica::DOM::Node 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, &" << _prefix << "_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << " if ((ctx->exec_content_foreach_done(ctx, &" << _prefix << "_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != USCXML_ERR_OK) return err;" << std::endl; stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << " return USCXML_ERR_MISSING_CALLBACK;" << std::endl; stream << padding << "}" << std::endl; } else if(TAGNAME(elem) == "if") { @@ -1069,7 +1223,7 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Nodeexec_content_raise(ctx, "; stream << (HAS_ATTR(elem, "event") ? "\"" + escape(ATTR(elem, "event")) + "\"" : "NULL"); - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << ")) != USCXML_ERR_OK) return err;" << std::endl; stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << " return USCXML_ERR_MISSING_CALLBACK;" << std::endl; stream << padding << "}" << std::endl; } else if(TAGNAME(elem) == "send") { @@ -1112,9 +1266,9 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Nodeexec_content_send != NULL) {" << std::endl; stream << padding; stream << " if ((ctx->exec_content_send(ctx, &" << _prefix << "_elem_sends[" << ATTR(elem, "documentOrder") << "]"; - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << ")) != USCXML_ERR_OK) return err;" << std::endl; stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << " return USCXML_ERR_MISSING_CALLBACK;" << std::endl; stream << padding << "}" << std::endl; } else if(TAGNAME(elem) == "cancel") { @@ -1124,9 +1278,9 @@ void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Nodeexec_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 << ")) != USCXML_ERR_OK) return err;" << std::endl; stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << " return USCXML_ERR_MISSING_CALLBACK;" << std::endl; stream << padding << "}" << std::endl; } else { @@ -1140,12 +1294,12 @@ void ChartToC::writeElementInfoInvocation(std::ostream& stream) { NodeSet invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); if (invokes.size() > 0) { _hasElement.insert("invoke"); - stream << "static const scxml_elem_invoke " << _prefix << "_elem_invokes[" << invokes.size() << "] = {" << std::endl; + stream << "static const uscxml_elem_invoke " << _prefix << "_elem_invokes[" << invokes.size() << "] = {" << std::endl; for (size_t i = 0; i < invokes.size(); i++) { Element invoke(invokes[i]); /* - stream << "struct scxml_elem_invoke {" << std::endl; + stream << "struct uscxml_elem_invoke {" << std::endl; stream << " const char* machine;" << std::endl; stream << " const char* type;" << std::endl; stream << " const char* typeexpr;" << std::endl; @@ -1155,8 +1309,8 @@ void ChartToC::writeElementInfoInvocation(std::ostream& stream) { stream << " const char* idlocation;" << std::endl; stream << " const char* sourcename;" << std::endl; stream << " const char* namelist;" << std::endl; - stream << " const uint8_t autoforward;" << std::endl; - stream << " const scxml_elem_param* params;" << std::endl; + stream << " const unsigned char autoforward;" << std::endl; + stream << " const uscxml_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; @@ -1170,7 +1324,7 @@ void ChartToC::writeElementInfoInvocation(std::ostream& stream) { size_t machIdx = 0; for (std::list::iterator machIter = _allMachines.begin(); machIter != _allMachines.end(); machIter++, machIdx++) { if ((*machIter)->_md5 == ATTR(invoke, "md5sum")) { - stream << "&scxml_machines[" << toStr(machIdx) << "]"; + stream << "&uscxml_machines[" << toStr(machIdx) << "]"; break; } } @@ -1262,7 +1416,7 @@ void ChartToC::writeElementInfo(std::ostream& stream) { NodeSet foreachs = DOMUtils::inDocumentOrder(_nsInfo.xmlNSPrefix + "foreach", _scxml); if (foreachs.size() > 0) { _hasElement.insert("foreach"); - stream << "static const scxml_elem_foreach " << _prefix << "_elem_foreachs[" << foreachs.size() << "] = {" << std::endl; + stream << "static const uscxml_elem_foreach " << _prefix << "_elem_foreachs[" << foreachs.size() << "] = {" << std::endl; stream << " /* array, item, index */" << std::endl; for (size_t i = 0; i < foreachs.size(); i++) { Element foreach(foreachs[i]); @@ -1298,7 +1452,7 @@ void ChartToC::writeElementInfo(std::ostream& stream) { parent = Node(); - stream << "static const scxml_elem_data " << _prefix << "_elem_datas[" << datas.size() + distinctParents << "] = {" << std::endl; + stream << "static const uscxml_elem_data " << _prefix << "_elem_datas[" << datas.size() + distinctParents << "] = {" << std::endl; stream << " /* id, src, expr, content */" << std::endl; for (size_t i = 0; i < datas.size(); i++) { Element data(datas[i]); @@ -1347,7 +1501,7 @@ void ChartToC::writeElementInfo(std::ostream& stream) { } parent = Node(); - stream << "static const scxml_elem_param " << _prefix << "_elem_params[" << params.size() + distinctParents << "] = {" << std::endl; + stream << "static const uscxml_elem_param " << _prefix << "_elem_params[" << params.size() + distinctParents << "] = {" << std::endl; stream << " /* name, expr, location */" << std::endl; for (size_t i = 0; i < params.size(); i++) { Element param(params[i]); @@ -1373,7 +1527,7 @@ void ChartToC::writeElementInfo(std::ostream& stream) { NodeSet sends = DOMUtils::inDocumentOrder(_nsInfo.xmlNSPrefix + "send", _scxml); if (sends.size() > 0) { _hasElement.insert("send"); - stream << "static const scxml_elem_send " << _prefix << "_elem_sends[" << sends.size() << "] = {" << std::endl; + stream << "static const uscxml_elem_send " << _prefix << "_elem_sends[" << sends.size() << "] = {" << std::endl; for (size_t i = 0; i < sends.size(); i++) { Element send(sends[i]); stream << " { "; @@ -1434,7 +1588,7 @@ void ChartToC::writeElementInfo(std::ostream& stream) { } NodeSet donedatas = DOMUtils::inDocumentOrder(_nsInfo.xmlNSPrefix + "donedata", _scxml); - stream << "static const scxml_elem_donedata " << _prefix << "_elem_donedatas[" << donedatas.size() + 1 << "] = {" << std::endl; + stream << "static const uscxml_elem_donedata " << _prefix << "_elem_donedatas[" << donedatas.size() + 1 << "] = {" << std::endl; stream << " /* source, content, contentexpr, params */" << std::endl; for (size_t i = 0; i < donedatas.size(); i++) { _hasElement.insert("donedata"); @@ -1476,7 +1630,7 @@ void ChartToC::writeMachineInfo(std::ostream& stream) { if (_topMostMachine != NULL) return; - stream << "const scxml_machine scxml_machines[" << _allMachines.size() + 1<< "] = {" << std::endl; + stream << "const uscxml_machine uscxml_machines[" << _allMachines.size() + 1<< "] = {" << std::endl; for (std::list::iterator machineIter = _allMachines.begin(); machineIter != _allMachines.end(); machineIter++) { ChartToC* m = (*machineIter); stream << " {" << std::endl; @@ -1493,7 +1647,7 @@ void ChartToC::writeMachineInfo(std::ostream& stream) { size_t parentIndex = 0; for (std::list::iterator parentIter = _allMachines.begin(); parentIter != _allMachines.end(); parentIter++, parentIndex++) { if (*parentIter == m->_parentMachine) { - stream << "&scxml_machines[" << toStr(parentIndex) << "]"; + stream << "&uscxml_machines[" << toStr(parentIndex) << "]"; } } } else { @@ -1519,7 +1673,7 @@ void ChartToC::writeMachineInfo(std::ostream& stream) { } void ChartToC::writeStates(std::ostream& stream) { - stream << "static const scxml_state " << _prefix << "_states[" << toStr(_states.size()) << "] = {" << std::endl; + stream << "static const uscxml_state " << _prefix << "_states[" << toStr(_states.size()) << "] = {" << std::endl; for (size_t i = 0; i < _states.size(); i++) { Element state(_states[i]); @@ -1572,26 +1726,26 @@ void ChartToC::writeStates(std::ostream& stream) { if (false) { } else if (iequals(TAGNAME(state), "initial")) { - stream << "SCXML_STATE_INITIAL"; + stream << "USCXML_STATE_INITIAL"; } else if (isFinal(state)) { - stream << "SCXML_STATE_FINAL"; + stream << "USCXML_STATE_FINAL"; } else if (isHistory(state)) { if (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")) { - stream << "SCXML_STATE_HISTORY_DEEP"; + stream << "USCXML_STATE_HISTORY_DEEP"; } else { - stream << "SCXML_STATE_HISTORY_SHALLOW"; + stream << "USCXML_STATE_HISTORY_SHALLOW"; } } else if (isAtomic(state)) { - stream << "SCXML_STATE_ATOMIC"; + stream << "USCXML_STATE_ATOMIC"; } else if (isParallel(state)) { - stream << "SCXML_STATE_PARALLEL"; + stream << "USCXML_STATE_PARALLEL"; } else if (isCompound(state)) { - stream << "SCXML_STATE_COMPOUND"; + stream << "USCXML_STATE_COMPOUND"; } else { // - stream << "SCXML_STATE_COMPOUND"; + stream << "USCXML_STATE_COMPOUND"; } if (HAS_ATTR(state, "hasHistoryChild")) { - stream << " | SCXML_STATE_HAS_HISTORY"; + stream << " | USCXML_STATE_HAS_HISTORY"; } stream << "," << std::endl; @@ -1610,7 +1764,7 @@ void ChartToC::writeTransitions(std::ostream& stream) { elements.insert(_nsInfo.xmlNSPrefix + "transition"); NodeSet transDocOrder = DOMUtils::inDocumentOrder(elements, _scxml); - stream << "static const scxml_transition " << _prefix << "_transitions[" << toStr(_transitions.size()) << "] = {" << std::endl; + stream << "static const uscxml_transition " << _prefix << "_transitions[" << toStr(_transitions.size()) << "] = {" << std::endl; for (size_t i = 0; i < _transitions.size(); i++) { Element transition(_transitions[i]); @@ -1656,27 +1810,27 @@ void ChartToC::writeTransitions(std::ostream& stream) { stream << " /* type */ "; std::string seperator = ""; if (!HAS_ATTR(transition, "target")) { - stream << seperator << "SCXML_TRANS_TARGETLESS"; + stream << seperator << "USCXML_TRANS_TARGETLESS"; seperator = " | "; } if (HAS_ATTR(transition, "type") && iequals(ATTR(transition, "type"), "internal")) { - stream << seperator << "SCXML_TRANS_INTERNAL"; + stream << seperator << "USCXML_TRANS_INTERNAL"; seperator = " | "; } if (!HAS_ATTR(transition, "event")) { - stream << seperator << "SCXML_TRANS_SPONTANEOUS"; + stream << seperator << "USCXML_TRANS_SPONTANEOUS"; seperator = " | "; } if (iequals(TAGNAME_CAST(transition.getParentNode()), "history")) { - stream << seperator << "SCXML_TRANS_HISTORY"; + stream << seperator << "USCXML_TRANS_HISTORY"; seperator = " | "; } if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) { - stream << seperator << "SCXML_TRANS_INITIAL"; + stream << seperator << "USCXML_TRANS_INITIAL"; seperator = " | "; } @@ -1762,67 +1916,68 @@ void ChartToC::writeCharArrayInitList(std::ostream& stream, const std::string& b } void ChartToC::writeFSM(std::ostream& stream) { - stream << "int scxml_step(scxml_ctx* ctx) {" << std::endl; + stream << "#ifndef USCXML_STEP_FUNCTION" << std::endl; + stream << "int uscxml_step(uscxml_ctx* ctx) {" << std::endl; stream << std::endl; - stream << " " << (_states.size() > _transitions.size() ? "SCXML_NR_STATES_TYPE" : "SCXML_NR_TRANS_TYPE") << " i, j, k;" << std::endl; - stream << " SCXML_NR_STATES_TYPE nr_states_bytes = ((SCXML_NUMBER_STATES + 7) & ~7) >> 3;" << std::endl; - stream << " SCXML_NR_TRANS_TYPE nr_trans_bytes = ((SCXML_NUMBER_TRANS + 7) & ~7) >> 3;" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; + stream << " " << (_states.size() > _transitions.size() ? "USCXML_NR_STATES_TYPE" : "USCXML_NR_TRANS_TYPE") << " i, j, k;" << std::endl; + stream << " USCXML_NR_STATES_TYPE nr_states_bytes = ((USCXML_NUMBER_STATES + 7) & ~7) >> 3;" << std::endl; + stream << " USCXML_NR_TRANS_TYPE nr_trans_bytes = ((USCXML_NUMBER_TRANS + 7) & ~7) >> 3;" << std::endl; + stream << " int err = USCXML_ERR_OK;" << std::endl; - stream << " char conflicts [SCXML_MAX_NR_TRANS_BYTES];" << std::endl; - stream << " char trans_set [SCXML_MAX_NR_TRANS_BYTES];" << std::endl; - stream << " char target_set [SCXML_MAX_NR_STATES_BYTES];" << std::endl; - stream << " char exit_set [SCXML_MAX_NR_STATES_BYTES];" << std::endl; - stream << " char entry_set [SCXML_MAX_NR_STATES_BYTES];" << std::endl; - stream << " char tmp_states [SCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " char conflicts [USCXML_MAX_NR_TRANS_BYTES];" << std::endl; + stream << " char trans_set [USCXML_MAX_NR_TRANS_BYTES];" << std::endl; + stream << " char target_set [USCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " char exit_set [USCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " char entry_set [USCXML_MAX_NR_STATES_BYTES];" << std::endl; + stream << " char tmp_states [USCXML_MAX_NR_STATES_BYTES];" << std::endl; stream << std::endl; - stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << "#ifdef USCXML_VERBOSE" << std::endl; stream << " printf(\"Config: \");" << std::endl; - stream << " printStateNames(ctx, ctx->config, SCXML_NUMBER_STATES);" << std::endl; + stream << " printStateNames(ctx, ctx->config, USCXML_NUMBER_STATES);" << std::endl; stream << "#endif" << std::endl; stream << std::endl; - stream << " if (ctx->flags & SCXML_CTX_FINISHED)" << std::endl; - stream << " return SCXML_ERR_DONE;" << std::endl; + stream << " if (ctx->flags & USCXML_CTX_FINISHED)" << std::endl; + stream << " return USCXML_ERR_DONE;" << std::endl; stream << std::endl; - stream << " if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL) {" << std::endl; - stream << " // exit all remaining states" << std::endl; - stream << " i = SCXML_NUMBER_STATES;" << std::endl; + stream << " if (ctx->flags & USCXML_CTX_TOP_LEVEL_FINAL) {" << std::endl; + stream << " /* exit all remaining states */" << std::endl; + stream << " i = USCXML_NUMBER_STATES;" << std::endl; stream << " while(i-- > 0) {" << std::endl; stream << " if (BIT_HAS(i, ctx->config)) {" << std::endl; - stream << " // call all on exit handlers" << std::endl; - stream << " if (ctx->machine->states[i].on_exit != NULL) {" << std::endl; - stream << " if unlikely((err = ctx->machine->states[i].on_exit(ctx, &ctx->machine->states[i], ctx->event)) != SCXML_ERR_OK)" << std::endl; + stream << " /* call all on exit handlers */" << std::endl; + stream << " if (USCXML_GET_STATE(i).on_exit != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_STATE(i).on_exit(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK)" << std::endl; stream << " return err;" << std::endl; stream << " }" << std::endl; // stream << " BIT_CLEAR(i, ctx->config);" << std::endl; stream << " }" << std::endl; stream << " if (BIT_HAS(i, ctx->invocations)) {" << std::endl; - stream << " if (ctx->machine->states[i].invoke != NULL)" << std::endl; - stream << " ctx->machine->states[i].invoke(ctx, &ctx->machine->states[i], NULL, 1);" << std::endl; + stream << " if (USCXML_GET_STATE(i).invoke != NULL)" << std::endl; + stream << " USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 1);" << std::endl; stream << " BIT_CLEAR(i, ctx->invocations);" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; - stream << " ctx->flags |= SCXML_CTX_FINISHED;" << std::endl; - stream << " return SCXML_ERR_DONE;" << std::endl; + stream << " ctx->flags |= USCXML_CTX_FINISHED;" << std::endl; + stream << " return USCXML_ERR_DONE;" << std::endl; stream << " }" << std::endl; stream << std::endl; stream << " bit_clear_all(target_set, nr_states_bytes);" << std::endl; stream << " bit_clear_all(trans_set, nr_trans_bytes);" << std::endl; - stream << " if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {" << std::endl; + stream << " if unlikely(ctx->flags == USCXML_CTX_PRISTINE) {" << std::endl; stream << " if (ctx->machine->script != NULL)" << std::endl; stream << " ctx->machine->script(ctx, &ctx->machine->states[0], NULL);" << std::endl; stream << " bit_or(target_set, ctx->machine->states[0].completion, nr_states_bytes);" << std::endl; - stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS | SCXML_CTX_INITIALIZED;" << std::endl; + stream << " ctx->flags |= USCXML_CTX_SPONTANEOUS | USCXML_CTX_INITIALIZED;" << std::endl; stream << " goto ESTABLISH_ENTRY_SET;" << std::endl; stream << " }" << std::endl; stream << std::endl; - stream << " if (ctx->flags & SCXML_CTX_SPONTANEOUS) {" << std::endl; + stream << " if (ctx->flags & USCXML_CTX_SPONTANEOUS) {" << std::endl; stream << " ctx->event = NULL;" << std::endl; stream << " goto SELECT_TRANSITIONS;" << std::endl; stream << " }" << std::endl; @@ -1831,18 +1986,18 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " }" << std::endl; stream << std::endl; - stream << " // manage invocations" << std::endl; - stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " // uninvoke" << std::endl; + stream << " /* manage invocations */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " /* uninvoke */" << std::endl; stream << " if (!BIT_HAS(i, ctx->config) && BIT_HAS(i, ctx->invocations)) {" << std::endl; - stream << " if (ctx->machine->states[i].invoke != NULL)" << std::endl; - stream << " ctx->machine->states[i].invoke(ctx, &ctx->machine->states[i], NULL, 1);" << std::endl; + stream << " if (USCXML_GET_STATE(i).invoke != NULL)" << std::endl; + stream << " USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 1);" << std::endl; stream << " BIT_CLEAR(i, ctx->invocations)" << std::endl; stream << " }" << std::endl; - stream << " // invoke" << std::endl; + stream << " /* invoke */" << std::endl; stream << " if (BIT_HAS(i, ctx->config) && !BIT_HAS(i, ctx->invocations)) {" << std::endl; - stream << " if (ctx->machine->states[i].invoke != NULL)" << std::endl; - stream << " ctx->machine->states[i].invoke(ctx, &ctx->machine->states[i], NULL, 0);" << std::endl; + stream << " if (USCXML_GET_STATE(i).invoke != NULL)" << std::endl; + stream << " USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 0);" << std::endl; stream << " BIT_SET_AT(i, ctx->invocations)" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; @@ -1856,29 +2011,29 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << "SELECT_TRANSITIONS:" << std::endl; stream << " bit_clear_all(conflicts, nr_trans_bytes);" << std::endl; stream << " bit_clear_all(exit_set, nr_states_bytes);" << std::endl; - stream << " for (i = 0; i < SCXML_NUMBER_TRANS; i++) {" << std::endl; - stream << " // never select history or initial transitions automatically" << std::endl; - stream << " if unlikely(ctx->machine->transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL))" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_TRANS; i++) {" << std::endl; + stream << " /* never select history or initial transitions automatically */" << std::endl; + stream << " if unlikely(USCXML_GET_TRANS(i).type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL))" << std::endl; stream << " continue;" << std::endl; stream << std::endl; - stream << " // is the transition active?" << std::endl; - stream << " if (BIT_HAS(ctx->machine->transitions[i].source, ctx->config)) {" << std::endl; - stream << " // is it non-conflicting?" << std::endl; + stream << " /* is the transition active? */" << std::endl; + stream << " if (BIT_HAS(USCXML_GET_TRANS(i).source, ctx->config)) {" << std::endl; + stream << " /* is it non-conflicting? */" << std::endl; stream << " if (!BIT_HAS(i, conflicts)) {" << std::endl; - stream << " // is it enabled?" << std::endl; - stream << " if (ctx->is_enabled(ctx, &ctx->machine->transitions[i], ctx->event) > 0) {" << std::endl; - stream << " // remember that we found a transition" << std::endl; - stream << " ctx->flags |= SCXML_CTX_TRANSITION_FOUND;" << std::endl; + stream << " /* is it enabled? */" << std::endl; + stream << " if (ctx->is_enabled(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) {" << std::endl; + stream << " /* remember that we found a transition */" << std::endl; + stream << " ctx->flags |= USCXML_CTX_TRANSITION_FOUND;" << std::endl; stream << std::endl; - stream << " // transitions that are pre-empted" << std::endl; - stream << " bit_or(conflicts, ctx->machine->transitions[i].conflicts, nr_trans_bytes);" << std::endl; + stream << " /* transitions that are pre-empted */" << std::endl; + stream << " bit_or(conflicts, USCXML_GET_TRANS(i).conflicts, nr_trans_bytes);" << std::endl; stream << std::endl; - stream << " // states that are directly targeted (resolve as entry-set later)" << std::endl; - stream << " bit_or(target_set, ctx->machine->transitions[i].target, nr_states_bytes);" << std::endl; + stream << " /* states that are directly targeted (resolve as entry-set later) */" << std::endl; + stream << " bit_or(target_set, USCXML_GET_TRANS(i).target, nr_states_bytes);" << std::endl; stream << std::endl; - stream << " // states that will be left" << std::endl; - stream << " bit_or(exit_set, ctx->machine->transitions[i].exit_set, nr_states_bytes);" << std::endl; + stream << " /* states that will be left */" << std::endl; + stream << " bit_or(exit_set, USCXML_GET_TRANS(i).exit_set, nr_states_bytes);" << std::endl; stream << std::endl; stream << " BIT_SET_AT(i, trans_set);" << std::endl; stream << " }" << std::endl; @@ -1888,48 +2043,48 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " bit_and(exit_set, ctx->config, nr_states_bytes);" << std::endl; stream << std::endl; - stream << " if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) {" << std::endl; - stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS;" << std::endl; - stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl; + stream << " if (ctx->flags & USCXML_CTX_TRANSITION_FOUND) {" << std::endl; + stream << " ctx->flags |= USCXML_CTX_SPONTANEOUS;" << std::endl; + stream << " ctx->flags &= ~USCXML_CTX_TRANSITION_FOUND;" << std::endl; stream << " } else {" << std::endl; - stream << " ctx->flags &= ~SCXML_CTX_SPONTANEOUS;" << std::endl; -// stream << " return SCXML_ERR_OK;" << std::endl; + stream << " ctx->flags &= ~USCXML_CTX_SPONTANEOUS;" << std::endl; +// stream << " return USCXML_ERR_OK;" << std::endl; stream << " }" << std::endl; stream << std::endl; - stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << "#ifdef USCXML_VERBOSE" << std::endl; stream << " printf(\"Targets: \");" << std::endl; - stream << " printStateNames(ctx, target_set, SCXML_NUMBER_STATES);" << std::endl; + stream << " printStateNames(ctx, target_set, USCXML_NUMBER_STATES);" << std::endl; stream << "#endif" << std::endl; stream << std::endl; - stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << "#ifdef USCXML_VERBOSE" << std::endl; stream << " printf(\"Exiting: \");" << std::endl; - stream << " printStateNames(ctx, exit_set, SCXML_NUMBER_STATES);" << std::endl; + stream << " printStateNames(ctx, exit_set, USCXML_NUMBER_STATES);" << std::endl; stream << "#endif" << std::endl; stream << std::endl; - stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << "#ifdef USCXML_VERBOSE" << std::endl; stream << " printf(\"History: \");" << std::endl; - stream << " printStateNames(ctx, ctx->history, SCXML_NUMBER_STATES);" << std::endl; + stream << " printStateNames(ctx, ctx->history, USCXML_NUMBER_STATES);" << std::endl; stream << "#endif" << std::endl; stream << std::endl; - stream << "// REMEMBER_HISTORY:" << std::endl; - stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " if unlikely(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl; - stream << " SCXML_STATE_MASK(ctx->machine->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(BIT_HAS(ctx->machine->states[i].parent, exit_set)) {" << std::endl; - stream << " bit_copy(tmp_states, ctx->machine->states[i].completion, nr_states_bytes);" << std::endl; + stream << "/* REMEMBER_HISTORY: */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_SHALLOW ||" << std::endl; + stream << " USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP) {" << std::endl; + stream << " /* a history state whose parent is about to be exited */" << std::endl; + stream << " if unlikely(BIT_HAS(USCXML_GET_STATE(i).parent, exit_set)) {" << std::endl; + stream << " bit_copy(tmp_states, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; stream << std::endl; - stream << " // set those states who were enabled" << std::endl; + stream << " /* set those states who were enabled */" << std::endl; stream << " bit_and(tmp_states, ctx->config, nr_states_bytes);" << std::endl; stream << std::endl; - stream << " // clear current history with completion mask" << std::endl; - stream << " bit_and_not(ctx->history, ctx->machine->states[i].completion, nr_states_bytes);" << std::endl; + stream << " /* clear current history with completion mask */" << std::endl; + stream << " bit_and_not(ctx->history, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; stream << std::endl; - stream << " // set history" << std::endl; + stream << " /* set history */" << std::endl; stream << " bit_or(ctx->history, tmp_states, nr_states_bytes);" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; @@ -1937,36 +2092,36 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << std::endl; stream << "ESTABLISH_ENTRY_SET:" << std::endl; - stream << " // calculate new entry set" << std::endl; + stream << " /* calculate new entry set */" << std::endl; stream << " bit_copy(entry_set, target_set, nr_states_bytes);" << std::endl; stream << std::endl; - stream << " // iterate for ancestors" << std::endl; - stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " /* iterate for ancestors */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; stream << " if (BIT_HAS(i, entry_set)) {" << std::endl; - stream << " bit_or(entry_set, ctx->machine->states[i].ancestors, nr_states_bytes);" << std::endl; + stream << " bit_or(entry_set, USCXML_GET_STATE(i).ancestors, nr_states_bytes);" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; stream << std::endl; - stream << " // iterate for descendants" << std::endl; - stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " /* iterate for descendants */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; stream << " if (BIT_HAS(i, entry_set)) {" << std::endl; - stream << " switch (SCXML_STATE_MASK(ctx->machine->states[i].type)) {" << std::endl; - stream << " case SCXML_STATE_PARALLEL: {" << std::endl; - stream << " bit_or(entry_set, ctx->machine->states[i].completion, nr_states_bytes);" << std::endl; + stream << " switch (USCXML_STATE_MASK(USCXML_GET_STATE(i).type)) {" << std::endl; + stream << " case USCXML_STATE_PARALLEL: {" << std::endl; + stream << " bit_or(entry_set, USCXML_GET_STATE(i).completion, nr_states_bytes);" << 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 << " if (!bit_has_and(ctx->machine->states[i].completion, ctx->history, nr_states_bytes) &&" << std::endl; - stream << " !BIT_HAS(ctx->machine->states[i].parent, ctx->config)) {" << std::endl; - stream << " // nothing set for history, look for a default transition" << std::endl; - stream << " for (j = 0; j < SCXML_NUMBER_TRANS; j++) {" << std::endl; + stream << " case USCXML_STATE_HISTORY_SHALLOW:" << std::endl; + stream << " case USCXML_STATE_HISTORY_DEEP: {" << std::endl; + stream << " if (!bit_has_and(USCXML_GET_STATE(i).completion, ctx->history, nr_states_bytes) &&" << std::endl; + stream << " !BIT_HAS(USCXML_GET_STATE(i).parent, ctx->config)) {" << std::endl; + stream << " /* nothing set for history, look for a default transition */" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_TRANS; j++) {" << std::endl; stream << " if unlikely(ctx->machine->transitions[j].source == i) {" << std::endl; stream << " bit_or(entry_set, ctx->machine->transitions[j].target, nr_states_bytes);" << std::endl; - stream << " if(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_DEEP &&" << std::endl; - stream << " !bit_has_and(ctx->machine->transitions[j].target, ctx->machine->states[i].children, nr_states_bytes)) {" << std::endl; - stream << " for (k = i + 1; k < SCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " if(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP &&" << std::endl; + stream << " !bit_has_and(ctx->machine->transitions[j].target, USCXML_GET_STATE(i).children, nr_states_bytes)) {" << std::endl; + stream << " for (k = i + 1; k < USCXML_NUMBER_STATES; k++) {" << std::endl; stream << " if (BIT_HAS(k, ctx->machine->transitions[j].target)) {" << std::endl; stream << " bit_or(entry_set, ctx->machine->states[k].ancestors, nr_states_bytes);" << std::endl; stream << " break;" << std::endl; @@ -1976,24 +2131,24 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " BIT_SET_AT(j, trans_set);" << std::endl; stream << " break;" << std::endl; stream << " }" << std::endl; - stream << " // Note: SCXML mandates every history to have a transition!" << std::endl; + stream << " /* Note: SCXML mandates every history to have a transition! */" << std::endl; stream << " }" << std::endl; stream << " } else {" << std::endl; - stream << " bit_copy(tmp_states, ctx->machine->states[i].completion, nr_states_bytes);" << std::endl; + stream << " bit_copy(tmp_states, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; stream << " bit_and(tmp_states, ctx->history, nr_states_bytes);" << std::endl; stream << " bit_or(entry_set, tmp_states, nr_states_bytes);" << std::endl; - stream << " if (ctx->machine->states[i].type == (SCXML_STATE_HAS_HISTORY | SCXML_STATE_HISTORY_DEEP)) {" << std::endl; - stream << " // a deep history state with nested histories -> more completion" << std::endl; - stream << " for (j = i + 1; j < SCXML_NUMBER_STATES; j++) {" << std::endl; - stream << " if (BIT_HAS(j, ctx->machine->states[i].completion) &&" << std::endl; + stream << " if (USCXML_GET_STATE(i).type == (USCXML_STATE_HAS_HISTORY | USCXML_STATE_HISTORY_DEEP)) {" << std::endl; + stream << " /* a deep history state with nested histories -> more completion */" << std::endl; + stream << " for (j = i + 1; j < USCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " if (BIT_HAS(j, USCXML_GET_STATE(i).completion) &&" << std::endl; stream << " BIT_HAS(j, entry_set) &&" << std::endl; - stream << " (ctx->machine->states[j].type & SCXML_STATE_HAS_HISTORY)) {" << std::endl; - stream << " for (k = j + 1; k < SCXML_NUMBER_STATES; k++) {" << std::endl; - stream << " // add nested history to entry_set" << std::endl; - stream << " if ((SCXML_STATE_MASK(ctx->machine->states[k].type) == SCXML_STATE_HISTORY_DEEP ||" << std::endl; - stream << " SCXML_STATE_MASK(ctx->machine->states[k].type) == SCXML_STATE_HISTORY_SHALLOW) &&" << std::endl; + stream << " (ctx->machine->states[j].type & USCXML_STATE_HAS_HISTORY)) {" << std::endl; + stream << " for (k = j + 1; k < USCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " /* add nested history to entry_set */" << std::endl; + stream << " if ((USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_HISTORY_DEEP ||" << std::endl; + stream << " USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_HISTORY_SHALLOW) &&" << std::endl; stream << " BIT_HAS(k, ctx->machine->states[j].children)) {" << std::endl; - stream << " // a nested history state" << std::endl; + stream << " /* a nested history state */" << std::endl; stream << " BIT_SET_AT(k, entry_set);" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; @@ -2003,13 +2158,13 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " }" << std::endl; stream << " break;" << std::endl; stream << " }" << std::endl; - stream << " case SCXML_STATE_INITIAL: {" << std::endl; - stream << " for (j = 0; j < SCXML_NUMBER_TRANS; j++) {" << std::endl; + stream << " case USCXML_STATE_INITIAL: {" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_TRANS; j++) {" << std::endl; stream << " if (ctx->machine->transitions[j].source == i) {" << std::endl; stream << " BIT_SET_AT(j, trans_set);" << std::endl; stream << " BIT_CLEAR(i, entry_set);" << std::endl; stream << " bit_or(entry_set, ctx->machine->transitions[j].target, nr_states_bytes);" << std::endl; - stream << " for (k = i + 1; k < SCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " for (k = i + 1; k < USCXML_NUMBER_STATES; k++) {" << std::endl; stream << " if (BIT_HAS(k, ctx->machine->transitions[j].target)) {" << std::endl; stream << " bit_or(entry_set, ctx->machine->states[k].ancestors, nr_states_bytes);" << std::endl; stream << " }" << std::endl; @@ -2018,18 +2173,18 @@ void ChartToC::writeFSM(std::ostream& stream) { 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, ctx->machine->states[i].children, nr_states_bytes) &&" << std::endl; - stream << " (!bit_has_and(ctx->config, ctx->machine->states[i].children, nr_states_bytes) ||" << std::endl; - stream << " bit_has_and(exit_set, ctx->machine->states[i].children, nr_states_bytes)))" << std::endl; + stream << " case USCXML_STATE_COMPOUND: { /* we need to check whether one child is already in entry_set */" << std::endl; + stream << " if (!bit_has_and(entry_set, USCXML_GET_STATE(i).children, nr_states_bytes) &&" << std::endl; + stream << " (!bit_has_and(ctx->config, USCXML_GET_STATE(i).children, nr_states_bytes) ||" << std::endl; + stream << " bit_has_and(exit_set, USCXML_GET_STATE(i).children, nr_states_bytes)))" << std::endl; stream << " {" << std::endl; - stream << " bit_or(entry_set, ctx->machine->states[i].completion, nr_states_bytes);" << std::endl; - stream << " if (!bit_has_and(ctx->machine->states[i].completion, ctx->machine->states[i].children, nr_states_bytes)) {" << std::endl; - stream << " // deep completion" << std::endl; - stream << " for (j = i + 1; j < SCXML_NUMBER_STATES; j++) {" << std::endl; - stream << " if (BIT_HAS(j, ctx->machine->states[i].completion)) {" << std::endl; + stream << " bit_or(entry_set, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; + stream << " if (!bit_has_and(USCXML_GET_STATE(i).completion, USCXML_GET_STATE(i).children, nr_states_bytes)) {" << std::endl; + stream << " /* deep completion */" << std::endl; + stream << " for (j = i + 1; j < USCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " if (BIT_HAS(j, USCXML_GET_STATE(i).completion)) {" << std::endl; stream << " bit_or(entry_set, ctx->machine->states[j].ancestors, nr_states_bytes);" << std::endl; - stream << " break; // completion of compound is single state" << std::endl; + stream << " break; /* completion of compound is single state */" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; @@ -2041,19 +2196,19 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " }" << std::endl; stream << std::endl; - stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << "#ifdef USCXML_VERBOSE" << std::endl; stream << " printf(\"Transitions: \");" << std::endl; stream << " printBitsetIndices(trans_set, sizeof(char) * 8 * nr_trans_bytes);" << std::endl; stream << "#endif" << std::endl; stream << std::endl; - stream << "// EXIT_STATES:" << std::endl; - stream << " i = SCXML_NUMBER_STATES;" << std::endl; + stream << "/* EXIT_STATES: */" << std::endl; + stream << " i = USCXML_NUMBER_STATES;" << std::endl; stream << " while(i-- > 0) {" << std::endl; stream << " if (BIT_HAS(i, exit_set) && BIT_HAS(i, ctx->config)) {" << std::endl; - stream << " // call all on exit handlers" << std::endl; - stream << " if (ctx->machine->states[i].on_exit != NULL) {" << std::endl; - stream << " if unlikely((err = ctx->machine->states[i].on_exit(ctx, &ctx->machine->states[i], ctx->event)) != SCXML_ERR_OK)" << std::endl; + stream << " /* call all on exit handlers */" << std::endl; + stream << " if (USCXML_GET_STATE(i).on_exit != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_STATE(i).on_exit(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK)" << std::endl; stream << " return err;" << std::endl; stream << " }" << std::endl; stream << " BIT_CLEAR(i, ctx->config);" << std::endl; @@ -2061,83 +2216,83 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " }" << std::endl; stream << std::endl; - stream << "// TAKE_TRANSITIONS:" << std::endl; - stream << " for (i = 0; i < SCXML_NUMBER_TRANS; i++) {" << std::endl; - stream << " if (BIT_HAS(i, trans_set) && (ctx->machine->transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) == 0) {" << std::endl; - stream << " // call executable content in transition" << std::endl; - stream << " if (ctx->machine->transitions[i].on_transition != NULL) {" << std::endl; - stream << " if unlikely((err = ctx->machine->transitions[i].on_transition(ctx," << std::endl; - stream << " &ctx->machine->states[ctx->machine->transitions[i].source]," << std::endl; - stream << " ctx->event)) != SCXML_ERR_OK)" << std::endl; + stream << "/* TAKE_TRANSITIONS: */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_TRANS; i++) {" << std::endl; + stream << " if (BIT_HAS(i, trans_set) && (USCXML_GET_TRANS(i).type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL)) == 0) {" << std::endl; + stream << " /* call executable content in transition */" << std::endl; + stream << " if (USCXML_GET_TRANS(i).on_transition != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_TRANS(i).on_transition(ctx," << std::endl; + stream << " &ctx->machine->states[USCXML_GET_TRANS(i).source]," << std::endl; + stream << " ctx->event)) != USCXML_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 << "#ifdef USCXML_VERBOSE" << std::endl; stream << " printf(\"Entering: \");" << std::endl; - stream << " printStateNames(ctx, entry_set, SCXML_NUMBER_STATES);" << std::endl; + stream << " printStateNames(ctx, entry_set, USCXML_NUMBER_STATES);" << std::endl; stream << "#endif" << std::endl; stream << std::endl; - stream << "// ENTER_STATES:" << std::endl; - stream << " for (i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << "/* ENTER_STATES: */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; stream << " if (BIT_HAS(i, entry_set) && !BIT_HAS(i, ctx->config)) {" << std::endl; - stream << " // these are no proper states" << std::endl; - stream << " if unlikely(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_DEEP ||" << std::endl; - stream << " SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl; - stream << " SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_INITIAL)" << std::endl; + stream << " /* these are no proper states */" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP ||" << std::endl; + stream << " USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_SHALLOW ||" << std::endl; + stream << " USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_INITIAL)" << std::endl; stream << " continue;" << std::endl; stream << std::endl; stream << " BIT_SET_AT(i, ctx->config);" << std::endl; stream << std::endl; - stream << " // initialize data" << std::endl; + stream << " /* initialize data */" << std::endl; stream << " if (!BIT_HAS(i, ctx->initialized_data)) {" << std::endl; - stream << " if unlikely(ctx->machine->states[i].data != NULL && ctx->exec_content_init != NULL) {" << std::endl; - stream << " ctx->exec_content_init(ctx, ctx->machine->states[i].data);" << std::endl; + stream << " if unlikely(USCXML_GET_STATE(i).data != NULL && ctx->exec_content_init != NULL) {" << std::endl; + stream << " ctx->exec_content_init(ctx, USCXML_GET_STATE(i).data);" << std::endl; stream << " }" << std::endl; stream << " BIT_SET_AT(i, ctx->initialized_data);" << std::endl; stream << " }" << std::endl; stream << std::endl; - stream << " if (ctx->machine->states[i].on_entry != NULL) {" << std::endl; - stream << " if unlikely((err = ctx->machine->states[i].on_entry(ctx, &ctx->machine->states[i], ctx->event)) != SCXML_ERR_OK)" << std::endl; + stream << " if (USCXML_GET_STATE(i).on_entry != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_STATE(i).on_entry(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK)" << std::endl; stream << " return err;" << std::endl; stream << " }" << std::endl; stream << std::endl; - stream << " // take history and initial transitions" << std::endl; - stream << " for (j = 0; j < SCXML_NUMBER_TRANS; j++) {" << std::endl; + stream << " /* take history and initial transitions */" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_TRANS; j++) {" << std::endl; stream << " if unlikely(BIT_HAS(j, trans_set) &&" << std::endl; - stream << " (ctx->machine->transitions[j].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) &&" << std::endl; + stream << " (ctx->machine->transitions[j].type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL)) &&" << std::endl; stream << " ctx->machine->states[ctx->machine->transitions[j].source].parent == i) {" << std::endl; - stream << " // call executable content in transition" << std::endl; + stream << " /* call executable content in transition */" << std::endl; stream << " if (ctx->machine->transitions[j].on_transition != NULL) {" << std::endl; stream << " if unlikely((err = ctx->machine->transitions[j].on_transition(ctx," << std::endl; - stream << " &ctx->machine->states[i]," << std::endl; - stream << " ctx->event)) != SCXML_ERR_OK)" << std::endl; + stream << " &USCXML_GET_STATE(i)," << std::endl; + stream << " ctx->event)) != USCXML_ERR_OK)" << std::endl; stream << " return err;" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; stream << " }" << std::endl; stream << std::endl; - stream << " // handle final states" << std::endl; - stream << " if unlikely(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_FINAL) {" << std::endl; - stream << " if unlikely(ctx->machine->states[i].ancestors[0] == 0x01) {" << std::endl; - stream << " ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL;" << std::endl; + stream << " /* handle final states */" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_FINAL) {" << std::endl; + stream << " if unlikely(USCXML_GET_STATE(i).ancestors[0] == 0x01) {" << std::endl; + stream << " ctx->flags |= USCXML_CTX_TOP_LEVEL_FINAL;" << std::endl; stream << " } else {" << std::endl; - stream << " // raise done event" << std::endl; - stream << " const scxml_elem_donedata* donedata = &ctx->machine->donedata[0];" << std::endl; - stream << " while(ELEM_DONEDATA_IS_SET(donedata)) {" << std::endl; + stream << " /* raise done event */" << std::endl; + stream << " const uscxml_elem_donedata* donedata = &ctx->machine->donedata[0];" << std::endl; + stream << " while(USCXML_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, &ctx->machine->states[ctx->machine->states[i].parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl; + stream << " ctx->raise_done_event(ctx, &ctx->machine->states[USCXML_GET_STATE(i).parent], (USCXML_ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl; stream << " }" << std::endl; stream << std::endl; @@ -2148,13 +2303,13 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " * 3. Iterate all active final states and remove their ancestors" << std::endl; stream << " * 4. If a state remains, not all children of a parallel are final" << std::endl; stream << " */" << std::endl; - stream << " for (j = 0; j < SCXML_NUMBER_STATES; j++) {" << std::endl; - stream << " if unlikely(SCXML_STATE_MASK(ctx->machine->states[j].type) == SCXML_STATE_PARALLEL &&" << std::endl; - stream << " BIT_HAS(j, ctx->machine->states[i].ancestors)) {" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(ctx->machine->states[j].type) == USCXML_STATE_PARALLEL &&" << std::endl; + stream << " BIT_HAS(j, USCXML_GET_STATE(i).ancestors)) {" << std::endl; stream << " bit_clear_all(tmp_states, nr_states_bytes);" << std::endl; - stream << " for (k = 0; k < SCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " for (k = 0; k < USCXML_NUMBER_STATES; k++) {" << std::endl; stream << " if unlikely(BIT_HAS(j, ctx->machine->states[k].ancestors) && BIT_HAS(k, ctx->config)) {" << std::endl; - stream << " if (SCXML_STATE_MASK(ctx->machine->states[k].type) == SCXML_STATE_FINAL) {" << std::endl; + stream << " if (USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_FINAL) {" << std::endl; stream << " bit_and_not(tmp_states, ctx->machine->states[k].ancestors, nr_states_bytes);" << std::endl; stream << " } else {" << std::endl; stream << " BIT_SET_AT(k, tmp_states);" << std::endl; @@ -2175,9 +2330,13 @@ void ChartToC::writeFSM(std::ostream& stream) { stream << " }" << std::endl; stream << std::endl; - stream << " return SCXML_ERR_OK;" << std::endl; + stream << " return USCXML_ERR_OK;" << std::endl; stream << "}" << std::endl; stream << std::endl; + + stream << "#define USCXML_STEP_FUNCTION" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; } ChartToC::~ChartToC() { diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h index f9b9599..4e1d14a 100644 --- a/src/uscxml/transform/ChartToC.h +++ b/src/uscxml/transform/ChartToC.h @@ -1,6 +1,6 @@ /** * @file - * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @author 2012-2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) * @copyright Simplified BSD * * @cond @@ -51,6 +51,7 @@ protected: void writeExecContent(std::ostream& stream); void writeExecContentFinalize(std::ostream& stream); void writeElementInfoInvocation(std::ostream& stream); + void writeForwardDeclarations(std::ostream& stream); void writeElementInfo(std::ostream& stream); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c4486eb..d61abf7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,7 +31,11 @@ if (NOT WIN32) target_link_libraries(test-promela-parser uscxml_transform) USCXML_TEST_COMPILE(BUILD_ONLY NAME test-stress LABEL general/test-stress FILES src/test-stress.cpp) - USCXML_TEST_COMPILE(NAME test-c-machine LABEL general/test-c-machine FILES src/test-c-machine.cpp) + USCXML_TEST_COMPILE(NAME test-c-machine LABEL general/test-c-machine FILES + src/test-c-machine.cpp + # ../src/compiled/cxx/StateChart.cpp + # ../src/compiled/cxx/StateChart.h + ) USCXML_TEST_COMPILE(NAME test-misc LABEL general/test-misc FILES src/test-misc.cpp) endif() diff --git a/test/src/test-c-machine.cpp b/test/src/test-c-machine.cpp index 85571e4..3bd92aa 100644 --- a/test/src/test-c-machine.cpp +++ b/test/src/test-c-machine.cpp @@ -6,7 +6,7 @@ #include // deque #include // trim -#define SCXML_VERBOSE +#define USCXML_VERBOSE #include "uscxml/config.h" @@ -35,20 +35,20 @@ # include "uscxml/plugins/DataModel.h" # endif -#define USER_DATA(ctx) ((StateMachine*)(((scxml_ctx*)ctx)->user_data)) +#define USER_DATA(ctx) ((StateMachine*)(((uscxml_ctx*)ctx)->user_data)) using namespace uscxml; class StateMachine : public InterpreterInfo { public: - StateMachine(const scxml_machine* machine) : machine(machine), parentMachine(NULL), topMostMachine(NULL), invocation(NULL) { + StateMachine(const uscxml_machine* machine) : machine(machine), parentMachine(NULL), topMostMachine(NULL), invocation(NULL) { allMachines[sessionId] = this; topMostMachine = this; currentMachine = allMachines.begin(); init(); } - StateMachine(StateMachine* parent, const scxml_machine* machine, const scxml_elem_invoke* invoke) : machine(machine), invocation(invoke) { + StateMachine(StateMachine* parent, const uscxml_machine* machine, const uscxml_elem_invoke* invoke) : machine(machine), invocation(invoke) { parentMachine = parent; topMostMachine = parent->topMostMachine; init(); @@ -60,7 +60,7 @@ public: currEvent = NULL; // clear and initialize machine context - memset(&ctx, 0, sizeof(scxml_ctx)); + memset(&ctx, 0, sizeof(uscxml_ctx)); ctx.machine = machine; ctx.user_data = (void*)this; @@ -90,8 +90,8 @@ public: if (invocation != NULL) { /// test 226/240 - initialize from invoke request if (invocation->params != NULL) { - const scxml_elem_param* param = invocation->params; - while(ELEM_PARAM_IS_SET(param)) { + const uscxml_elem_param* param = invocation->params; + while(USCXML_ELEM_PARAM_IS_SET(param)) { std::string identifier; if (param->name != NULL) { identifier = param->name; @@ -147,13 +147,13 @@ public: bool hasPendingWork() { return (iq.size() > 0 || eq.size() > 0 || - ctx.flags & SCXML_CTX_SPONTANEOUS || - ctx.flags == SCXML_CTX_PRISTINE || + ctx.flags & USCXML_CTX_SPONTANEOUS || + ctx.flags == USCXML_CTX_PRISTINE || memcmp(ctx.config, ctx.invocations, sizeof(ctx.config)) != 0); } bool isDone() { - return ctx.flags & SCXML_CTX_FINISHED; + return ctx.flags & USCXML_CTX_FINISHED; } void finalize() { @@ -202,16 +202,16 @@ public: StateMachine* toRun = currentMachine->second; if (!toRun->hasPendingWork()) { - return SCXML_ERR_IDLE; + return USCXML_ERR_IDLE; } // test 187 if (toRun->isDone()) { toRun->finalize(); - return SCXML_ERR_IDLE; + return USCXML_ERR_IDLE; } - state = scxml_step(&toRun->ctx); + state = uscxml_step(&toRun->ctx); if (toRun->currEvent != NULL) { delete toRun->currEvent; toRun->currEvent = NULL; @@ -250,7 +250,7 @@ public: // callbacks for scxml context - static int isEnabled(const scxml_ctx* ctx, const scxml_transition* t, const void* e) { + static int isEnabled(const uscxml_ctx* ctx, const uscxml_transition* t, const void* e) { Event* event = (Event*)e; if (event == NULL) { if (t->event == NULL) { @@ -277,7 +277,7 @@ public: return false; } - static int isTrue(const scxml_ctx* ctx, const char* expr) { + static int isTrue(const uscxml_ctx* ctx, const char* expr) { try { return USER_DATA(ctx)->dataModel.evalAsBool(expr); } catch (Event e) { @@ -286,7 +286,7 @@ public: return false; } - static int invoke(const scxml_ctx* ctx, const scxml_state* s, const scxml_elem_invoke* invocation, uint8_t uninvoke) { + static int invoke(const uscxml_ctx* ctx, const uscxml_state* s, const uscxml_elem_invoke* invocation, unsigned char uninvoke) { std::map &allMachines = USER_DATA(ctx)->topMostMachine->allMachines; StateMachine* topMachine = USER_DATA(ctx)->topMostMachine; @@ -300,7 +300,7 @@ public: topMachine->invocationIds.erase(invocation); } } else { - return SCXML_ERR_UNSUPPORTED; + return USCXML_ERR_UNSUPPORTED; } } else { // invocations @@ -311,7 +311,7 @@ public: invokedMachine = new StateMachine(USER_DATA(ctx), invocation->machine, invocation); } catch (Event e) { delete invokedMachine; - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } if (invocation->id != NULL) { invokedMachine->invokeId = invocation->id; @@ -321,18 +321,18 @@ public: ctx->exec_content_assign(ctx, invocation->idlocation, std::string("\"" + invokedMachine->invokeId + "\"").c_str()); } else { delete invokedMachine; - return SCXML_ERR_UNSUPPORTED; + return USCXML_ERR_UNSUPPORTED; } allMachines[invokedMachine->invokeId] = invokedMachine; topMachine->invocationIds[invocation] = invokedMachine->invokeId; } else { - return SCXML_ERR_UNSUPPORTED; + return USCXML_ERR_UNSUPPORTED; } } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int raiseDoneEvent(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata) { + static int raiseDoneEvent(const uscxml_ctx* ctx, const uscxml_state* state, const uscxml_elem_donedata* donedata) { Event* e = new Event(); e->name = std::string("done.state.") + state->name; @@ -347,8 +347,8 @@ public: } } else { try { - const scxml_elem_param* param = donedata->params; - while (param && ELEM_PARAM_IS_SET(param)) { + const uscxml_elem_param* param = donedata->params; + while (param && USCXML_ELEM_PARAM_IS_SET(param)) { Data paramValue; if (param->expr != NULL) { paramValue = USER_DATA(ctx)->dataModel.getStringAsData(param->expr); @@ -364,14 +364,14 @@ public: } } -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Raising Done Event: %s\n", e->name.c_str()); #endif USER_DATA(ctx)->iq.push_back(e); - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentSend(const scxml_ctx* ctx, const scxml_elem_send* send) { + static int execContentSend(const uscxml_ctx* ctx, const uscxml_elem_send* send) { SendRequest* e = new SendRequest(); std::string target; @@ -386,7 +386,7 @@ public: if (e->target.size() > 0 && (e->target[0] != '#' || e->target[1] != '_')) { delete e; execContentRaise(ctx, "error.execution"); - return SCXML_ERR_INVALID_TARGET; + return USCXML_ERR_INVALID_TARGET; } e->origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; @@ -403,14 +403,14 @@ public: } catch (Event exc) { execContentRaise(ctx, exc.name.c_str()); delete e; - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } // only one somewhat supported if (e->type != "http://www.w3.org/TR/scxml/#SCXMLEventProcessor") { delete e; execContentRaise(ctx, "error.execution"); - return SCXML_ERR_INVALID_TARGET; + return USCXML_ERR_INVALID_TARGET; } e->origintype = e->type; @@ -423,8 +423,8 @@ public: } try { - const scxml_elem_param* param = send->params; - while (param && ELEM_PARAM_IS_SET(param)) { + const uscxml_elem_param* param = send->params; + while (param && USCXML_ELEM_PARAM_IS_SET(param)) { Data paramValue; if (param->expr != NULL) { paramValue = USER_DATA(ctx)->dataModel.getStringAsData(param->expr); @@ -436,7 +436,7 @@ public: } } catch (Event e) { execContentRaise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } try { @@ -456,7 +456,7 @@ public: } } catch (Event e) { execContentRaise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } if (send->content != NULL) { @@ -515,10 +515,10 @@ public: delayedSend((void*)ctx, sendid); } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentRaise(const scxml_ctx* ctx, const char* event) { + static int execContentRaise(const uscxml_ctx* ctx, const char* event) { Event* e = new Event(); e->name = event; @@ -528,10 +528,10 @@ public: e->eventType = Event::INTERNAL; } USER_DATA(ctx)->iq.push_back(e); - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentCancel(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr) { + static int execContentCancel(const uscxml_ctx* ctx, const char* sendid, const char* sendidexpr) { std::string eventId; if (sendid != NULL) { eventId = sendid; @@ -543,12 +543,12 @@ public: USER_DATA(ctx)->delayQueue.cancelEvent(eventId); } else { execContentRaise(ctx, "error.execution"); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentLog(const scxml_ctx* ctx, const char* label, const char* expr) { + static int execContentLog(const uscxml_ctx* ctx, const char* label, const char* expr) { try { if (label != NULL) { printf("%s%s", label, (expr != NULL ? ": " : "")); @@ -562,29 +562,29 @@ public: } } catch (Event e) { execContentRaise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentAssign(const scxml_ctx* ctx, const char* location, const char* expr) { + static int execContentAssign(const uscxml_ctx* ctx, const char* location, const char* expr) { std::string key = location; if (key == "_sessionid" || key == "_name" || key == "_ioprocessors" || key == "_invokers" || key == "_event") { execContentRaise(ctx, "error.execution"); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } try { - Data d(expr, Data::INTERPRETED); + Data d = USER_DATA(ctx)->dataModel.getStringAsData(expr); USER_DATA(ctx)->dataModel.assign(key, d); } catch (Event e) { execContentRaise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentForeachInit(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { + static int execContentForeachInit(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach) { try { scxml_foreach_info* feInfo = (scxml_foreach_info*)malloc(sizeof(scxml_foreach_info)); USER_DATA(ctx)->foreachInfo[foreach] = feInfo; @@ -593,12 +593,12 @@ public: feInfo->currIteration = 0; } catch (Event e) { execContentRaise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentForeachNext(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { + static int execContentForeachNext(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach) { try { scxml_foreach_info* feInfo = USER_DATA(ctx)->foreachInfo[foreach]; if (feInfo->currIteration < feInfo->iterations) { @@ -607,25 +607,25 @@ public: (foreach->index != NULL ? foreach->index : ""), feInfo->currIteration); feInfo->currIteration++; - return SCXML_ERR_OK; + return USCXML_ERR_OK; } } catch (Event e) { execContentRaise(ctx, e.name.c_str()); free(USER_DATA(ctx)->foreachInfo[foreach]); USER_DATA(ctx)->foreachInfo.erase(foreach); - return SCXML_ERR_EXEC_CONTENT; + return USCXML_ERR_EXEC_CONTENT; } - return SCXML_ERR_FOREACH_DONE; + return USCXML_ERR_FOREACH_DONE; } - static int execContentForeachDone(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { + static int execContentForeachDone(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach) { free(USER_DATA(ctx)->foreachInfo[foreach]); USER_DATA(ctx)->foreachInfo.erase(foreach); - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentInit(const scxml_ctx* ctx, const scxml_elem_data* data) { - while(ELEM_DATA_IS_SET(data)) { + static int execContentInit(const uscxml_ctx* ctx, const uscxml_elem_data* data) { + while(USCXML_ELEM_DATA_IS_SET(data)) { if (USER_DATA(ctx)->invokeData.find(data->id) != USER_DATA(ctx)->invokeData.end()) { // passed via param or namelist: test245 try { @@ -638,10 +638,12 @@ public: std::stringstream content; if (data->expr != NULL) { - d = Data(data->expr, Data::INTERPRETED); + d = USER_DATA(ctx)->dataModel.getStringAsData(data->expr); +// d = Data(data->expr, Data::INTERPRETED); } else if (data->content != NULL) { content << data->content; - d = Data(content.str(), Data::INTERPRETED); + d = USER_DATA(ctx)->dataModel.getStringAsData(content.str()); +// d = Data(content.str(), Data::INTERPRETED); } else if (data->src != NULL) { URL sourceURL(data->src); if (USER_DATA(ctx)->baseURL.size() > 0) { @@ -650,8 +652,8 @@ public: sourceURL.toAbsoluteCwd(); } content << sourceURL; - d = Data(content.str(), Data::INTERPRETED); - +// d = Data(content.str(), Data::INTERPRETED); + d = USER_DATA(ctx)->dataModel.getStringAsData(content.str()); } else { d = Data("undefined", Data::INTERPRETED); } @@ -673,19 +675,19 @@ public: } data++; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static int execContentScript(const scxml_ctx* ctx, const char* src, const char* content) { + static int execContentScript(const uscxml_ctx* ctx, const char* src, const char* content) { if (content != NULL) { USER_DATA(ctx)->dataModel.eval(Arabica::DOM::Element(), content); } else if (src != NULL) { - return SCXML_ERR_UNSUPPORTED; + return USCXML_ERR_UNSUPPORTED; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } - static void* dequeueExternal(const scxml_ctx* ctx) { + static void* dequeueExternal(const uscxml_ctx* ctx) { tthread::lock_guard lock(USER_DATA(ctx)->mutex); if (USER_DATA(ctx)->eq.size() == 0) return NULL; @@ -717,20 +719,20 @@ public: } } -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Popping External Event: %s\n", e->name.c_str()); #endif return e; } - static void* dequeueInternal(const scxml_ctx* ctx) { + static void* dequeueInternal(const uscxml_ctx* ctx) { if (USER_DATA(ctx)->iq.size() == 0) return NULL; Event* e = USER_DATA(ctx)->iq.front(); USER_DATA(ctx)->iq.pop_front(); USER_DATA(ctx)->currEvent = e; USER_DATA(ctx)->dataModel.setEvent(*e); -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Popping Internal Event: %s\n", e->name.c_str()); #endif return e; @@ -744,13 +746,13 @@ public: if (sr->target == "#_internal") { e->eventType = Event::INTERNAL; -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Pushing Internal Event: %s\n", e->name.c_str()); #endif USER_DATA(ctx)->iq.push_back(e); } else if (sr->target == "#_external") { e->eventType = Event::EXTERNAL; -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Pushing External Event: %s\n", e->name.c_str()); #endif USER_DATA(ctx)->eq.push_back(e); @@ -774,7 +776,7 @@ public: } if (!sessionFound) { // test496 - execContentRaise((scxml_ctx*)ctx, "error.communication"); + execContentRaise((uscxml_ctx*)ctx, "error.communication"); } } else if (sr->target.substr(0,2) == "#_") { e->eventType = Event::EXTERNAL; @@ -782,7 +784,7 @@ public: if (USER_DATA(ctx)->topMostMachine->allMachines.find(targetId) != USER_DATA(ctx)->topMostMachine->allMachines.end()) { USER_DATA(ctx)->topMostMachine->allMachines[targetId]->eq.push_back(e); } else { - execContentRaise((scxml_ctx*)ctx, "error.communication"); + execContentRaise((uscxml_ctx*)ctx, "error.communication"); } } else { assert(false); @@ -865,13 +867,13 @@ NEXT_DESC: Event* currEvent; - std::map invocationIds; + std::map invocationIds; std::map allMachines; bool isFinalized; int state; - scxml_ctx ctx; - const scxml_machine* machine; + uscxml_ctx ctx; + const uscxml_machine* machine; StateMachine* parentMachine; StateMachine* topMostMachine; @@ -883,7 +885,7 @@ NEXT_DESC: // in case we were invoked std::string invokeId; - const scxml_elem_invoke* invocation; + const uscxml_elem_invoke* invocation; std::map invokeData; std::deque iq; @@ -904,7 +906,7 @@ protected: DelayedEventQueue delayQueue; std::map sendIds; - std::map foreachInfo; + std::map foreachInfo; tthread::condition_variable monitor; tthread::mutex mutex; @@ -928,7 +930,7 @@ int main(int argc, char** argv) { double avgDm = 0; #endif - StateMachine rootMachine(&scxml_machines[0]); + StateMachine rootMachine(&uscxml_machines[0]); Timer tTotal; tTotal.start(); @@ -950,7 +952,7 @@ int main(int argc, char** argv) { } microSteps++; - assert(rootMachine.ctx.flags & SCXML_CTX_TOP_LEVEL_FINAL); + assert(rootMachine.ctx.flags & USCXML_CTX_TOP_LEVEL_FINAL); t.stop(); avg += t.elapsed; diff --git a/test/src/test-c-machine.machine.c b/test/src/test-c-machine.machine.c index cb9fcae..5ac3994 100644 --- a/test/src/test-c-machine.machine.c +++ b/test/src/test-c-machine.machine.c @@ -1,183 +1,285 @@ /** Generated from source: - file:///Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test237.scxml + file:///Users/sradomski/Documents/TK/Code/uscxml/test/w3c/lua/test150.scxml */ -#include // explicit types -#include // NULL +#include /* explicit types */ +#include /* NULL */ + +#ifndef USCXML_GEN_C_MACROS + +/** + * All macros used for the scxml types and functions + * + * ** IMPORTANT: Make sure to set the following macros prior to including. ** + * They are used to represent the machine in the types to follow + * and to allocate stack memory during a micro-step function. + * When in doubt, overprovide. + * + * USCXML_NR_STATES_TYPE + * as the smallest type for positive integers that can contain the + * largest number of states from an individual state machine. E.g.: + * < 2^8 states => uint8_t + * < 2^16 states => uint16_t + * < 2^32 states => uint32_t + */ + +#ifndef USCXML_NR_STATES_TYPE +# define USCXML_NR_STATES_TYPE uint8_t +#endif + +/** + * USCXML_NR_TRANS_TYPE + * the same as above but for the number of transitions. + */ + +#ifndef USCXML_NR_TRANS_TYPE +# define USCXML_NR_TRANS_TYPE uint8_t +#endif + +/** + * USCXML_MAX_NR_STATES_BYTES + * the smallest multiple of 8 that, if multiplied by 8, + * is larger than USCXML_NR_STATES_TYPE, e.g: + * 1-8 states => 1 + * 9-16 states => 2 + * 17-24 states => 3 + * 25-32 states => 4 + * ... + */ + +#ifndef USCXML_MAX_NR_STATES_BYTES +# define USCXML_MAX_NR_STATES_BYTES 1 +#endif + +/** + * USCXML_MAX_NR_TRANS_BYTES + * same as above but for transitions. + */ + +#ifndef USCXML_MAX_NR_TRANS_BYTES +# define USCXML_MAX_NR_TRANS_BYTES 1 +#endif + +/** + * USCXML_NUMBER_STATES / USCXML_NUMBER_TRANS + * Per default the number of states / transitions is retrieved from the machine + * info in the uscxml_ctx struct, but you can also hard-code it per macro. + */ + +#ifndef USCXML_NUMBER_STATES +# define USCXML_NUMBER_STATES (ctx->machine->nr_states) +#endif + +#ifndef USCXML_NUMBER_TRANS +# define USCXML_NUMBER_TRANS (ctx->machine->nr_transitions) +#endif + +/** + * USCXML_GET_STATE / USCXML_GET_TRANS + * Per default an individual state or transitions is retrieved from the machine + * info in the uscxml_ctx struct, but you can also hard-code it per macro. + */ + +#ifndef USCXML_GET_STATE +# define USCXML_GET_STATE(i) (ctx->machine->states[i]) +#endif + +#ifndef USCXML_GET_TRANS +# define USCXML_GET_TRANS(i) (ctx->machine->transitions[i]) +#endif + + +/* Common macros below */ #define BIT_HAS(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0) #define BIT_SET_AT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7)); #define BIT_CLEAR(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF; #ifdef __GNUC__ -#define likely(x) (__builtin_expect(!!(x), 1)) -#define unlikely(x) (__builtin_expect(!!(x), 0)) +# define likely(x) (__builtin_expect(!!(x), 1)) +# define unlikely(x) (__builtin_expect(!!(x), 0)) #else -#define likely(x) (x) -#define unlikely(x) (x) +# define likely(x) (x) +# define unlikely(x) (x) #endif -#ifndef SCXML_NR_STATES_TYPE -# define SCXML_NR_STATES_TYPE uint8_t -#endif +/* error return codes */ +#define USCXML_ERR_OK 0 +#define USCXML_ERR_IDLE 1 +#define USCXML_ERR_DONE 2 +#define USCXML_ERR_MISSING_CALLBACK 3 +#define USCXML_ERR_FOREACH_DONE 4 +#define USCXML_ERR_EXEC_CONTENT 5 +#define USCXML_ERR_INVALID_TARGET 6 +#define USCXML_ERR_INVALID_TYPE 7 +#define USCXML_ERR_UNSUPPORTED 8 + +#define USCXML_TRANS_SPONTANEOUS 0x01 +#define USCXML_TRANS_TARGETLESS 0x02 +#define USCXML_TRANS_INTERNAL 0x04 +#define USCXML_TRANS_HISTORY 0x08 +#define USCXML_TRANS_INITIAL 0x10 + +#define USCXML_STATE_ATOMIC 0x01 +#define USCXML_STATE_PARALLEL 0x02 +#define USCXML_STATE_COMPOUND 0x03 +#define USCXML_STATE_FINAL 0x04 +#define USCXML_STATE_HISTORY_DEEP 0x05 +#define USCXML_STATE_HISTORY_SHALLOW 0x06 +#define USCXML_STATE_INITIAL 0x07 +#define USCXML_STATE_HAS_HISTORY 0x80 /* highest bit */ +#define USCXML_STATE_MASK(t) (t & 0x7F) /* mask highest bit */ + +#define USCXML_CTX_PRISTINE 0x00 +#define USCXML_CTX_SPONTANEOUS 0x01 +#define USCXML_CTX_INITIALIZED 0x02 +#define USCXML_CTX_TOP_LEVEL_FINAL 0x04 +#define USCXML_CTX_TRANSITION_FOUND 0x08 +#define USCXML_CTX_FINISHED 0x10 + +#define USCXML_ELEM_DATA_IS_SET(data) (data->id != NULL) +#define USCXML_ELEM_DONEDATA_IS_SET(donedata) (donedata->content != NULL || donedata->contentexpr != NULL || donedata->params != NULL) +#define USCXML_ELEM_PARAM_IS_SET(param) (param->name != NULL) +#define USCXML_MACHINE_IS_SET(machine) (machine->nr_states > 0) + +#define USCXML_GEN_C_MACROS +#endif -#ifndef SCXML_NR_TRANS_TYPE -# define SCXML_NR_TRANS_TYPE uint8_t -#endif -#ifndef SCXML_MAX_NR_STATES_BYTES -# define SCXML_MAX_NR_STATES_BYTES 1 -#endif +#ifndef USCXML_GEN_C_TYPES -#ifndef SCXML_MAX_NR_TRANS_BYTES -# define SCXML_MAX_NR_TRANS_BYTES 1 -#endif +/** + * All types required to represent an SCXML state chart. + * Just predefine the USCXML_GEN_C_TYPES macro if you do not need them. + */ + +typedef struct uscxml_machine uscxml_machine; +typedef struct uscxml_transition uscxml_transition; +typedef struct uscxml_state uscxml_state; +typedef struct uscxml_ctx uscxml_ctx; +typedef struct uscxml_elem_invoke uscxml_elem_invoke; + +typedef struct uscxml_elem_send uscxml_elem_send; +typedef struct uscxml_elem_param uscxml_elem_param; +typedef struct uscxml_elem_data uscxml_elem_data; +typedef struct uscxml_elem_donedata uscxml_elem_donedata; +typedef struct uscxml_elem_foreach uscxml_elem_foreach; + +typedef void* (*dequeue_internal_t)(const uscxml_ctx* ctx); +typedef void* (*dequeue_external_t)(const uscxml_ctx* ctx); +typedef int (*is_enabled_t)(const uscxml_ctx* ctx, const uscxml_transition* transition, const void* event); +typedef int (*is_true_t)(const uscxml_ctx* ctx, const char* expr); +typedef int (*exec_content_t)(const uscxml_ctx* ctx, const uscxml_state* state, const void* event); +typedef int (*raise_done_event_t)(const uscxml_ctx* ctx, const uscxml_state* state, const uscxml_elem_donedata* donedata); +typedef int (*invoke_t)(const uscxml_ctx* ctx, const uscxml_state* s, const uscxml_elem_invoke* invocation, unsigned char uninvoke); + +typedef int (*exec_content_log_t)(const uscxml_ctx* ctx, const char* label, const char* expr); +typedef int (*exec_content_raise_t)(const uscxml_ctx* ctx, const char* event); +typedef int (*exec_content_send_t)(const uscxml_ctx* ctx, const uscxml_elem_send* send); +typedef int (*exec_content_foreach_init_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach); +typedef int (*exec_content_foreach_next_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach); +typedef int (*exec_content_foreach_done_t)(const uscxml_ctx* ctx, const uscxml_elem_foreach* foreach); +typedef int (*exec_content_assign_t)(const uscxml_ctx* ctx, const char* location, const char* expr); +typedef int (*exec_content_init_t)(const uscxml_ctx* ctx, const uscxml_elem_data* data); +typedef int (*exec_content_cancel_t)(const uscxml_ctx* ctx, const char* sendid, const char* sendidexpr); +typedef int (*exec_content_finalize_t)(const uscxml_ctx* ctx, const uscxml_elem_invoke* invoker, const void* event); +typedef int (*exec_content_script_t)(const uscxml_ctx* ctx, const char* src, const char* content); -// error return codes -#define SCXML_ERR_OK 0 -#define SCXML_ERR_IDLE 1 -#define SCXML_ERR_DONE 2 -#define SCXML_ERR_MISSING_CALLBACK 3 -#define SCXML_ERR_FOREACH_DONE 4 -#define SCXML_ERR_EXEC_CONTENT 5 -#define SCXML_ERR_INVALID_TARGET 6 -#define SCXML_ERR_INVALID_TYPE 7 -#define SCXML_ERR_UNSUPPORTED 8 - -#define SCXML_NUMBER_STATES (ctx->machine->nr_states) -#define SCXML_NUMBER_TRANS (ctx->machine->nr_transitions) - -#define SCXML_TRANS_SPONTANEOUS 0x01 -#define SCXML_TRANS_TARGETLESS 0x02 -#define SCXML_TRANS_INTERNAL 0x04 -#define SCXML_TRANS_HISTORY 0x08 -#define SCXML_TRANS_INITIAL 0x10 - -#define SCXML_STATE_ATOMIC 0x01 -#define SCXML_STATE_PARALLEL 0x02 -#define SCXML_STATE_COMPOUND 0x03 -#define SCXML_STATE_FINAL 0x04 -#define SCXML_STATE_HISTORY_DEEP 0x05 -#define SCXML_STATE_HISTORY_SHALLOW 0x06 -#define SCXML_STATE_INITIAL 0x07 -#define SCXML_STATE_HAS_HISTORY 0x80 // highest bit -#define SCXML_STATE_MASK(t) (t & 0x7F) // mask highest bit - -#define SCXML_CTX_PRISTINE 0x00 -#define SCXML_CTX_SPONTANEOUS 0x01 -#define SCXML_CTX_INITIALIZED 0x02 -#define SCXML_CTX_TOP_LEVEL_FINAL 0x04 -#define SCXML_CTX_TRANSITION_FOUND 0x08 -#define SCXML_CTX_FINISHED 0x10 - -#define ELEM_DATA_IS_SET(data) (data->id != NULL) -#define ELEM_DONEDATA_IS_SET(donedata) (donedata->content != NULL || donedata->contentexpr != NULL || donedata->params != NULL) -#define ELEM_PARAM_IS_SET(param) (param->name != NULL) -#define SCXML_MACHINE_IS_SET(machine) (machine->nr_states > 0) - - -typedef struct scxml_machine scxml_machine; -typedef struct scxml_transition scxml_transition; -typedef struct scxml_state scxml_state; -typedef struct scxml_ctx scxml_ctx; -typedef struct scxml_elem_invoke scxml_elem_invoke; - -typedef struct scxml_elem_send scxml_elem_send; -typedef struct scxml_elem_param scxml_elem_param; -typedef struct scxml_elem_data scxml_elem_data; -typedef struct scxml_elem_donedata scxml_elem_donedata; -typedef struct scxml_elem_foreach scxml_elem_foreach; - -typedef void* (*dequeue_internal_t)(const scxml_ctx* ctx); -typedef void* (*dequeue_external_t)(const scxml_ctx* ctx); -typedef int (*is_enabled_t)(const scxml_ctx* ctx, const scxml_transition* transition, const void* event); -typedef int (*is_true_t)(const scxml_ctx* ctx, const char* expr); -typedef int (*exec_content_t)(const scxml_ctx* ctx, const scxml_state* state, const void* event); -typedef int (*raise_done_event_t)(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata); -typedef int (*invoke_t)(const scxml_ctx* ctx, const scxml_state* s, const scxml_elem_invoke* invocation, uint8_t uninvoke); - -typedef int (*exec_content_log_t)(const scxml_ctx* ctx, const char* label, const char* expr); -typedef int (*exec_content_raise_t)(const scxml_ctx* ctx, const char* event); -typedef int (*exec_content_send_t)(const scxml_ctx* ctx, const scxml_elem_send* send); -typedef int (*exec_content_foreach_init_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach); -typedef int (*exec_content_foreach_next_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach); -typedef int (*exec_content_foreach_done_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach); -typedef int (*exec_content_assign_t)(const scxml_ctx* ctx, const char* location, const char* expr); -typedef int (*exec_content_init_t)(const scxml_ctx* ctx, const scxml_elem_data* data); -typedef int (*exec_content_cancel_t)(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr); -typedef int (*exec_content_finalize_t)(const scxml_ctx* ctx, const scxml_elem_invoke* invoker, const void* event); -typedef int (*exec_content_script_t)(const scxml_ctx* ctx, const char* src, const char* content); - -struct scxml_machine { - uint8_t flags; - SCXML_NR_STATES_TYPE nr_states; - SCXML_NR_TRANS_TYPE nr_transitions; - const char* name; - const char* datamodel; - const char* uuid; - const scxml_state* states; - const scxml_transition* transitions; - const scxml_machine* parent; - const scxml_elem_donedata* donedata; - const exec_content_t script; +/** + * A single SCXML state-machine. + */ +struct uscxml_machine { + unsigned char flags; /* Unused */ + USCXML_NR_STATES_TYPE nr_states; /* Make sure to set type per macro! */ + USCXML_NR_TRANS_TYPE nr_transitions; /* Make sure to set type per macro! */ + const char* name; + const char* datamodel; + const char* uuid; /* currently MD5 sum */ + const uscxml_state* states; + const uscxml_transition* transitions; + const uscxml_machine* parent; + const uscxml_elem_donedata* donedata; + const exec_content_t script; /* Global script elements */ }; -// forward declare machines to allow references -extern const scxml_machine scxml_machines[3]; - -struct scxml_elem_data { +/** + * All information pertaining to a element. + * With late data binding, blocks of data elements are separated by NULL + * use USCXML_ELEM_DATA_IS_SET to test for end of a block. + */ +struct uscxml_elem_data { const char* id; const char* src; const char* expr; const char* content; }; -struct scxml_state { - const char* name; // eventual name - const uint8_t parent; // parent - const exec_content_t on_entry; // on entry handlers - const exec_content_t on_exit; // on exit handlers - const invoke_t invoke; // invocations - const char children[SCXML_MAX_NR_STATES_BYTES]; // all children - const char completion[SCXML_MAX_NR_STATES_BYTES]; // default completion - const char ancestors[SCXML_MAX_NR_STATES_BYTES]; // all ancestors - const scxml_elem_data* data; - const uint8_t type; // atomic, parallel, compound, final, history +/** + * All information pertaining to any state element. + */ +struct uscxml_state { + const char* name; /* eventual name */ + const USCXML_NR_STATES_TYPE parent; /* parent */ + const exec_content_t on_entry; /* on entry handlers */ + const exec_content_t on_exit; /* on exit handlers */ + const invoke_t invoke; /* invocations */ + const char children[USCXML_MAX_NR_STATES_BYTES]; /* all children */ + const char completion[USCXML_MAX_NR_STATES_BYTES]; /* default completion */ + const char ancestors[USCXML_MAX_NR_STATES_BYTES]; /* all ancestors */ + const uscxml_elem_data* data; /* data with late binding */ + const unsigned char type; /* One of USCXML_STATE_* */ }; -struct scxml_transition { - const uint8_t source; - const char target[SCXML_MAX_NR_STATES_BYTES]; +/** + * All information pertaining to a element. + */ +struct uscxml_transition { + const USCXML_NR_STATES_TYPE source; + const char target[USCXML_MAX_NR_STATES_BYTES]; const char* event; const char* condition; const exec_content_t on_transition; - const uint8_t type; - const char conflicts[SCXML_MAX_NR_TRANS_BYTES]; - const char exit_set[SCXML_MAX_NR_STATES_BYTES]; + const unsigned char type; + const char conflicts[USCXML_MAX_NR_TRANS_BYTES]; + const char exit_set[USCXML_MAX_NR_STATES_BYTES]; }; -struct scxml_elem_foreach { +/** + * All information pertaining to a element. + */ +struct uscxml_elem_foreach { const char* array; const char* item; const char* index; }; -struct scxml_elem_param { +/** + * All information pertaining to a element. + * Blocks of params are separated by NULL params, use + * USCXML_ELEM_PARAM_IS_SET to test for end of a block. + */ +struct uscxml_elem_param { const char* name; const char* expr; const char* location; }; -struct scxml_elem_donedata { - const uint8_t source; +/** + * All information pertaining to a element. + */ +struct uscxml_elem_donedata { + const USCXML_NR_STATES_TYPE source; const char* content; const char* contentexpr; - const scxml_elem_param* params; + const uscxml_elem_param* params; }; -struct scxml_elem_invoke { - const scxml_machine* machine; +/** + * All information pertaining to an element. + */ +struct uscxml_elem_invoke { + const uscxml_machine* machine; const char* type; const char* typeexpr; const char* src; @@ -186,14 +288,17 @@ struct scxml_elem_invoke { const char* idlocation; const char* sourcename; const char* namelist; - const uint8_t autoforward; - const scxml_elem_param* params; + const unsigned char autoforward; + const uscxml_elem_param* params; exec_content_finalize_t finalize; const char* content; const char* contentexpr; }; -struct scxml_elem_send { +/** + * All information pertaining to a element. + */ +struct uscxml_elem_send { const char* event; const char* eventexpr; const char* target; @@ -204,405 +309,310 @@ struct scxml_elem_send { const char* idlocation; const char* delay; const char* delayexpr; - const char* namelist; + const char* namelist; /* not space-separated, still as in attribute value */ const char* content; const char* contentexpr; - const scxml_elem_param* params; + const uscxml_elem_param* params; }; -struct scxml_ctx { - uint8_t flags; - const scxml_machine* machine; +/** + * Represents an instance of a state-chart at runtime/ + */ +struct uscxml_ctx { + unsigned char flags; + const uscxml_machine* machine; - char config[SCXML_MAX_NR_STATES_BYTES]; - char history[SCXML_MAX_NR_STATES_BYTES]; - char invocations[SCXML_MAX_NR_STATES_BYTES]; - char initialized_data[SCXML_MAX_NR_STATES_BYTES]; + char config[USCXML_MAX_NR_STATES_BYTES]; /* Make sure these macros specify a sufficient size */ + char history[USCXML_MAX_NR_STATES_BYTES]; + char invocations[USCXML_MAX_NR_STATES_BYTES]; + char initialized_data[USCXML_MAX_NR_STATES_BYTES]; void* user_data; void* event; dequeue_internal_t dequeue_internal; dequeue_external_t dequeue_external; - is_enabled_t is_enabled; - is_true_t is_true; + is_enabled_t is_enabled; + is_true_t is_true; raise_done_event_t raise_done_event; - exec_content_log_t exec_content_log; - exec_content_raise_t exec_content_raise; - exec_content_send_t exec_content_send; + exec_content_log_t exec_content_log; + exec_content_raise_t exec_content_raise; + exec_content_send_t exec_content_send; exec_content_foreach_init_t exec_content_foreach_init; exec_content_foreach_next_t exec_content_foreach_next; exec_content_foreach_done_t exec_content_foreach_done; - exec_content_assign_t exec_content_assign; - exec_content_init_t exec_content_init; - exec_content_cancel_t exec_content_cancel; - exec_content_script_t exec_content_script; + exec_content_assign_t exec_content_assign; + exec_content_init_t exec_content_init; + exec_content_cancel_t exec_content_cancel; + exec_content_script_t exec_content_script; + invoke_t invoke; }; -static const scxml_elem_send _scxml_290B2E91_elem_sends[2] = { - { - /* event */ "timeout1", - /* eventexpr */ NULL, - /* target */ NULL, - /* targetexpr */ NULL, - /* type */ NULL, - /* typeexpr */ NULL, - /* id */ NULL, - /* idlocation */ NULL, - /* delay */ NULL, - /* delayexpr */ "'1s'", - /* namelist */ NULL, - /* content */ NULL, - /* contentexpr */ NULL, - /* params */ NULL - }, - { - /* event */ "timeout2", - /* eventexpr */ NULL, - /* target */ NULL, - /* targetexpr */ NULL, - /* type */ NULL, - /* typeexpr */ NULL, - /* id */ NULL, - /* idlocation */ NULL, - /* delay */ NULL, - /* delayexpr */ "'1.5s'", - /* namelist */ NULL, - /* content */ NULL, - /* contentexpr */ NULL, - /* params */ NULL - } +#define USCXML_GEN_C_TYPES +#endif + +/* forward declare machines to allow references */ +extern const uscxml_machine uscxml_machines[2]; + +static const uscxml_elem_foreach _uscxml_9FEEFF45_elem_foreachs[2] = { + /* array, item, index */ + { "testvar3", "testvar1", "testvar2" }, + { "testvar3", "testvar4", "testvar5" } +}; + +static const uscxml_elem_data _uscxml_9FEEFF45_elem_datas[4] = { + /* id, src, expr, content */ + { "testvar1", NULL, NULL, NULL }, + { "testvar2", NULL, NULL, NULL }, + { "testvar3", NULL, NULL, "{1,2,3}" }, + { NULL, NULL, NULL, NULL } }; -static const scxml_elem_donedata _scxml_290B2E91_elem_donedatas[1] = { +static const uscxml_elem_donedata _uscxml_9FEEFF45_elem_donedatas[1] = { /* source, content, contentexpr, params */ { 0, NULL, NULL, NULL } }; -static const scxml_elem_invoke _scxml_290B2E91_elem_invokes[1] = { - { - /* machine */ &scxml_machines[1], - /* type */ "http://www.w3.org/TR/scxml/", - /* typeexpr */ NULL, - /* src */ NULL, - /* srcexpr */ NULL, - /* id */ "6be2e509-b4f4-4179-8cba-1e8701b5d7a8", - /* idlocation */ NULL, - /* sourcename */ "s0", - /* namelist */ NULL, - /* autoforward */ 0, - /* params */ NULL, - /* finalize */ NULL, - /* content */ NULL, - /* contentexpr */ NULL, - } -}; +static int _uscxml_9FEEFF45_s0_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + int err = USCXML_ERR_OK; + if likely(ctx->exec_content_foreach_init != NULL && + ctx->exec_content_foreach_next != NULL && + ctx->exec_content_foreach_done != NULL) { -static int _scxml_290B2E91_s0_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - int err = SCXML_ERR_OK; - if likely(ctx->exec_content_send != NULL) { - if ((ctx->exec_content_send(ctx, &_scxml_290B2E91_elem_sends[0])) != SCXML_ERR_OK) return err; + if unlikely((ctx->exec_content_foreach_init(ctx, &_uscxml_9FEEFF45_elem_foreachs[0])) != USCXML_ERR_OK) return err; + while (ctx->exec_content_foreach_next(ctx, &_uscxml_9FEEFF45_elem_foreachs[0]) == USCXML_ERR_OK) { + } + if ((ctx->exec_content_foreach_done(ctx, &_uscxml_9FEEFF45_elem_foreachs[0])) != USCXML_ERR_OK) return err; } else { - return SCXML_ERR_MISSING_CALLBACK; + return USCXML_ERR_MISSING_CALLBACK; } - return SCXML_ERR_OK; -} - -static int _scxml_290B2E91_s0_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - _scxml_290B2E91_s0_on_entry_0(ctx, state, event); - return SCXML_ERR_OK; -} - -static int _scxml_290B2E91_s0_invoke(const scxml_ctx* ctx, const scxml_state* s, const scxml_elem_invoke* invocation, uint8_t uninvoke) { - ctx->invoke(ctx, s, &_scxml_290B2E91_elem_invokes[0], uninvoke); - - return SCXML_ERR_OK; -} -static int _scxml_290B2E91_s1_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - int err = SCXML_ERR_OK; - if likely(ctx->exec_content_send != NULL) { - if ((ctx->exec_content_send(ctx, &_scxml_290B2E91_elem_sends[1])) != SCXML_ERR_OK) return err; + if likely(ctx->exec_content_raise != NULL) { + if unlikely((ctx->exec_content_raise(ctx, "foo")) != USCXML_ERR_OK) return err; } else { - return SCXML_ERR_MISSING_CALLBACK; + return USCXML_ERR_MISSING_CALLBACK; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } -static int _scxml_290B2E91_s1_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - _scxml_290B2E91_s1_on_entry_0(ctx, state, event); - return SCXML_ERR_OK; +static int _uscxml_9FEEFF45_s0_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_9FEEFF45_s0_on_entry_0(ctx, state, event); + return USCXML_ERR_OK; } -static int _scxml_290B2E91_pass_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - int err = SCXML_ERR_OK; - if likely(ctx->exec_content_log != NULL) { - if unlikely((ctx->exec_content_log(ctx, "Outcome", "'pass'")) != SCXML_ERR_OK) return err; +static int _uscxml_9FEEFF45_s1_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + int err = USCXML_ERR_OK; + if likely(ctx->exec_content_foreach_init != NULL && + ctx->exec_content_foreach_next != NULL && + ctx->exec_content_foreach_done != NULL) { + + if unlikely((ctx->exec_content_foreach_init(ctx, &_uscxml_9FEEFF45_elem_foreachs[1])) != USCXML_ERR_OK) return err; + while (ctx->exec_content_foreach_next(ctx, &_uscxml_9FEEFF45_elem_foreachs[1]) == USCXML_ERR_OK) { + } + if ((ctx->exec_content_foreach_done(ctx, &_uscxml_9FEEFF45_elem_foreachs[1])) != USCXML_ERR_OK) return err; } else { - return SCXML_ERR_MISSING_CALLBACK; + return USCXML_ERR_MISSING_CALLBACK; } - return SCXML_ERR_OK; -} - -static int _scxml_290B2E91_pass_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - _scxml_290B2E91_pass_on_entry_0(ctx, state, event); - return SCXML_ERR_OK; -} - -static int _scxml_290B2E91_fail_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - int err = SCXML_ERR_OK; - if likely(ctx->exec_content_log != NULL) { - if unlikely((ctx->exec_content_log(ctx, "Outcome", "'fail'")) != SCXML_ERR_OK) return err; + if likely(ctx->exec_content_raise != NULL) { + if unlikely((ctx->exec_content_raise(ctx, "bar")) != USCXML_ERR_OK) return err; } else { - return SCXML_ERR_MISSING_CALLBACK; + return USCXML_ERR_MISSING_CALLBACK; } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } -static int _scxml_290B2E91_fail_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - _scxml_290B2E91_fail_on_entry_0(ctx, state, event); - return SCXML_ERR_OK; +static int _uscxml_9FEEFF45_s1_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_9FEEFF45_s1_on_entry_0(ctx, state, event); + return USCXML_ERR_OK; } -static const scxml_state _scxml_290B2E91_states[5] = { +static const uscxml_state _uscxml_9FEEFF45_states[6] = { { /* state number 0 */ /* name */ NULL, /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x1e /* 01111 */ }, - /* completion */ { 0x02 /* 01000 */ }, - /* ancestors */ { 0x00 /* 00000 */ }, - /* data */ NULL, - /* type */ SCXML_STATE_COMPOUND, + /* children */ { 0x3e /* 011111 */ }, + /* completion */ { 0x02 /* 010000 */ }, + /* ancestors */ { 0x00 /* 000000 */ }, + /* data */ &_uscxml_9FEEFF45_elem_datas[0], + /* type */ USCXML_STATE_COMPOUND, }, { /* state number 1 */ /* name */ "s0", /* parent */ 0, - /* onentry */ _scxml_290B2E91_s0_on_entry, + /* onentry */ _uscxml_9FEEFF45_s0_on_entry, /* onexit */ NULL, - /* invoke */ _scxml_290B2E91_s0_invoke, - /* children */ { 0x00 /* 00000 */ }, - /* completion */ { 0x00 /* 00000 */ }, - /* ancestors */ { 0x01 /* 10000 */ }, + /* invoke */ NULL, + /* children */ { 0x00 /* 000000 */ }, + /* completion */ { 0x00 /* 000000 */ }, + /* ancestors */ { 0x01 /* 100000 */ }, /* data */ NULL, - /* type */ SCXML_STATE_ATOMIC, + /* type */ USCXML_STATE_ATOMIC, }, { /* state number 2 */ /* name */ "s1", /* parent */ 0, - /* onentry */ _scxml_290B2E91_s1_on_entry, + /* onentry */ _uscxml_9FEEFF45_s1_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 00000 */ }, - /* completion */ { 0x00 /* 00000 */ }, - /* ancestors */ { 0x01 /* 10000 */ }, + /* children */ { 0x00 /* 000000 */ }, + /* completion */ { 0x00 /* 000000 */ }, + /* ancestors */ { 0x01 /* 100000 */ }, /* data */ NULL, - /* type */ SCXML_STATE_ATOMIC, + /* type */ USCXML_STATE_ATOMIC, }, { /* state number 3 */ - /* name */ "pass", + /* name */ "s2", /* parent */ 0, - /* onentry */ _scxml_290B2E91_pass_on_entry, + /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 00000 */ }, - /* completion */ { 0x00 /* 00000 */ }, - /* ancestors */ { 0x01 /* 10000 */ }, + /* children */ { 0x00 /* 000000 */ }, + /* completion */ { 0x00 /* 000000 */ }, + /* ancestors */ { 0x01 /* 100000 */ }, /* data */ NULL, - /* type */ SCXML_STATE_FINAL, + /* type */ USCXML_STATE_ATOMIC, }, { /* state number 4 */ + /* name */ "pass", + /* parent */ 0, + /* onentry */ NULL, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00 /* 000000 */ }, + /* completion */ { 0x00 /* 000000 */ }, + /* ancestors */ { 0x01 /* 100000 */ }, + /* data */ NULL, + /* type */ USCXML_STATE_FINAL, + }, + { /* state number 5 */ /* name */ "fail", /* parent */ 0, - /* onentry */ _scxml_290B2E91_fail_on_entry, + /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00 /* 00000 */ }, - /* completion */ { 0x00 /* 00000 */ }, - /* ancestors */ { 0x01 /* 10000 */ }, + /* children */ { 0x00 /* 000000 */ }, + /* completion */ { 0x00 /* 000000 */ }, + /* ancestors */ { 0x01 /* 100000 */ }, /* data */ NULL, - /* type */ SCXML_STATE_FINAL, + /* type */ USCXML_STATE_FINAL, } }; -static const scxml_transition _scxml_290B2E91_transitions[3] = { +static const uscxml_transition _uscxml_9FEEFF45_transitions[6] = { { /* transition number 0 with priority 0 - target: s1 + target: fail */ /* source */ 1, - /* target */ { 0x04 /* 00100 */ }, - /* event */ "timeout1", + /* target */ { 0x20 /* 000001 */ }, + /* event */ "error", /* condition */ NULL, /* ontrans */ NULL, /* type */ 0, - /* conflicts */ { 0x07 /* 111 */ }, - /* exit set */ { 0x1e /* 01111 */ } + /* conflicts */ { 0x3f /* 111111 */ }, + /* exit set */ { 0x3e /* 011111 */ } }, { /* transition number 1 with priority 1 + target: s1 + */ + /* source */ 1, + /* target */ { 0x04 /* 001000 */ }, + /* event */ "*", + /* condition */ NULL, + /* ontrans */ NULL, + /* type */ 0, + /* conflicts */ { 0x3f /* 111111 */ }, + /* exit set */ { 0x3e /* 011111 */ } + }, + { /* transition number 2 with priority 2 target: fail */ /* source */ 2, - /* target */ { 0x10 /* 00001 */ }, - /* event */ "done.invoke", + /* target */ { 0x20 /* 000001 */ }, + /* event */ "error", /* condition */ NULL, /* ontrans */ NULL, /* type */ 0, - /* conflicts */ { 0x07 /* 111 */ }, - /* exit set */ { 0x1e /* 01111 */ } + /* conflicts */ { 0x3f /* 111111 */ }, + /* exit set */ { 0x3e /* 011111 */ } }, - { /* transition number 2 with priority 2 - target: pass + { /* transition number 3 with priority 3 + target: s2 */ /* source */ 2, - /* target */ { 0x08 /* 00010 */ }, + /* target */ { 0x08 /* 000100 */ }, /* event */ "*", /* condition */ NULL, /* ontrans */ NULL, /* type */ 0, - /* conflicts */ { 0x07 /* 111 */ }, - /* exit set */ { 0x1e /* 01111 */ } - } -}; - -static const scxml_elem_send _scxml_740A1EEF_elem_sends[1] = { - { - /* event */ "timeout", - /* eventexpr */ NULL, - /* target */ NULL, - /* targetexpr */ NULL, - /* type */ NULL, - /* typeexpr */ NULL, - /* id */ NULL, - /* idlocation */ NULL, - /* delay */ NULL, - /* delayexpr */ "'2s'", - /* namelist */ NULL, - /* content */ NULL, - /* contentexpr */ NULL, - /* params */ NULL - } -}; - -static const scxml_elem_donedata _scxml_740A1EEF_elem_donedatas[1] = { - /* source, content, contentexpr, params */ - { 0, NULL, NULL, NULL } -}; - -static int _scxml_740A1EEF_sub0_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - int err = SCXML_ERR_OK; - if likely(ctx->exec_content_send != NULL) { - if ((ctx->exec_content_send(ctx, &_scxml_740A1EEF_elem_sends[0])) != SCXML_ERR_OK) return err; - } else { - return SCXML_ERR_MISSING_CALLBACK; - } - return SCXML_ERR_OK; -} - -static int _scxml_740A1EEF_sub0_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - _scxml_740A1EEF_sub0_on_entry_0(ctx, state, event); - return SCXML_ERR_OK; -} - -static const scxml_state _scxml_740A1EEF_states[3] = { - { /* state number 0 */ - /* name */ NULL, - /* parent */ 0, - /* onentry */ NULL, - /* onexit */ NULL, - /* invoke */ NULL, - /* children */ { 0x06 /* 011 */ }, - /* completion */ { 0x02 /* 010 */ }, - /* ancestors */ { 0x00 /* 000 */ }, - /* data */ NULL, - /* type */ SCXML_STATE_COMPOUND, + /* conflicts */ { 0x3f /* 111111 */ }, + /* exit set */ { 0x3e /* 011111 */ } }, - { /* state number 1 */ - /* name */ "sub0", - /* parent */ 0, - /* onentry */ _scxml_740A1EEF_sub0_on_entry, - /* onexit */ NULL, - /* invoke */ NULL, - /* children */ { 0x00 /* 000 */ }, - /* completion */ { 0x00 /* 000 */ }, - /* ancestors */ { 0x01 /* 100 */ }, - /* data */ NULL, - /* type */ SCXML_STATE_ATOMIC, + { /* transition number 4 with priority 4 + target: pass + */ + /* source */ 3, + /* target */ { 0x10 /* 000010 */ }, + /* event */ NULL, + /* condition */ "testvar4 ~= nil", + /* ontrans */ NULL, + /* type */ USCXML_TRANS_SPONTANEOUS, + /* conflicts */ { 0x3f /* 111111 */ }, + /* exit set */ { 0x3e /* 011111 */ } }, - { /* state number 2 */ - /* name */ "subFinal", - /* parent */ 0, - /* onentry */ NULL, - /* onexit */ NULL, - /* invoke */ NULL, - /* children */ { 0x00 /* 000 */ }, - /* completion */ { 0x00 /* 000 */ }, - /* ancestors */ { 0x01 /* 100 */ }, - /* data */ NULL, - /* type */ SCXML_STATE_FINAL, - } -}; - -static const scxml_transition _scxml_740A1EEF_transitions[1] = { - { /* transition number 0 with priority 0 - target: subFinal + { /* transition number 5 with priority 5 + target: fail */ - /* source */ 1, - /* target */ { 0x04 /* 001 */ }, - /* event */ "timeout", + /* source */ 3, + /* target */ { 0x20 /* 000001 */ }, + /* event */ NULL, /* condition */ NULL, /* ontrans */ NULL, - /* type */ 0, - /* conflicts */ { 0x01 /* 1 */ }, - /* exit set */ { 0x06 /* 011 */ } + /* type */ USCXML_TRANS_SPONTANEOUS, + /* conflicts */ { 0x3f /* 111111 */ }, + /* exit set */ { 0x3e /* 011111 */ } } }; -const scxml_machine scxml_machines[3] = { +const uscxml_machine uscxml_machines[2] = { { /* flags */ 0, - /* nr_states */ 5, - /* nr_transitions */ 3, + /* nr_states */ 6, + /* nr_transitions */ 6, /* name */ "", - /* datamodel */ "ecmascript", - /* uuid */ "290B2E91E83BC4AC61271D1C9891410E", - /* states */ &_scxml_290B2E91_states[0], - /* transitions */ &_scxml_290B2E91_transitions[0], + /* datamodel */ "lua", + /* uuid */ "9FEEFF45D10C557438897A21612B7382", + /* states */ &_uscxml_9FEEFF45_states[0], + /* transitions */ &_uscxml_9FEEFF45_transitions[0], /* parent */ NULL, - /* donedata */ &_scxml_290B2E91_elem_donedatas[0], - /* script */ NULL - }, - { - /* flags */ 0, - /* nr_states */ 3, - /* nr_transitions */ 1, - /* name */ "", - /* datamodel */ "ecmascript", - /* uuid */ "740A1EEF39B05367B78DF059D2C8F917", - /* states */ &_scxml_740A1EEF_states[0], - /* transitions */ &_scxml_740A1EEF_transitions[0], - /* parent */ &scxml_machines[0], - /* donedata */ &_scxml_740A1EEF_elem_donedatas[0], + /* donedata */ &_uscxml_9FEEFF45_elem_donedatas[0], /* script */ NULL }, {0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; -#ifdef SCXML_VERBOSE -static void printStateNames(const scxml_ctx* ctx, const char* a, size_t length) { +#ifdef USCXML_VERBOSE +/** + * Print name of states contained in a (debugging). + */ +static void printStateNames(const uscxml_ctx* ctx, const char* a, size_t length) { size_t i; const char* seperator = ""; for (i = 0; i < length; i++) { if (BIT_HAS(i, a)) { - printf("%s%s", seperator, (ctx->machine->states[i].name != NULL ? ctx->machine->states[i].name : "UNK")); + printf("%s%s", seperator, (USCXML_GET_STATE(i).name != NULL ? USCXML_GET_STATE(i).name : "UNK")); seperator = ", "; } } printf("\n"); } +/** + * Print bits set in a in a binary representation (debugging). + */ static void printBitsetIndices(const char* a, size_t length) { size_t i; const char* seperator = ""; @@ -616,6 +626,10 @@ static void printBitsetIndices(const char* a, size_t length) { } #endif +#ifndef USCXML_BIT_OPERATIONS +/** + * Return true if there is a common bit in a and b. + */ static int bit_has_and(const char* a, const char* b, size_t i) { while(i--) { if (a[i] & b[i]) @@ -624,12 +638,19 @@ static int bit_has_and(const char* a, const char* b, size_t i) { return 0; } +/** + * Set all bits to 0, this corresponds to memset(a, 0, i), + * but does not require string.h or cstring. + */ static void bit_clear_all(char* a, size_t i) { while(i--) { a[i] = 0; } } +/** + * Return true if there is any bit set in a. + */ static int bit_has_any(const char* a, size_t i) { while(i--) { if (a[i] > 0) @@ -638,83 +659,100 @@ static int bit_has_any(const char* a, size_t i) { return 0; } +/** + * Set all bits from given mask in dest, this is |= for bit arrays. + */ static void bit_or(char* dest, const char* mask, size_t i) { while(i--) { dest[i] |= mask[i]; } } +/** + * Copy all bits from source to dest, this corresponds to memcpy(a, b, i), + * but does not require string.h or cstring. + */ static void bit_copy(char* dest, const char* source, size_t i) { while(i--) { dest[i] = source[i]; } } +/** + * Unset bits from mask in dest. + */ static void bit_and_not(char* dest, const char* mask, size_t i) { while(i--) { dest[i] &= ~mask[i]; } } +/** + * Set bits from mask in dest. + */ static void bit_and(char* dest, const char* mask, size_t i) { while(i--) { dest[i] &= mask[i]; }; } -int scxml_step(scxml_ctx* ctx) { - - SCXML_NR_STATES_TYPE i, j, k; - SCXML_NR_STATES_TYPE nr_states_bytes = ((SCXML_NUMBER_STATES + 7) & ~7) >> 3; - SCXML_NR_TRANS_TYPE nr_trans_bytes = ((SCXML_NUMBER_TRANS + 7) & ~7) >> 3; - int err = SCXML_ERR_OK; - char conflicts [SCXML_MAX_NR_TRANS_BYTES]; - char trans_set [SCXML_MAX_NR_TRANS_BYTES]; - char target_set [SCXML_MAX_NR_STATES_BYTES]; - char exit_set [SCXML_MAX_NR_STATES_BYTES]; - char entry_set [SCXML_MAX_NR_STATES_BYTES]; - char tmp_states [SCXML_MAX_NR_STATES_BYTES]; +#define USCXML_BIT_OPERATIONS +#endif -#ifdef SCXML_VERBOSE +#ifndef USCXML_STEP_FUNCTION +int uscxml_step(uscxml_ctx* ctx) { + + USCXML_NR_TRANS_TYPE i, j, k; + USCXML_NR_STATES_TYPE nr_states_bytes = ((USCXML_NUMBER_STATES + 7) & ~7) >> 3; + USCXML_NR_TRANS_TYPE nr_trans_bytes = ((USCXML_NUMBER_TRANS + 7) & ~7) >> 3; + int err = USCXML_ERR_OK; + char conflicts [USCXML_MAX_NR_TRANS_BYTES]; + char trans_set [USCXML_MAX_NR_TRANS_BYTES]; + char target_set [USCXML_MAX_NR_STATES_BYTES]; + char exit_set [USCXML_MAX_NR_STATES_BYTES]; + char entry_set [USCXML_MAX_NR_STATES_BYTES]; + char tmp_states [USCXML_MAX_NR_STATES_BYTES]; + +#ifdef USCXML_VERBOSE printf("Config: "); - printStateNames(ctx, ctx->config, SCXML_NUMBER_STATES); + printStateNames(ctx, ctx->config, USCXML_NUMBER_STATES); #endif - if (ctx->flags & SCXML_CTX_FINISHED) - return SCXML_ERR_DONE; + if (ctx->flags & USCXML_CTX_FINISHED) + return USCXML_ERR_DONE; - if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL) { - // exit all remaining states - i = SCXML_NUMBER_STATES; + if (ctx->flags & USCXML_CTX_TOP_LEVEL_FINAL) { + /* exit all remaining states */ + i = USCXML_NUMBER_STATES; while(i-- > 0) { if (BIT_HAS(i, ctx->config)) { - // call all on exit handlers - if (ctx->machine->states[i].on_exit != NULL) { - if unlikely((err = ctx->machine->states[i].on_exit(ctx, &ctx->machine->states[i], ctx->event)) != SCXML_ERR_OK) + /* call all on exit handlers */ + if (USCXML_GET_STATE(i).on_exit != NULL) { + if unlikely((err = USCXML_GET_STATE(i).on_exit(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK) return err; } } if (BIT_HAS(i, ctx->invocations)) { - if (ctx->machine->states[i].invoke != NULL) - ctx->machine->states[i].invoke(ctx, &ctx->machine->states[i], NULL, 1); + if (USCXML_GET_STATE(i).invoke != NULL) + USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 1); BIT_CLEAR(i, ctx->invocations); } } - ctx->flags |= SCXML_CTX_FINISHED; - return SCXML_ERR_DONE; + ctx->flags |= USCXML_CTX_FINISHED; + return USCXML_ERR_DONE; } bit_clear_all(target_set, nr_states_bytes); bit_clear_all(trans_set, nr_trans_bytes); - if unlikely(ctx->flags == SCXML_CTX_PRISTINE) { + if unlikely(ctx->flags == USCXML_CTX_PRISTINE) { if (ctx->machine->script != NULL) ctx->machine->script(ctx, &ctx->machine->states[0], NULL); bit_or(target_set, ctx->machine->states[0].completion, nr_states_bytes); - ctx->flags |= SCXML_CTX_SPONTANEOUS | SCXML_CTX_INITIALIZED; + ctx->flags |= USCXML_CTX_SPONTANEOUS | USCXML_CTX_INITIALIZED; goto ESTABLISH_ENTRY_SET; } - if (ctx->flags & SCXML_CTX_SPONTANEOUS) { + if (ctx->flags & USCXML_CTX_SPONTANEOUS) { ctx->event = NULL; goto SELECT_TRANSITIONS; } @@ -722,18 +760,18 @@ int scxml_step(scxml_ctx* ctx) { goto SELECT_TRANSITIONS; } - // manage invocations - for (i = 0; i < SCXML_NUMBER_STATES; i++) { - // uninvoke + /* manage invocations */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { + /* uninvoke */ if (!BIT_HAS(i, ctx->config) && BIT_HAS(i, ctx->invocations)) { - if (ctx->machine->states[i].invoke != NULL) - ctx->machine->states[i].invoke(ctx, &ctx->machine->states[i], NULL, 1); + if (USCXML_GET_STATE(i).invoke != NULL) + USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 1); BIT_CLEAR(i, ctx->invocations) } - // invoke + /* invoke */ if (BIT_HAS(i, ctx->config) && !BIT_HAS(i, ctx->invocations)) { - if (ctx->machine->states[i].invoke != NULL) - ctx->machine->states[i].invoke(ctx, &ctx->machine->states[i], NULL, 0); + if (USCXML_GET_STATE(i).invoke != NULL) + USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 0); BIT_SET_AT(i, ctx->invocations) } } @@ -745,28 +783,28 @@ int scxml_step(scxml_ctx* ctx) { SELECT_TRANSITIONS: bit_clear_all(conflicts, nr_trans_bytes); bit_clear_all(exit_set, nr_states_bytes); - for (i = 0; i < SCXML_NUMBER_TRANS; i++) { - // never select history or initial transitions automatically - if unlikely(ctx->machine->transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) + for (i = 0; i < USCXML_NUMBER_TRANS; i++) { + /* never select history or initial transitions automatically */ + if unlikely(USCXML_GET_TRANS(i).type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL)) continue; - // is the transition active? - if (BIT_HAS(ctx->machine->transitions[i].source, ctx->config)) { - // is it non-conflicting? + /* is the transition active? */ + if (BIT_HAS(USCXML_GET_TRANS(i).source, ctx->config)) { + /* is it non-conflicting? */ if (!BIT_HAS(i, conflicts)) { - // is it enabled? - if (ctx->is_enabled(ctx, &ctx->machine->transitions[i], ctx->event) > 0) { - // remember that we found a transition - ctx->flags |= SCXML_CTX_TRANSITION_FOUND; + /* is it enabled? */ + if (ctx->is_enabled(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) { + /* remember that we found a transition */ + ctx->flags |= USCXML_CTX_TRANSITION_FOUND; - // transitions that are pre-empted - bit_or(conflicts, ctx->machine->transitions[i].conflicts, nr_trans_bytes); + /* transitions that are pre-empted */ + bit_or(conflicts, USCXML_GET_TRANS(i).conflicts, nr_trans_bytes); - // states that are directly targeted (resolve as entry-set later) - bit_or(target_set, ctx->machine->transitions[i].target, nr_states_bytes); + /* states that are directly targeted (resolve as entry-set later) */ + bit_or(target_set, USCXML_GET_TRANS(i).target, nr_states_bytes); - // states that will be left - bit_or(exit_set, ctx->machine->transitions[i].exit_set, nr_states_bytes); + /* states that will be left */ + bit_or(exit_set, USCXML_GET_TRANS(i).exit_set, nr_states_bytes); BIT_SET_AT(i, trans_set); } @@ -775,78 +813,78 @@ SELECT_TRANSITIONS: } bit_and(exit_set, ctx->config, nr_states_bytes); - if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) { - ctx->flags |= SCXML_CTX_SPONTANEOUS; - ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND; + if (ctx->flags & USCXML_CTX_TRANSITION_FOUND) { + ctx->flags |= USCXML_CTX_SPONTANEOUS; + ctx->flags &= ~USCXML_CTX_TRANSITION_FOUND; } else { - ctx->flags &= ~SCXML_CTX_SPONTANEOUS; + ctx->flags &= ~USCXML_CTX_SPONTANEOUS; } -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Targets: "); - printStateNames(ctx, target_set, SCXML_NUMBER_STATES); + printStateNames(ctx, target_set, USCXML_NUMBER_STATES); #endif -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Exiting: "); - printStateNames(ctx, exit_set, SCXML_NUMBER_STATES); + printStateNames(ctx, exit_set, USCXML_NUMBER_STATES); #endif -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("History: "); - printStateNames(ctx, ctx->history, SCXML_NUMBER_STATES); + printStateNames(ctx, ctx->history, USCXML_NUMBER_STATES); #endif -// REMEMBER_HISTORY: - for (i = 0; i < SCXML_NUMBER_STATES; i++) { - if unlikely(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_SHALLOW || - SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_DEEP) { - // a history state whose parent is about to be exited - if unlikely(BIT_HAS(ctx->machine->states[i].parent, exit_set)) { - bit_copy(tmp_states, ctx->machine->states[i].completion, nr_states_bytes); +/* REMEMBER_HISTORY: */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { + if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_SHALLOW || + USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP) { + /* a history state whose parent is about to be exited */ + if unlikely(BIT_HAS(USCXML_GET_STATE(i).parent, exit_set)) { + bit_copy(tmp_states, USCXML_GET_STATE(i).completion, nr_states_bytes); - // set those states who were enabled + /* set those states who were enabled */ bit_and(tmp_states, ctx->config, nr_states_bytes); - // clear current history with completion mask - bit_and_not(ctx->history, ctx->machine->states[i].completion, nr_states_bytes); + /* clear current history with completion mask */ + bit_and_not(ctx->history, USCXML_GET_STATE(i).completion, nr_states_bytes); - // set history + /* set history */ bit_or(ctx->history, tmp_states, nr_states_bytes); } } } ESTABLISH_ENTRY_SET: - // calculate new entry set + /* calculate new entry set */ bit_copy(entry_set, target_set, nr_states_bytes); - // iterate for ancestors - for (i = 0; i < SCXML_NUMBER_STATES; i++) { + /* iterate for ancestors */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { if (BIT_HAS(i, entry_set)) { - bit_or(entry_set, ctx->machine->states[i].ancestors, nr_states_bytes); + bit_or(entry_set, USCXML_GET_STATE(i).ancestors, nr_states_bytes); } } - // iterate for descendants - for (i = 0; i < SCXML_NUMBER_STATES; i++) { + /* iterate for descendants */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { if (BIT_HAS(i, entry_set)) { - switch (SCXML_STATE_MASK(ctx->machine->states[i].type)) { - case SCXML_STATE_PARALLEL: { - bit_or(entry_set, ctx->machine->states[i].completion, nr_states_bytes); + switch (USCXML_STATE_MASK(USCXML_GET_STATE(i).type)) { + case USCXML_STATE_PARALLEL: { + bit_or(entry_set, USCXML_GET_STATE(i).completion, nr_states_bytes); break; } - case SCXML_STATE_HISTORY_SHALLOW: - case SCXML_STATE_HISTORY_DEEP: { - if (!bit_has_and(ctx->machine->states[i].completion, ctx->history, nr_states_bytes) && - !BIT_HAS(ctx->machine->states[i].parent, ctx->config)) { - // nothing set for history, look for a default transition - for (j = 0; j < SCXML_NUMBER_TRANS; j++) { + case USCXML_STATE_HISTORY_SHALLOW: + case USCXML_STATE_HISTORY_DEEP: { + if (!bit_has_and(USCXML_GET_STATE(i).completion, ctx->history, nr_states_bytes) && + !BIT_HAS(USCXML_GET_STATE(i).parent, ctx->config)) { + /* nothing set for history, look for a default transition */ + for (j = 0; j < USCXML_NUMBER_TRANS; j++) { if unlikely(ctx->machine->transitions[j].source == i) { bit_or(entry_set, ctx->machine->transitions[j].target, nr_states_bytes); - if(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_DEEP && - !bit_has_and(ctx->machine->transitions[j].target, ctx->machine->states[i].children, nr_states_bytes)) { - for (k = i + 1; k < SCXML_NUMBER_STATES; k++) { + if(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP && + !bit_has_and(ctx->machine->transitions[j].target, USCXML_GET_STATE(i).children, nr_states_bytes)) { + for (k = i + 1; k < USCXML_NUMBER_STATES; k++) { if (BIT_HAS(k, ctx->machine->transitions[j].target)) { bit_or(entry_set, ctx->machine->states[k].ancestors, nr_states_bytes); break; @@ -856,24 +894,24 @@ ESTABLISH_ENTRY_SET: BIT_SET_AT(j, trans_set); break; } - // Note: SCXML mandates every history to have a transition! + /* Note: SCXML mandates every history to have a transition! */ } } else { - bit_copy(tmp_states, ctx->machine->states[i].completion, nr_states_bytes); + bit_copy(tmp_states, USCXML_GET_STATE(i).completion, nr_states_bytes); bit_and(tmp_states, ctx->history, nr_states_bytes); bit_or(entry_set, tmp_states, nr_states_bytes); - if (ctx->machine->states[i].type == (SCXML_STATE_HAS_HISTORY | SCXML_STATE_HISTORY_DEEP)) { - // a deep history state with nested histories -> more completion - for (j = i + 1; j < SCXML_NUMBER_STATES; j++) { - if (BIT_HAS(j, ctx->machine->states[i].completion) && + if (USCXML_GET_STATE(i).type == (USCXML_STATE_HAS_HISTORY | USCXML_STATE_HISTORY_DEEP)) { + /* a deep history state with nested histories -> more completion */ + for (j = i + 1; j < USCXML_NUMBER_STATES; j++) { + if (BIT_HAS(j, USCXML_GET_STATE(i).completion) && BIT_HAS(j, entry_set) && - (ctx->machine->states[j].type & SCXML_STATE_HAS_HISTORY)) { - for (k = j + 1; k < SCXML_NUMBER_STATES; k++) { - // add nested history to entry_set - if ((SCXML_STATE_MASK(ctx->machine->states[k].type) == SCXML_STATE_HISTORY_DEEP || - SCXML_STATE_MASK(ctx->machine->states[k].type) == SCXML_STATE_HISTORY_SHALLOW) && + (ctx->machine->states[j].type & USCXML_STATE_HAS_HISTORY)) { + for (k = j + 1; k < USCXML_NUMBER_STATES; k++) { + /* add nested history to entry_set */ + if ((USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_HISTORY_DEEP || + USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_HISTORY_SHALLOW) && BIT_HAS(k, ctx->machine->states[j].children)) { - // a nested history state + /* a nested history state */ BIT_SET_AT(k, entry_set); } } @@ -883,13 +921,13 @@ ESTABLISH_ENTRY_SET: } break; } - case SCXML_STATE_INITIAL: { - for (j = 0; j < SCXML_NUMBER_TRANS; j++) { + case USCXML_STATE_INITIAL: { + for (j = 0; j < USCXML_NUMBER_TRANS; j++) { if (ctx->machine->transitions[j].source == i) { BIT_SET_AT(j, trans_set); BIT_CLEAR(i, entry_set); bit_or(entry_set, ctx->machine->transitions[j].target, nr_states_bytes); - for (k = i + 1; k < SCXML_NUMBER_STATES; k++) { + for (k = i + 1; k < USCXML_NUMBER_STATES; k++) { if (BIT_HAS(k, ctx->machine->transitions[j].target)) { bit_or(entry_set, ctx->machine->states[k].ancestors, nr_states_bytes); } @@ -898,18 +936,18 @@ ESTABLISH_ENTRY_SET: } break; } - case SCXML_STATE_COMPOUND: { // we need to check whether one child is already in entry_set - if (!bit_has_and(entry_set, ctx->machine->states[i].children, nr_states_bytes) && - (!bit_has_and(ctx->config, ctx->machine->states[i].children, nr_states_bytes) || - bit_has_and(exit_set, ctx->machine->states[i].children, nr_states_bytes))) + case USCXML_STATE_COMPOUND: { /* we need to check whether one child is already in entry_set */ + if (!bit_has_and(entry_set, USCXML_GET_STATE(i).children, nr_states_bytes) && + (!bit_has_and(ctx->config, USCXML_GET_STATE(i).children, nr_states_bytes) || + bit_has_and(exit_set, USCXML_GET_STATE(i).children, nr_states_bytes))) { - bit_or(entry_set, ctx->machine->states[i].completion, nr_states_bytes); - if (!bit_has_and(ctx->machine->states[i].completion, ctx->machine->states[i].children, nr_states_bytes)) { - // deep completion - for (j = i + 1; j < SCXML_NUMBER_STATES; j++) { - if (BIT_HAS(j, ctx->machine->states[i].completion)) { + bit_or(entry_set, USCXML_GET_STATE(i).completion, nr_states_bytes); + if (!bit_has_and(USCXML_GET_STATE(i).completion, USCXML_GET_STATE(i).children, nr_states_bytes)) { + /* deep completion */ + for (j = i + 1; j < USCXML_NUMBER_STATES; j++) { + if (BIT_HAS(j, USCXML_GET_STATE(i).completion)) { bit_or(entry_set, ctx->machine->states[j].ancestors, nr_states_bytes); - break; // completion of compound is single state + break; /* completion of compound is single state */ } } } @@ -920,94 +958,94 @@ ESTABLISH_ENTRY_SET: } } -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Transitions: "); printBitsetIndices(trans_set, sizeof(char) * 8 * nr_trans_bytes); #endif -// EXIT_STATES: - i = SCXML_NUMBER_STATES; +/* EXIT_STATES: */ + i = USCXML_NUMBER_STATES; while(i-- > 0) { if (BIT_HAS(i, exit_set) && BIT_HAS(i, ctx->config)) { - // call all on exit handlers - if (ctx->machine->states[i].on_exit != NULL) { - if unlikely((err = ctx->machine->states[i].on_exit(ctx, &ctx->machine->states[i], ctx->event)) != SCXML_ERR_OK) + /* call all on exit handlers */ + if (USCXML_GET_STATE(i).on_exit != NULL) { + if unlikely((err = USCXML_GET_STATE(i).on_exit(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK) return err; } BIT_CLEAR(i, ctx->config); } } -// TAKE_TRANSITIONS: - for (i = 0; i < SCXML_NUMBER_TRANS; i++) { - if (BIT_HAS(i, trans_set) && (ctx->machine->transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) == 0) { - // call executable content in transition - if (ctx->machine->transitions[i].on_transition != NULL) { - if unlikely((err = ctx->machine->transitions[i].on_transition(ctx, - &ctx->machine->states[ctx->machine->transitions[i].source], - ctx->event)) != SCXML_ERR_OK) +/* TAKE_TRANSITIONS: */ + for (i = 0; i < USCXML_NUMBER_TRANS; i++) { + if (BIT_HAS(i, trans_set) && (USCXML_GET_TRANS(i).type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL)) == 0) { + /* call executable content in transition */ + if (USCXML_GET_TRANS(i).on_transition != NULL) { + if unlikely((err = USCXML_GET_TRANS(i).on_transition(ctx, + &ctx->machine->states[USCXML_GET_TRANS(i).source], + ctx->event)) != USCXML_ERR_OK) return err; } } } -#ifdef SCXML_VERBOSE +#ifdef USCXML_VERBOSE printf("Entering: "); - printStateNames(ctx, entry_set, SCXML_NUMBER_STATES); + printStateNames(ctx, entry_set, USCXML_NUMBER_STATES); #endif -// ENTER_STATES: - for (i = 0; i < SCXML_NUMBER_STATES; i++) { +/* ENTER_STATES: */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { if (BIT_HAS(i, entry_set) && !BIT_HAS(i, ctx->config)) { - // these are no proper states - if unlikely(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_DEEP || - SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_HISTORY_SHALLOW || - SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_INITIAL) + /* these are no proper states */ + if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP || + USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_SHALLOW || + USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_INITIAL) continue; BIT_SET_AT(i, ctx->config); - // initialize data + /* initialize data */ if (!BIT_HAS(i, ctx->initialized_data)) { - if unlikely(ctx->machine->states[i].data != NULL && ctx->exec_content_init != NULL) { - ctx->exec_content_init(ctx, ctx->machine->states[i].data); + if unlikely(USCXML_GET_STATE(i).data != NULL && ctx->exec_content_init != NULL) { + ctx->exec_content_init(ctx, USCXML_GET_STATE(i).data); } BIT_SET_AT(i, ctx->initialized_data); } - if (ctx->machine->states[i].on_entry != NULL) { - if unlikely((err = ctx->machine->states[i].on_entry(ctx, &ctx->machine->states[i], ctx->event)) != SCXML_ERR_OK) + if (USCXML_GET_STATE(i).on_entry != NULL) { + if unlikely((err = USCXML_GET_STATE(i).on_entry(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK) return err; } - // take history and initial transitions - for (j = 0; j < SCXML_NUMBER_TRANS; j++) { + /* take history and initial transitions */ + for (j = 0; j < USCXML_NUMBER_TRANS; j++) { if unlikely(BIT_HAS(j, trans_set) && - (ctx->machine->transitions[j].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_INITIAL)) && + (ctx->machine->transitions[j].type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL)) && ctx->machine->states[ctx->machine->transitions[j].source].parent == i) { - // call executable content in transition + /* call executable content in transition */ if (ctx->machine->transitions[j].on_transition != NULL) { if unlikely((err = ctx->machine->transitions[j].on_transition(ctx, - &ctx->machine->states[i], - ctx->event)) != SCXML_ERR_OK) + &USCXML_GET_STATE(i), + ctx->event)) != USCXML_ERR_OK) return err; } } } - // handle final states - if unlikely(SCXML_STATE_MASK(ctx->machine->states[i].type) == SCXML_STATE_FINAL) { - if unlikely(ctx->machine->states[i].ancestors[0] == 0x01) { - ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL; + /* handle final states */ + if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_FINAL) { + if unlikely(USCXML_GET_STATE(i).ancestors[0] == 0x01) { + ctx->flags |= USCXML_CTX_TOP_LEVEL_FINAL; } else { - // raise done event - const scxml_elem_donedata* donedata = &ctx->machine->donedata[0]; - while(ELEM_DONEDATA_IS_SET(donedata)) { + /* raise done event */ + const uscxml_elem_donedata* donedata = &ctx->machine->donedata[0]; + while(USCXML_ELEM_DONEDATA_IS_SET(donedata)) { if unlikely(donedata->source == i) break; donedata++; } - ctx->raise_done_event(ctx, &ctx->machine->states[ctx->machine->states[i].parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL)); + ctx->raise_done_event(ctx, &ctx->machine->states[USCXML_GET_STATE(i).parent], (USCXML_ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL)); } /** @@ -1017,13 +1055,13 @@ ESTABLISH_ENTRY_SET: * 3. Iterate all active final states and remove their ancestors * 4. If a state remains, not all children of a parallel are final */ - for (j = 0; j < SCXML_NUMBER_STATES; j++) { - if unlikely(SCXML_STATE_MASK(ctx->machine->states[j].type) == SCXML_STATE_PARALLEL && - BIT_HAS(j, ctx->machine->states[i].ancestors)) { + for (j = 0; j < USCXML_NUMBER_STATES; j++) { + if unlikely(USCXML_STATE_MASK(ctx->machine->states[j].type) == USCXML_STATE_PARALLEL && + BIT_HAS(j, USCXML_GET_STATE(i).ancestors)) { bit_clear_all(tmp_states, nr_states_bytes); - for (k = 0; k < SCXML_NUMBER_STATES; k++) { + for (k = 0; k < USCXML_NUMBER_STATES; k++) { if unlikely(BIT_HAS(j, ctx->machine->states[k].ancestors) && BIT_HAS(k, ctx->config)) { - if (SCXML_STATE_MASK(ctx->machine->states[k].type) == SCXML_STATE_FINAL) { + if (USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_FINAL) { bit_and_not(tmp_states, ctx->machine->states[k].ancestors, nr_states_bytes); } else { BIT_SET_AT(k, tmp_states); @@ -1041,6 +1079,9 @@ ESTABLISH_ENTRY_SET: } } - return SCXML_ERR_OK; + return USCXML_ERR_OK; } +#define USCXML_STEP_FUNCTION +#endif + -- cgit v0.12