diff options
Diffstat (limited to 'test/src')
-rw-r--r-- | test/src/test-c-machine.cpp | 166 | ||||
-rw-r--r-- | test/src/test-c-machine.machine.c | 1191 |
2 files changed, 700 insertions, 657 deletions
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> // deque #include <boost/algorithm/string.hpp> // 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<std::string, StateMachine*> &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<std::string>(), 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<tthread::mutex> 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<const scxml_elem_invoke*, std::string> invocationIds; + std::map<const uscxml_elem_invoke*, std::string> invocationIds; std::map<std::string, StateMachine*> 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<std::string, Data> invokeData; std::deque<Event*> iq; @@ -904,7 +906,7 @@ protected: DelayedEventQueue delayQueue; std::map<std::string, SendRequest*> sendIds; - std::map<const scxml_elem_foreach*, scxml_foreach_info*> foreachInfo; + std::map<const uscxml_elem_foreach*, scxml_foreach_info*> 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 <stdint.h> // explicit types -#include <stddef.h> // NULL +#include <stdint.h> /* explicit types */ +#include <stddef.h> /* 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 <data> 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 <transitions> 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 <foreach> element. + */ +struct uscxml_elem_foreach { const char* array; const char* item; const char* index; }; -struct scxml_elem_param { +/** + * All information pertaining to a <param> 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 <donedata> 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 <invoke> 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 <send> 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 + |