diff options
Diffstat (limited to 'test/src')
-rw-r--r-- | test/src/test-c-inline.c | 40 | ||||
-rw-r--r-- | test/src/test-c-inline.c.scxml.c | 951 | ||||
-rw-r--r-- | test/src/test-c-machine.cpp | 42 | ||||
-rw-r--r-- | test/src/test-c-machine.scxml.c (renamed from test/src/test-c-machine.machine.c) | 228 |
4 files changed, 1148 insertions, 113 deletions
diff --git a/test/src/test-c-inline.c b/test/src/test-c-inline.c new file mode 100644 index 0000000..c12ac73 --- /dev/null +++ b/test/src/test-c-inline.c @@ -0,0 +1,40 @@ +#include <stdlib.h> // EXIT_SUCCESS +#include <stdio.h> // printf +#include <string.h> // memset + +/** + * Preprocess: + * uscxml-transform -tc -i ./test-c-inline.c -o ./test-c-inline.c.scxml.c + */ + +/** INLINE SCXML BEGIN +<scxml name="test-inline" datamodel="native"> + <state id="foo"> + <onentry> + enteredFoo(); + </onentry> + </state> +</scxml> +INLINE SCXML END */ + +/** + * These function can be called from within executable content + */ +void enteredFoo() { + printf("Entered Foo!\n"); +} + +#include "test-c-inline.c.scxml.c" + +int main(int argc, char** argv) { + uscxml_ctx ctx; + memset(&ctx, 0, sizeof(uscxml_ctx)); + ctx.machine = &USCXML_MACHINE_TEST_INLINE; + + int err = USCXML_ERR_OK; + while(err != USCXML_ERR_DONE) { + err = uscxml_step(&ctx); + } + + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/test/src/test-c-inline.c.scxml.c b/test/src/test-c-inline.c.scxml.c new file mode 100644 index 0000000..d586bb3 --- /dev/null +++ b/test/src/test-c-inline.c.scxml.c @@ -0,0 +1,951 @@ +/** + Generated from source: + file:///Users/sradomski/Documents/TK/Code/uscxml/test/src/test-c-inline.c +*/ + +#ifndef USCXML_NO_STDTYPES_H +# include <stdint.h> /* explicit types */ +#endif +#include <stddef.h> /* NULL */ + +#ifndef USCXML_NO_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 0 +#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)) +#else +# define likely(x) (x) +# define unlikely(x) (x) +#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_NO_GEN_C_MACROS +#endif + + +#ifndef USCXML_NO_GEN_C_TYPES + +/** + * All types required to represent an SCXML state chart. + * Just predefine the USCXML_NO_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); + +/** + * 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 */ +}; + +/** + * 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; +}; + +/** + * 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_* */ +}; + +/** + * 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 unsigned char type; + const char conflicts[USCXML_MAX_NR_TRANS_BYTES]; + const char exit_set[USCXML_MAX_NR_STATES_BYTES]; +}; + +/** + * All information pertaining to a <foreach> element. + */ +struct uscxml_elem_foreach { + const char* array; + const char* item; + const char* index; +}; + +/** + * 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; +}; + +/** + * All information pertaining to a <donedata> element. + */ +struct uscxml_elem_donedata { + const USCXML_NR_STATES_TYPE source; + const char* content; + const char* contentexpr; + const uscxml_elem_param* params; +}; + +/** + * All information pertaining to an <invoke> element. + */ +struct uscxml_elem_invoke { + const uscxml_machine* machine; + const char* type; + const char* typeexpr; + const char* src; + const char* srcexpr; + const char* id; + const char* idlocation; + const char* sourcename; + const char* namelist; + const unsigned char autoforward; + const uscxml_elem_param* params; + exec_content_finalize_t finalize; + const char* content; + const char* contentexpr; +}; + +/** + * All information pertaining to a <send> element. + */ +struct uscxml_elem_send { + const char* event; + const char* eventexpr; + const char* target; + const char* targetexpr; + const char* type; + const char* typeexpr; + const char* id; + const char* idlocation; + const char* delay; + const char* delayexpr; + const char* namelist; /* not space-separated, still as in attribute value */ + const char* content; + const char* contentexpr; + const uscxml_elem_param* params; +}; + +/** + * Represents an instance of a state-chart at runtime/ + */ +struct uscxml_ctx { + unsigned char flags; + const uscxml_machine* machine; + + 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; + 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_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; + + invoke_t invoke; +}; + +#define USCXML_NO_GEN_C_TYPES +#endif + +/* forward declare machines to allow references */ +extern const uscxml_machine _uscxml_9FAC9BE9_machine; + +#ifndef USCXML_NO_ELEM_INFO + +static const uscxml_elem_donedata _uscxml_9FAC9BE9_elem_donedatas[1] = { + /* source, content, contentexpr, params */ + { 0, NULL, NULL, NULL } +}; + +#endif + +#ifndef USCXML_NO_ELEM_INFO + +#endif + +#ifndef USCXML_NO_EXEC_CONTENT + +static int _uscxml_9FAC9BE9_foo_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + int err = USCXML_ERR_OK; + + enteredFoo(); + return USCXML_ERR_OK; +} + +static int _uscxml_9FAC9BE9_foo_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_9FAC9BE9_foo_on_entry_0(ctx, state, event); + return USCXML_ERR_OK; +} + +#endif + +#ifndef USCXML_NO_ELEM_INFO + +static const uscxml_state _uscxml_9FAC9BE9_states[2] = { + { /* state number 0 */ + /* name */ NULL, + /* parent */ 0, + /* onentry */ NULL, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x02 /* 01 */ }, + /* completion */ { 0x02 /* 01 */ }, + /* ancestors */ { 0x00 /* 00 */ }, + /* data */ NULL, + /* type */ USCXML_STATE_COMPOUND, + }, + { /* state number 1 */ + /* name */ "foo", + /* parent */ 0, + /* onentry */ _uscxml_9FAC9BE9_foo_on_entry, + /* onexit */ NULL, + /* invoke */ NULL, + /* children */ { 0x00 /* 00 */ }, + /* completion */ { 0x00 /* 00 */ }, + /* ancestors */ { 0x01 /* 10 */ }, + /* data */ NULL, + /* type */ USCXML_STATE_ATOMIC, + } +}; + +#endif + +#ifndef USCXML_NO_ELEM_INFO + +static const uscxml_transition _uscxml_9FAC9BE9_transitions[0] = { +}; + +#endif + +#ifndef USCXML_NO_ELEM_INFO + +#ifndef USCXML_MACHINE +# define USCXML_MACHINE _uscxml_9FAC9BE9_machine +#endif +#define USCXML_MACHINE_0 _uscxml_9FAC9BE9_machine +#define USCXML_MACHINE_TEST_INLINE _uscxml_9FAC9BE9_machine + +const uscxml_machine _uscxml_9FAC9BE9_machine = { + /* flags */ 0, + /* nr_states */ 2, + /* nr_transitions */ 0, + /* name */ "test-inline", + /* datamodel */ "native", + /* uuid */ "9FAC9BE9A82F66AFD36A205557064B27", + /* states */ &_uscxml_9FAC9BE9_states[0], + /* transitions */ &_uscxml_9FAC9BE9_transitions[0], + /* parent */ NULL, + /* donedata */ &_uscxml_9FAC9BE9_elem_donedatas[0], + /* script */ NULL +}; + +#endif + +#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, (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 = ""; + for (i = 0; i < length; i++) { + if (BIT_HAS(i, a)) { + printf("%s%lu", seperator, i); + seperator = ", "; + } + } + printf("\n"); +} +#endif + +#ifndef USCXML_NO_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]) + return 1; + } + 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) + return 1; + } + 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]; + }; +} + +#define USCXML_NO_BIT_OPERATIONS +#endif + +#ifndef USCXML_NO_STEP_FUNCTION +int uscxml_step(uscxml_ctx* ctx) { + + USCXML_NR_STATES_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, USCXML_NUMBER_STATES); +#endif + + if (ctx->flags & USCXML_CTX_FINISHED) + return USCXML_ERR_DONE; + + 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 (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 (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 |= 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 == 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 |= USCXML_CTX_SPONTANEOUS | USCXML_CTX_INITIALIZED; + goto ESTABLISH_ENTRY_SET; + } + + if (ctx->flags & USCXML_CTX_SPONTANEOUS) { + ctx->event = NULL; + goto SELECT_TRANSITIONS; + } + if (ctx->dequeue_internal != NULL && (ctx->event = ctx->dequeue_internal(ctx)) != NULL) { + goto SELECT_TRANSITIONS; + } + + /* manage invocations */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { + /* uninvoke */ + if (!BIT_HAS(i, ctx->config) && BIT_HAS(i, ctx->invocations)) { + 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 */ + if (BIT_HAS(i, ctx->config) && !BIT_HAS(i, ctx->invocations)) { + 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) + } + } + + if (ctx->dequeue_external != NULL && (ctx->event = ctx->dequeue_external(ctx)) != NULL) { + goto SELECT_TRANSITIONS; + } + + if (ctx->dequeue_external == NULL) { + return USCXML_ERR_DONE; + } + return USCXML_ERR_IDLE; + +SELECT_TRANSITIONS: + bit_clear_all(conflicts, nr_trans_bytes); + bit_clear_all(exit_set, nr_states_bytes); + 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(USCXML_GET_TRANS(i).source, ctx->config)) { + /* is it non-conflicting? */ + if (!BIT_HAS(i, conflicts)) { + /* is it spontaneous with an event or vice versa? */ + if ((USCXML_GET_TRANS(i).event == NULL && ctx->event == NULL) || + (USCXML_GET_TRANS(i).event != NULL && ctx->event != NULL)) { + /* 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, USCXML_GET_TRANS(i).conflicts, nr_trans_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, USCXML_GET_TRANS(i).exit_set, nr_states_bytes); + + BIT_SET_AT(i, trans_set); + } + } + } + } + } + bit_and(exit_set, ctx->config, nr_states_bytes); + + if (ctx->flags & USCXML_CTX_TRANSITION_FOUND) { + ctx->flags |= USCXML_CTX_SPONTANEOUS; + ctx->flags &= ~USCXML_CTX_TRANSITION_FOUND; + } else { + ctx->flags &= ~USCXML_CTX_SPONTANEOUS; + } + +#ifdef USCXML_VERBOSE + printf("Targets: "); + printStateNames(ctx, target_set, USCXML_NUMBER_STATES); +#endif + +#ifdef USCXML_VERBOSE + printf("Exiting: "); + printStateNames(ctx, exit_set, USCXML_NUMBER_STATES); +#endif + +#ifdef USCXML_VERBOSE + printf("History: "); + printStateNames(ctx, ctx->history, USCXML_NUMBER_STATES); +#endif + +/* 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 */ + bit_and(tmp_states, ctx->config, nr_states_bytes); + + /* clear current history with completion mask */ + bit_and_not(ctx->history, USCXML_GET_STATE(i).completion, nr_states_bytes); + + /* set history */ + bit_or(ctx->history, tmp_states, nr_states_bytes); + } + } + } + +ESTABLISH_ENTRY_SET: + /* calculate new entry set */ + bit_copy(entry_set, target_set, nr_states_bytes); + + /* iterate for ancestors */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { + if (BIT_HAS(i, entry_set)) { + bit_or(entry_set, USCXML_GET_STATE(i).ancestors, nr_states_bytes); + } + } + + /* iterate for descendants */ + for (i = 0; i < USCXML_NUMBER_STATES; i++) { + if (BIT_HAS(i, entry_set)) { + 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 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(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; + } + } + } + BIT_SET_AT(j, trans_set); + break; + } + /* Note: SCXML mandates every history to have a transition! */ + } + } else { + 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 (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 & 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 */ + BIT_SET_AT(k, entry_set); + } + } + } + } + } + } + break; + } + 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 < 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; + } + 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, 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; + } + } + } + } + +#ifdef USCXML_VERBOSE + printf("Transitions: "); + printBitsetIndices(trans_set, sizeof(char) * 8 * nr_trans_bytes); +#endif + +/* 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 (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 < 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 USCXML_VERBOSE + printf("Entering: "); + printStateNames(ctx, entry_set, USCXML_NUMBER_STATES); +#endif + +/* 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(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 */ + if (!BIT_HAS(i, ctx->initialized_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 (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 < USCXML_NUMBER_TRANS; j++) { + if unlikely(BIT_HAS(j, trans_set) && + (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 */ + if (ctx->machine->transitions[j].on_transition != NULL) { + if unlikely((err = ctx->machine->transitions[j].on_transition(ctx, + &USCXML_GET_STATE(i), + ctx->event)) != USCXML_ERR_OK) + return err; + } + } + } + + /* 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 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[USCXML_GET_STATE(i).parent], (USCXML_ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL)); + } + + /** + * are we the last final state to leave a parallel state?: + * 1. Gather all parallel states in our ancestor chain + * 2. Find all states for which these parallels are ancestors + * 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 < 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 < USCXML_NUMBER_STATES; k++) { + if unlikely(BIT_HAS(j, ctx->machine->states[k].ancestors) && BIT_HAS(k, ctx->config)) { + 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); + } + } + } + if unlikely(!bit_has_any(tmp_states, nr_states_bytes)) { + ctx->raise_done_event(ctx, &ctx->machine->states[j], NULL); + } + } + } + + } + + } + } + + return USCXML_ERR_OK; +} + +#define USCXML_NO_STEP_FUNCTION +#endif + diff --git a/test/src/test-c-machine.cpp b/test/src/test-c-machine.cpp index 3bd92aa..2879ef9 100644 --- a/test/src/test-c-machine.cpp +++ b/test/src/test-c-machine.cpp @@ -17,7 +17,7 @@ #endif #ifndef AUTOINCLUDE_TEST -#include "test-c-machine.machine.c" +#include "test-c-machine.scxml.c" #endif #include "uscxml/Convenience.h" @@ -637,27 +637,27 @@ public: Data d; std::stringstream content; - if (data->expr != NULL) { - d = USER_DATA(ctx)->dataModel.getStringAsData(data->expr); -// d = Data(data->expr, Data::INTERPRETED); - } else if (data->content != NULL) { - content << data->content; - 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) { - sourceURL.toAbsolute(USER_DATA(ctx)->baseURL); + try { + if (data->expr != NULL) { +// d = USER_DATA(ctx)->dataModel.getStringAsData(data->expr); + d = Data(data->expr, Data::INTERPRETED); + } else if (data->content != NULL) { + content << data->content; + 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) { + sourceURL.toAbsolute(USER_DATA(ctx)->baseURL); + } else { + sourceURL.toAbsoluteCwd(); + } + content << sourceURL; + // d = Data(content.str(), Data::INTERPRETED); + d = USER_DATA(ctx)->dataModel.getStringAsData(content.str()); } else { - sourceURL.toAbsoluteCwd(); + d = Data("undefined", Data::INTERPRETED); } - content << sourceURL; -// d = Data(content.str(), Data::INTERPRETED); - d = USER_DATA(ctx)->dataModel.getStringAsData(content.str()); - } else { - d = Data("undefined", Data::INTERPRETED); - } - try { // this might fail with an unquoted string literal in content USER_DATA(ctx)->dataModel.init(data->id, d); } catch (Event e) { @@ -930,7 +930,7 @@ int main(int argc, char** argv) { double avgDm = 0; #endif - StateMachine rootMachine(&uscxml_machines[0]); + StateMachine rootMachine(&USCXML_MACHINE); Timer tTotal; tTotal.start(); diff --git a/test/src/test-c-machine.machine.c b/test/src/test-c-machine.scxml.c index 5ac3994..cbbfbfe 100644 --- a/test/src/test-c-machine.machine.c +++ b/test/src/test-c-machine.scxml.c @@ -1,12 +1,14 @@ /** Generated from source: - file:///Users/sradomski/Documents/TK/Code/uscxml/test/w3c/lua/test150.scxml + file:///Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test326.scxml */ -#include <stdint.h> /* explicit types */ +#ifndef USCXML_NO_STDTYPES_H +# include <stdint.h> /* explicit types */ +#endif #include <stddef.h> /* NULL */ -#ifndef USCXML_GEN_C_MACROS +#ifndef USCXML_NO_GEN_C_MACROS /** * All macros used for the scxml types and functions @@ -143,15 +145,15 @@ #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 +#define USCXML_NO_GEN_C_MACROS #endif -#ifndef USCXML_GEN_C_TYPES +#ifndef USCXML_NO_GEN_C_TYPES /** * All types required to represent an SCXML state chart. - * Just predefine the USCXML_GEN_C_TYPES macro if you do not need them. + * Just predefine the USCXML_NO_GEN_C_TYPES macro if you do not need them. */ typedef struct uscxml_machine uscxml_machine; @@ -350,41 +352,38 @@ struct uscxml_ctx { invoke_t invoke; }; -#define USCXML_GEN_C_TYPES +#define USCXML_NO_GEN_C_TYPES #endif /* forward declare machines to allow references */ -extern const uscxml_machine uscxml_machines[2]; +extern const uscxml_machine _uscxml_EC83C2A5_machine; -static const uscxml_elem_foreach _uscxml_9FEEFF45_elem_foreachs[2] = { - /* array, item, index */ - { "testvar3", "testvar1", "testvar2" }, - { "testvar3", "testvar4", "testvar5" } -}; +#ifndef USCXML_NO_ELEM_INFO -static const uscxml_elem_data _uscxml_9FEEFF45_elem_datas[4] = { +static const uscxml_elem_data _uscxml_EC83C2A5_elem_datas[3] = { /* id, src, expr, content */ - { "testvar1", NULL, NULL, NULL }, - { "testvar2", NULL, NULL, NULL }, - { "testvar3", NULL, NULL, "{1,2,3}" }, + { "Var1", NULL, "_ioprocessors", NULL }, + { "Var2", NULL, NULL, NULL }, { NULL, NULL, NULL, NULL } }; -static const uscxml_elem_donedata _uscxml_9FEEFF45_elem_donedatas[1] = { +static const uscxml_elem_donedata _uscxml_EC83C2A5_elem_donedatas[1] = { /* source, content, contentexpr, params */ { 0, NULL, NULL, 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) { +#endif - 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; +#ifndef USCXML_NO_ELEM_INFO + +#endif + +#ifndef USCXML_NO_EXEC_CONTENT + +static int _uscxml_EC83C2A5_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_assign != NULL) { + if ((ctx->exec_content_assign(ctx, "_ioprocessors", "'otherName'")) != USCXML_ERR_OK) return err; } else { return USCXML_ERR_MISSING_CALLBACK; } @@ -396,38 +395,61 @@ static int _uscxml_9FEEFF45_s0_on_entry_0(const uscxml_ctx* ctx, const uscxml_st return USCXML_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); +static int _uscxml_EC83C2A5_s1_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_EC83C2A5_s1_on_entry_0(ctx, state, event); return USCXML_ERR_OK; } -static int _uscxml_9FEEFF45_s1_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { +static int _uscxml_EC83C2A5_s2_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 likely(ctx->exec_content_assign != NULL) { + if ((ctx->exec_content_assign(ctx, "Var2", "_ioprocessors")) != USCXML_ERR_OK) return err; + } else { + return USCXML_ERR_MISSING_CALLBACK; + } + return USCXML_ERR_OK; +} - 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; +static int _uscxml_EC83C2A5_s2_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_EC83C2A5_s2_on_entry_0(ctx, state, event); + return USCXML_ERR_OK; +} + +static int _uscxml_EC83C2A5_pass_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + int err = USCXML_ERR_OK; + if likely(ctx->exec_content_log != NULL) { + if unlikely((ctx->exec_content_log(ctx, "Outcome", "'pass'")) != USCXML_ERR_OK) return err; } else { return USCXML_ERR_MISSING_CALLBACK; } - if likely(ctx->exec_content_raise != NULL) { - if unlikely((ctx->exec_content_raise(ctx, "bar")) != USCXML_ERR_OK) return err; + return USCXML_ERR_OK; +} + +static int _uscxml_EC83C2A5_pass_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_EC83C2A5_pass_on_entry_0(ctx, state, event); + return USCXML_ERR_OK; +} + +static int _uscxml_EC83C2A5_fail_on_entry_0(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + int err = USCXML_ERR_OK; + if likely(ctx->exec_content_log != NULL) { + if unlikely((ctx->exec_content_log(ctx, "Outcome", "'fail'")) != USCXML_ERR_OK) return err; } else { return USCXML_ERR_MISSING_CALLBACK; } return USCXML_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); +static int _uscxml_EC83C2A5_fail_on_entry(const uscxml_ctx* ctx, const uscxml_state* state, const void* event) { + _uscxml_EC83C2A5_fail_on_entry_0(ctx, state, event); return USCXML_ERR_OK; } -static const uscxml_state _uscxml_9FEEFF45_states[6] = { +#endif + +#ifndef USCXML_NO_ELEM_INFO + +static const uscxml_state _uscxml_EC83C2A5_states[6] = { { /* state number 0 */ /* name */ NULL, /* parent */ 0, @@ -437,13 +459,13 @@ static const uscxml_state _uscxml_9FEEFF45_states[6] = { /* children */ { 0x3e /* 011111 */ }, /* completion */ { 0x02 /* 010000 */ }, /* ancestors */ { 0x00 /* 000000 */ }, - /* data */ &_uscxml_9FEEFF45_elem_datas[0], + /* data */ &_uscxml_EC83C2A5_elem_datas[0], /* type */ USCXML_STATE_COMPOUND, }, { /* state number 1 */ /* name */ "s0", /* parent */ 0, - /* onentry */ _uscxml_9FEEFF45_s0_on_entry, + /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, /* children */ { 0x00 /* 000000 */ }, @@ -455,7 +477,7 @@ static const uscxml_state _uscxml_9FEEFF45_states[6] = { { /* state number 2 */ /* name */ "s1", /* parent */ 0, - /* onentry */ _uscxml_9FEEFF45_s1_on_entry, + /* onentry */ _uscxml_EC83C2A5_s1_on_entry, /* onexit */ NULL, /* invoke */ NULL, /* children */ { 0x00 /* 000000 */ }, @@ -467,7 +489,7 @@ static const uscxml_state _uscxml_9FEEFF45_states[6] = { { /* state number 3 */ /* name */ "s2", /* parent */ 0, - /* onentry */ NULL, + /* onentry */ _uscxml_EC83C2A5_s2_on_entry, /* onexit */ NULL, /* invoke */ NULL, /* children */ { 0x00 /* 000000 */ }, @@ -479,7 +501,7 @@ static const uscxml_state _uscxml_9FEEFF45_states[6] = { { /* state number 4 */ /* name */ "pass", /* parent */ 0, - /* onentry */ NULL, + /* onentry */ _uscxml_EC83C2A5_pass_on_entry, /* onexit */ NULL, /* invoke */ NULL, /* children */ { 0x00 /* 000000 */ }, @@ -491,7 +513,7 @@ static const uscxml_state _uscxml_9FEEFF45_states[6] = { { /* state number 5 */ /* name */ "fail", /* parent */ 0, - /* onentry */ NULL, + /* onentry */ _uscxml_EC83C2A5_fail_on_entry, /* onexit */ NULL, /* invoke */ NULL, /* children */ { 0x00 /* 000000 */ }, @@ -502,37 +524,41 @@ static const uscxml_state _uscxml_9FEEFF45_states[6] = { } }; -static const uscxml_transition _uscxml_9FEEFF45_transitions[6] = { +#endif + +#ifndef USCXML_NO_ELEM_INFO + +static const uscxml_transition _uscxml_EC83C2A5_transitions[6] = { { /* transition number 0 with priority 0 - target: fail + target: s1 */ /* source */ 1, - /* target */ { 0x20 /* 000001 */ }, - /* event */ "error", - /* condition */ NULL, + /* target */ { 0x04 /* 001000 */ }, + /* event */ NULL, + /* condition */ "Var1", /* ontrans */ NULL, - /* type */ 0, + /* type */ USCXML_TRANS_SPONTANEOUS, /* conflicts */ { 0x3f /* 111111 */ }, /* exit set */ { 0x3e /* 011111 */ } }, { /* transition number 1 with priority 1 - target: s1 + target: fail */ /* source */ 1, - /* target */ { 0x04 /* 001000 */ }, - /* event */ "*", - /* condition */ NULL, + /* target */ { 0x20 /* 000001 */ }, + /* event */ NULL, + /* condition */ "true", /* ontrans */ NULL, - /* type */ 0, + /* type */ USCXML_TRANS_SPONTANEOUS, /* conflicts */ { 0x3f /* 111111 */ }, /* exit set */ { 0x3e /* 011111 */ } }, { /* transition number 2 with priority 2 - target: fail + target: s2 */ /* source */ 2, - /* target */ { 0x20 /* 000001 */ }, - /* event */ "error", + /* target */ { 0x08 /* 000100 */ }, + /* event */ "error.execution", /* condition */ NULL, /* ontrans */ NULL, /* type */ 0, @@ -540,10 +566,10 @@ static const uscxml_transition _uscxml_9FEEFF45_transitions[6] = { /* exit set */ { 0x3e /* 011111 */ } }, { /* transition number 3 with priority 3 - target: s2 + target: fail */ /* source */ 2, - /* target */ { 0x08 /* 000100 */ }, + /* target */ { 0x20 /* 000001 */ }, /* event */ "*", /* condition */ NULL, /* ontrans */ NULL, @@ -557,7 +583,7 @@ static const uscxml_transition _uscxml_9FEEFF45_transitions[6] = { /* source */ 3, /* target */ { 0x10 /* 000010 */ }, /* event */ NULL, - /* condition */ "testvar4 ~= nil", + /* condition */ "Var1==Var2", /* ontrans */ NULL, /* type */ USCXML_TRANS_SPONTANEOUS, /* conflicts */ { 0x3f /* 111111 */ }, @@ -577,23 +603,32 @@ static const uscxml_transition _uscxml_9FEEFF45_transitions[6] = { } }; -const uscxml_machine uscxml_machines[2] = { - { +#endif + +#ifndef USCXML_NO_ELEM_INFO + +#ifndef USCXML_MACHINE +# define USCXML_MACHINE _uscxml_EC83C2A5_machine +#endif +#define USCXML_MACHINE_0 _uscxml_EC83C2A5_machine +#define USCXML_MACHINE_MACHINENAME _uscxml_EC83C2A5_machine + +const uscxml_machine _uscxml_EC83C2A5_machine = { /* flags */ 0, /* nr_states */ 6, /* nr_transitions */ 6, - /* name */ "", - /* datamodel */ "lua", - /* uuid */ "9FEEFF45D10C557438897A21612B7382", - /* states */ &_uscxml_9FEEFF45_states[0], - /* transitions */ &_uscxml_9FEEFF45_transitions[0], + /* name */ "machineName", + /* datamodel */ "ecmascript", + /* uuid */ "EC83C2A5BDF05B11A1F7E2C35039F65D", + /* states */ &_uscxml_EC83C2A5_states[0], + /* transitions */ &_uscxml_EC83C2A5_transitions[0], /* parent */ NULL, - /* donedata */ &_uscxml_9FEEFF45_elem_donedatas[0], + /* donedata */ &_uscxml_EC83C2A5_elem_donedatas[0], /* script */ NULL - }, - {0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; +#endif + #ifdef USCXML_VERBOSE /** * Print name of states contained in a (debugging). @@ -626,7 +661,7 @@ static void printBitsetIndices(const char* a, size_t length) { } #endif -#ifndef USCXML_BIT_OPERATIONS +#ifndef USCXML_NO_BIT_OPERATIONS /** * Return true if there is a common bit in a and b. */ @@ -696,10 +731,10 @@ static void bit_and(char* dest, const char* mask, size_t i) { }; } -#define USCXML_BIT_OPERATIONS +#define USCXML_NO_BIT_OPERATIONS #endif -#ifndef USCXML_STEP_FUNCTION +#ifndef USCXML_NO_STEP_FUNCTION int uscxml_step(uscxml_ctx* ctx) { USCXML_NR_TRANS_TYPE i, j, k; @@ -756,7 +791,7 @@ int uscxml_step(uscxml_ctx* ctx) { ctx->event = NULL; goto SELECT_TRANSITIONS; } - if ((ctx->event = ctx->dequeue_internal(ctx)) != NULL) { + if (ctx->dequeue_internal != NULL && (ctx->event = ctx->dequeue_internal(ctx)) != NULL) { goto SELECT_TRANSITIONS; } @@ -776,10 +811,15 @@ int uscxml_step(uscxml_ctx* ctx) { } } - if ((ctx->event = ctx->dequeue_external(ctx)) != NULL) { + if (ctx->dequeue_external != NULL && (ctx->event = ctx->dequeue_external(ctx)) != NULL) { goto SELECT_TRANSITIONS; } + if (ctx->dequeue_external == NULL) { + return USCXML_ERR_DONE; + } + return USCXML_ERR_IDLE; + SELECT_TRANSITIONS: bit_clear_all(conflicts, nr_trans_bytes); bit_clear_all(exit_set, nr_states_bytes); @@ -792,21 +832,25 @@ SELECT_TRANSITIONS: 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, &USCXML_GET_TRANS(i), ctx->event) > 0) { - /* remember that we found a transition */ - ctx->flags |= USCXML_CTX_TRANSITION_FOUND; + /* is it spontaneous with an event or vice versa? */ + if ((USCXML_GET_TRANS(i).event == NULL && ctx->event == NULL) || + (USCXML_GET_TRANS(i).event != NULL && ctx->event != NULL)) { + /* 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, USCXML_GET_TRANS(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, USCXML_GET_TRANS(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, USCXML_GET_TRANS(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); + BIT_SET_AT(i, trans_set); + } } } } @@ -1082,6 +1126,6 @@ ESTABLISH_ENTRY_SET: return USCXML_ERR_OK; } -#define USCXML_STEP_FUNCTION +#define USCXML_NO_STEP_FUNCTION #endif |