1 /* Bug 1908493 2 * Bug test contains code fragments from qpnano framework, 3 * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved. 4 * and released under the GPL 5 * See www.quantum-leaps.com/downloads/index.htm#QPN 6 */ 7 8 #include <testfwk.h> 9 10 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) 11 12 #define Q_REENTRANT __reentrant 13 #define Q_ASSERT 14 #define Q_SIG(me_) (((QFsm *)(me_))->evt.sig) 15 #define int8_t char 16 #define QEP_MAX_NEST_DEPTH 5 17 18 #define QEP_EMPTY_SIG 0 19 20 enum QReservedSignals { 21 Q_ENTRY_SIG = 1, /**< signal for coding entry actions */ 22 Q_EXIT_SIG, /**< signal for coding exit actions */ 23 Q_INIT_SIG, /**< signal for coding nested initial transitions */ 24 Q_TIMEOUT_SIG, /**< signal used by time events */ 25 Q_USER_SIG /**< first signal that can be used in user applications */ 26 }; 27 28 typedef int8_t QSignal; 29 typedef struct QEventTag { 30 QSignal sig; 31 } QEvent; 32 33 struct QFsmTag; 34 struct QHsmTag; 35 36 typedef void (*QState) (struct QFsmTag *me); 37 typedef QState (*QHsmState) (struct QHsmTag *me); 38 39 typedef QState QSTATE; 40 41 typedef struct QFsmTag { 42 QState state; 43 QEvent evt; 44 } QFsm; 45 46 typedef struct QHsmTag { 47 QHsmState state; 48 QEvent evt; 49 } QHsm; 50 51 typedef struct QHsmDerivedTag { 52 QHsm super; 53 char value; 54 } QHsmDerived; 55 56 QHsmDerived AO_derived; 57 58 QSTATE state_1(QHsmDerived * me)59state_1 (QHsmDerived *me) Q_REENTRANT 60 { 61 if (Q_SIG (me) == Q_INIT_SIG) 62 me->value = 3; 63 64 return (QSTATE)0; 65 } 66 67 QSTATE state_2(QHsmDerived * me)68state_2 (QHsmDerived *me) Q_REENTRANT 69 { 70 if (Q_SIG (me) == Q_USER_SIG) 71 return (QSTATE)state_1; 72 73 return (QSTATE)0; 74 } 75 76 void QHsm_dispatch(QHsm * me)77QHsm_dispatch (QHsm *me) Q_REENTRANT 78 { 79 QHsmState path[QEP_MAX_NEST_DEPTH]; 80 QHsmState s; 81 QHsmState t = me->state; 82 83 path[1] = t; /* save the current state in case a transition is taken */ 84 85 do /* process the event hierarchically... */ 86 { 87 s = t; 88 89 /******************************************************************** 90 * 91 * The call which fails when s is copied from the stack frame 92 * 93 ********************************************************************/ 94 t = (QHsmState)((*s) (me)); /* invoke state handler s */ 95 96 } 97 while (t != (QHsmState)0); 98 99 if (me->evt.sig == (QSignal)0) /* transition taken? */ 100 { 101 QHsmState src = s; /* the source of the transition */ 102 int8_t ip = (int8_t)(-1); /* transition entry path index */ 103 104 path[0] = me->state; /* save the new state */ 105 me->state = path[1]; /* restore the current state */ 106 107 /* exit current state to the transition source src... */ 108 for (s = path[1]; s != src; ) 109 { 110 Q_SIG (me) = (QSignal)Q_EXIT_SIG; 111 t = (QHsmState)(*s) (me); /* find superstate of s */ 112 if (t != (QHsmState)0) /* exit action unhandled */ 113 { 114 s = t; /* t points to superstate */ 115 } 116 else /* exit action handled */ 117 { 118 Q_SIG (me) = (QSignal)QEP_EMPTY_SIG; 119 s = (QHsmState)(*s) (me); /* find superstate of s */ 120 } 121 } 122 123 t = path[0]; /* target of the transition */ 124 } 125 } 126 #endif 127 128 void testBug(void)129testBug (void) 130 { 131 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) 132 AO_derived.super.state = (QHsmState)state_2; 133 AO_derived.super.evt.sig = 2; 134 135 QHsm_dispatch ((QHsm *)&AO_derived); 136 137 ASSERT (1); /*if we don't get here the regression test will timeout */ 138 #endif 139 } 140