diff options
author | Stefan Radomski <sradomski@mintwerk.de> | 2016-01-20 16:19:38 (GMT) |
---|---|---|
committer | Stefan Radomski <sradomski@mintwerk.de> | 2016-01-20 16:19:38 (GMT) |
commit | 99457229adecc63246e900b01aee360039e7183d (patch) | |
tree | 5c103ab426fa3d27e983a54e481f2336295104ab /test | |
parent | b5abd34bfcc07588c7220d094a04dbc5708d344b (diff) | |
download | uscxml-99457229adecc63246e900b01aee360039e7183d.zip uscxml-99457229adecc63246e900b01aee360039e7183d.tar.gz uscxml-99457229adecc63246e900b01aee360039e7183d.tar.bz2 |
Added transition-less histories as an issue and completed C transformation
Diffstat (limited to 'test')
-rw-r--r-- | test/src/test-c-machine.machine.c | 238 | ||||
-rw-r--r-- | test/uscxml/automated/ecma/deep-histories2.scxml | 31 | ||||
-rw-r--r-- | test/uscxml/automated/ecma/uncompleted-history.scxml | 11 |
3 files changed, 155 insertions, 125 deletions
diff --git a/test/src/test-c-machine.machine.c b/test/src/test-c-machine.machine.c index 30d687c..d42d577 100644 --- a/test/src/test-c-machine.machine.c +++ b/test/src/test-c-machine.machine.c @@ -25,8 +25,8 @@ #define SCXML_ERR_UNSUPPORTED 8 #define SCXML_MACHINE_NAME "" -#define SCXML_NUMBER_STATES 12 -#define SCXML_NUMBER_TRANSITIONS 7 +#define SCXML_NUMBER_STATES 10 +#define SCXML_NUMBER_TRANSITIONS 5 #define SCXML_TRANS_SPONTANEOUS 0x01 #define SCXML_TRANS_TARGETLESS 0x02 @@ -41,6 +41,8 @@ #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 @@ -211,7 +213,7 @@ static int global_script(const scxml_ctx* ctx, const scxml_state* state, const v return SCXML_ERR_OK; } -static int s0_0_1_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { +static int s0_0_0_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, const void* event) { int err = SCXML_ERR_OK; if likely(ctx->exec_content_assign != NULL) { if ((ctx->exec_content_assign(ctx, "Var1", "Var1 + 1")) != SCXML_ERR_OK) return err; @@ -221,21 +223,36 @@ static int s0_0_1_on_entry_0(const scxml_ctx* ctx, const scxml_state* state, con return SCXML_ERR_OK; } -static int s0_0_1_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { - s0_0_1_on_entry_0(ctx, state, event); +static int s0_0_0_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + s0_0_0_on_entry_0(ctx, state, event); return SCXML_ERR_OK; } -static const scxml_state scxml_states[12] = { +static int 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_assign != NULL) { + if ((ctx->exec_content_assign(ctx, "Var1", "Var1 + 1")) != SCXML_ERR_OK) return err; + } else { + return SCXML_ERR_MISSING_CALLBACK; + } + return SCXML_ERR_OK; +} + +static int s1_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) { + s1_on_entry_0(ctx, state, event); + return SCXML_ERR_OK; +} + +static const scxml_state scxml_states[10] = { { /* state number 0 */ /* name */ NULL, /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x02, 0x0f /* 010000001111, 1 8 9 10 11 */ }, - /* completion */ { 0x02, 0x00 /* 010000000000, 1 */ }, - /* ancestors */ { 0x00, 0x00 /* 000000000000, */ }, + /* children */ { 0x82, 0x03 /* 0100000111, 1 7 8 9 */ }, + /* completion */ { 0x02, 0x00 /* 0100000000, 1 */ }, + /* ancestors */ { 0x00, 0x00 /* 0000000000, */ }, /* data */ &scxml_elem_datas[0], /* type */ SCXML_STATE_COMPOUND, }, @@ -245,23 +262,23 @@ static const scxml_state scxml_states[12] = { /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x8c, 0x00 /* 001100010000, 2 3 7 */ }, - /* completion */ { 0x08, 0x00 /* 000100000000, 3 */ }, - /* ancestors */ { 0x01, 0x00 /* 100000000000, 0 */ }, + /* children */ { 0x0c, 0x00 /* 0011000000, 2 3 */ }, + /* completion */ { 0x08, 0x00 /* 0001000000, 3 */ }, + /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ }, /* data */ NULL, - /* type */ SCXML_STATE_COMPOUND, + /* type */ SCXML_STATE_COMPOUND | SCXML_STATE_HAS_HISTORY, }, { /* state number 2 */ - /* name */ "s0.h0", + /* name */ "h0", /* parent */ 1, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0xe8, 0x00 /* 000101110000, 3 5 6 7 */ }, - /* ancestors */ { 0x03, 0x00 /* 110000000000, 0 1 */ }, + /* children */ { 0x00, 0x00 /* 0000000000, */ }, + /* completion */ { 0x08, 0x00 /* 0001000000, 3 */ }, + /* ancestors */ { 0x03, 0x00 /* 1100000000, 0 1 */ }, /* data */ NULL, - /* type */ SCXML_STATE_HISTORY_DEEP, + /* type */ SCXML_STATE_HISTORY_DEEP | SCXML_STATE_HAS_HISTORY, }, { /* state number 3 */ /* name */ "s0.0", @@ -269,194 +286,146 @@ static const scxml_state scxml_states[12] = { /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x70, 0x00 /* 000011100000, 4 5 6 */ }, - /* completion */ { 0x20, 0x00 /* 000001000000, 5 */ }, - /* ancestors */ { 0x03, 0x00 /* 110000000000, 0 1 */ }, + /* children */ { 0x70, 0x00 /* 0000111000, 4 5 6 */ }, + /* completion */ { 0x20, 0x00 /* 0000010000, 5 */ }, + /* ancestors */ { 0x03, 0x00 /* 1100000000, 0 1 */ }, /* data */ NULL, - /* type */ SCXML_STATE_COMPOUND, + /* type */ SCXML_STATE_COMPOUND | SCXML_STATE_HAS_HISTORY, }, { /* state number 4 */ - /* name */ "s0.0.h0", + /* name */ "h1", /* parent */ 3, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x60, 0x00 /* 000001100000, 5 6 */ }, - /* ancestors */ { 0x0b, 0x00 /* 110100000000, 0 1 3 */ }, + /* children */ { 0x00, 0x00 /* 0000000000, */ }, + /* completion */ { 0x60, 0x00 /* 0000011000, 5 6 */ }, + /* ancestors */ { 0x0b, 0x00 /* 1101000000, 0 1 3 */ }, /* data */ NULL, - /* type */ SCXML_STATE_HISTORY_SHALLOW, + /* type */ SCXML_STATE_HISTORY_DEEP, }, { /* state number 5 */ /* name */ "s0.0.0", /* parent */ 3, - /* onentry */ NULL, + /* onentry */ s0_0_0_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x00, 0x00 /* 000000000000, */ }, - /* ancestors */ { 0x0b, 0x00 /* 110100000000, 0 1 3 */ }, + /* children */ { 0x00, 0x00 /* 0000000000, */ }, + /* completion */ { 0x00, 0x00 /* 0000000000, */ }, + /* ancestors */ { 0x0b, 0x00 /* 1101000000, 0 1 3 */ }, /* data */ NULL, /* type */ SCXML_STATE_ATOMIC, }, { /* state number 6 */ /* name */ "s0.0.1", /* parent */ 3, - /* onentry */ s0_0_1_on_entry, - /* onexit */ NULL, - /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x00, 0x00 /* 000000000000, */ }, - /* ancestors */ { 0x0b, 0x00 /* 110100000000, 0 1 3 */ }, - /* data */ NULL, - /* type */ SCXML_STATE_ATOMIC, - }, - { /* state number 7 */ - /* name */ "s0.1", - /* parent */ 1, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x00, 0x00 /* 000000000000, */ }, - /* ancestors */ { 0x03, 0x00 /* 110000000000, 0 1 */ }, + /* children */ { 0x00, 0x00 /* 0000000000, */ }, + /* completion */ { 0x00, 0x00 /* 0000000000, */ }, + /* ancestors */ { 0x0b, 0x00 /* 1101000000, 0 1 3 */ }, /* data */ NULL, /* type */ SCXML_STATE_ATOMIC, }, - { /* state number 8 */ + { /* state number 7 */ /* name */ "s1", /* parent */ 0, - /* onentry */ NULL, - /* onexit */ NULL, - /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x00, 0x00 /* 000000000000, */ }, - /* ancestors */ { 0x01, 0x00 /* 100000000000, 0 */ }, - /* data */ NULL, - /* type */ SCXML_STATE_ATOMIC, - }, - { /* state number 9 */ - /* name */ "s2", - /* parent */ 0, - /* onentry */ NULL, + /* onentry */ s1_on_entry, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x00, 0x00 /* 000000000000, */ }, - /* ancestors */ { 0x01, 0x00 /* 100000000000, 0 */ }, + /* children */ { 0x00, 0x00 /* 0000000000, */ }, + /* completion */ { 0x00, 0x00 /* 0000000000, */ }, + /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ }, /* data */ NULL, /* type */ SCXML_STATE_ATOMIC, }, - { /* state number 10 */ + { /* state number 8 */ /* name */ "pass", /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x00, 0x00 /* 000000000000, */ }, - /* ancestors */ { 0x01, 0x00 /* 100000000000, 0 */ }, + /* children */ { 0x00, 0x00 /* 0000000000, */ }, + /* completion */ { 0x00, 0x00 /* 0000000000, */ }, + /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ }, /* data */ NULL, /* type */ SCXML_STATE_FINAL, }, - { /* state number 11 */ + { /* state number 9 */ /* name */ "fail", /* parent */ 0, /* onentry */ NULL, /* onexit */ NULL, /* invoke */ NULL, - /* children */ { 0x00, 0x00 /* 000000000000, */ }, - /* completion */ { 0x00, 0x00 /* 000000000000, */ }, - /* ancestors */ { 0x01, 0x00 /* 100000000000, 0 */ }, + /* children */ { 0x00, 0x00 /* 0000000000, */ }, + /* completion */ { 0x00, 0x00 /* 0000000000, */ }, + /* ancestors */ { 0x01, 0x00 /* 1000000000, 0 */ }, /* data */ NULL, /* type */ SCXML_STATE_FINAL, } }; -static const scxml_transition scxml_transitions[7] = { +static const scxml_transition scxml_transitions[5] = { { /* transition number 0 with priority 0 target: s0.0.1 */ /* name */ 5, - /* target */ { 0x40, 0x00 /* 000000100000, 6 */ }, + /* target */ { 0x40, 0x00 /* 0000001000, 6 */ }, /* event */ NULL, - /* condition */ NULL, + /* condition */ "Var1 == 1", /* ontrans */ NULL, /* type */ SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 1111110, 0 1 2 3 4 5 */ }, - /* exit set */ { 0x70, 0x00 /* 000011100000, 4 5 6 */ } + /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ }, + /* exit set */ { 0x70, 0x00 /* 0000111000, 4 5 6 */ } }, { /* transition number 1 with priority 1 target: s1 */ /* name */ 6, - /* target */ { 0x00, 0x01 /* 000000001000, 8 */ }, + /* target */ { 0x80, 0x00 /* 0000000100, 7 */ }, /* event */ NULL, /* condition */ "Var1 == 1", /* ontrans */ NULL, /* type */ SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 1111110, 0 1 2 3 4 5 */ }, - /* exit set */ { 0xfe, 0x0f /* 011111111111, 1 2 3 4 5 6 7 8 9 10 11 */ } + /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ }, + /* exit set */ { 0xfe, 0x03 /* 0111111111, 1 2 3 4 5 6 7 8 9 */ } }, { /* transition number 2 with priority 2 - target: s2 - */ - /* name */ 7, - /* target */ { 0x00, 0x02 /* 000000000100, 9 */ }, - /* event */ NULL, - /* condition */ NULL, - /* ontrans */ NULL, - /* type */ SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 1111110, 0 1 2 3 4 5 */ }, - /* exit set */ { 0xfe, 0x0f /* 011111111111, 1 2 3 4 5 6 7 8 9 10 11 */ } - }, - { /* transition number 3 with priority 3 target: pass */ /* name */ 1, - /* target */ { 0x00, 0x04 /* 000000000010, 10 */ }, + /* target */ { 0x00, 0x01 /* 0000000010, 8 */ }, /* event */ NULL, /* condition */ "Var1 == 2", /* ontrans */ NULL, /* type */ SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 1111110, 0 1 2 3 4 5 */ }, - /* exit set */ { 0xfe, 0x0f /* 011111111111, 1 2 3 4 5 6 7 8 9 10 11 */ } + /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ }, + /* exit set */ { 0xfe, 0x03 /* 0111111111, 1 2 3 4 5 6 7 8 9 */ } }, - { /* transition number 4 with priority 4 + { /* transition number 3 with priority 3 target: fail */ /* name */ 1, - /* target */ { 0x00, 0x08 /* 000000000001, 11 */ }, - /* event */ NULL, - /* condition */ NULL, - /* ontrans */ NULL, - /* type */ SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 1111110, 0 1 2 3 4 5 */ }, - /* exit set */ { 0xfe, 0x0f /* 011111111111, 1 2 3 4 5 6 7 8 9 10 11 */ } - }, - { /* transition number 5 with priority 5 - target: s0.1 - */ - /* name */ 8, - /* target */ { 0x80, 0x00 /* 000000010000, 7 */ }, + /* target */ { 0x00, 0x02 /* 0000000001, 9 */ }, /* event */ NULL, /* condition */ NULL, /* ontrans */ NULL, /* type */ SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x3f /* 1111110, 0 1 2 3 4 5 */ }, - /* exit set */ { 0xfe, 0x0f /* 011111111111, 1 2 3 4 5 6 7 8 9 10 11 */ } + /* conflicts */ { 0x0f /* 11110, 0 1 2 3 */ }, + /* exit set */ { 0xfe, 0x03 /* 0111111111, 1 2 3 4 5 6 7 8 9 */ } }, - { /* transition number 6 with priority 6 - target: s0.0.h0 + { /* transition number 4 with priority 4 + target: h0 */ - /* name */ 9, - /* target */ { 0x10, 0x00 /* 000010000000, 4 */ }, + /* name */ 7, + /* target */ { 0x04, 0x00 /* 0010000000, 2 */ }, /* event */ NULL, - /* condition */ NULL, + /* condition */ "Var1 == 2", /* ontrans */ NULL, /* type */ SCXML_TRANS_SPONTANEOUS, - /* conflicts */ { 0x40 /* 0000001, 6 */ }, - /* exit set */ { 0x00, 0x00 /* 000000000000, */ } + /* conflicts */ { 0x10 /* 00001, 4 */ }, + /* exit set */ { 0x00, 0x00 /* 0000000000, */ } } }; @@ -616,7 +585,8 @@ SELECT_TRANSITIONS: // REMEMBER_HISTORY: for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { - if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW || scxml_states[i].type == SCXML_STATE_HISTORY_DEEP) { + if unlikely(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_SHALLOW || + SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP) { // a history state whose parent is about to be exited if unlikely(IS_SET(scxml_states[i].parent, exit_set)) { char history[2] = {0, 0}; @@ -648,7 +618,7 @@ ESTABLISH_ENTRY_SET: // iterate for descendants for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { if (IS_SET(i, entry_set)) { - switch (scxml_states[i].type) { + switch (SCXML_STATE_MASK(scxml_states[i].type)) { case SCXML_STATE_PARALLEL: { bit_or(entry_set, scxml_states[i].completion, 2); break; @@ -671,6 +641,24 @@ ESTABLISH_ENTRY_SET: bit_copy(history_targets, scxml_states[i].completion, 2); bit_and(history_targets, ctx->history, 2); bit_or(entry_set, history_targets, 2); + if (scxml_states[i].type == (SCXML_STATE_HAS_HISTORY | SCXML_STATE_HISTORY_DEEP)) { + // a deep history state with nested histories -> more completion + for (size_t j = i + 1; j < SCXML_NUMBER_STATES; j++) { + if (IS_SET(j, scxml_states[i].completion) && + IS_SET(j, entry_set) && + (scxml_states[j].type & SCXML_STATE_HAS_HISTORY)) { + for (size_t k = j + 1; k < SCXML_NUMBER_STATES; k++) { + // add nested history to entry_set + if ((scxml_states[k].type == SCXML_STATE_HISTORY_DEEP || + scxml_states[k].type == SCXML_STATE_HISTORY_SHALLOW) && + IS_SET(k, scxml_states[j].children)) { + // a nested history state + SET_BIT(k, entry_set); + } + } + } + } + } } break; } @@ -751,9 +739,9 @@ ESTABLISH_ENTRY_SET: for (size_t i = 0; i < SCXML_NUMBER_STATES; i++) { if (IS_SET(i, entry_set) && !IS_SET(i, ctx->config)) { // these are no proper states - if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_DEEP || - scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW || - scxml_states[i].type == SCXML_STATE_INITIAL) + if unlikely(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_DEEP || + SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_HISTORY_SHALLOW || + SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_INITIAL) continue; SET_BIT(i, ctx->config); @@ -787,7 +775,7 @@ ESTABLISH_ENTRY_SET: } // handle final states - if unlikely(scxml_states[i].type == SCXML_STATE_FINAL) { + if unlikely(SCXML_STATE_MASK(scxml_states[i].type) == SCXML_STATE_FINAL) { if unlikely(scxml_states[i].ancestors[0] == 0x01) { ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL; } else { @@ -809,12 +797,12 @@ ESTABLISH_ENTRY_SET: * 4. If a state remains, not all children of a parallel are final */ for (size_t j = 0; j < SCXML_NUMBER_STATES; j++) { - if unlikely(scxml_states[j].type == SCXML_STATE_PARALLEL) { + if unlikely(SCXML_STATE_MASK(scxml_states[j].type) == SCXML_STATE_PARALLEL) { char parallel_children[2] = {0, 0}; size_t parallel = j; for (size_t k = 0; k < SCXML_NUMBER_STATES; k++) { if unlikely(IS_SET(parallel, scxml_states[k].ancestors) && IS_SET(k, ctx->config)) { - if (scxml_states[k].type == SCXML_STATE_FINAL) { + if (SCXML_STATE_MASK(scxml_states[k].type) == SCXML_STATE_FINAL) { bit_and_not(parallel_children, scxml_states[k].ancestors, 2); } else { SET_BIT(k, parallel_children); diff --git a/test/uscxml/automated/ecma/deep-histories2.scxml b/test/uscxml/automated/ecma/deep-histories2.scxml new file mode 100644 index 0000000..e19f029 --- /dev/null +++ b/test/uscxml/automated/ecma/deep-histories2.scxml @@ -0,0 +1,31 @@ +<scxml datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0" /> + </datamodel> + <state id="s0"> + <transition target="pass" cond="Var1 == 2" /> + <transition target="fail" /> + + <history id="h0" type="deep" /> + <state id="s0.0"> + <history id="h1" type="deep" /> + <state id="s0.0.0"> + <onentry> + <assign location="Var1" expr="Var1 + 1" /> + </onentry> + <transition target="s0.0.1" cond="Var1 == 1" /> + </state> + <state id="s0.0.1"> + <transition target="s1" cond="Var1 == 1" /> + </state> + </state> + </state> + <state id="s1"> + <onentry> + <assign location="Var1" expr="Var1 + 1" /> + </onentry> + <transition target="h0" cond="Var1 == 2" /> + </state> + <final id="pass" /> + <final id="fail" /> +</scxml>
\ No newline at end of file diff --git a/test/uscxml/automated/ecma/uncompleted-history.scxml b/test/uscxml/automated/ecma/uncompleted-history.scxml new file mode 100644 index 0000000..f6c3c04 --- /dev/null +++ b/test/uscxml/automated/ecma/uncompleted-history.scxml @@ -0,0 +1,11 @@ +<scxml datamodel="ecmascript" initial="s0.h0"> + <state id="s0"> + <transition target="fail" /> + <history id="s0.h0" type="deep" /> + <state id="s0.0"> + <transition target="pass" /> + </state> + </state> + <final id="pass" /> + <final id="fail" /> +</scxml>
\ No newline at end of file |