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
10 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // pdk needs function pointer to be reentrant even for a single argument
12 #define Q_REENTRANT __reentrant
14 #define Q_SIG(me_) (((QFsm *)(me_))->evt.sig)
16 #define QEP_MAX_NEST_DEPTH 5
18 #define QEP_EMPTY_SIG 0
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 */
28 typedef int8_t QSignal
;
29 typedef struct QEventTag
{
36 typedef void (*QState
) (struct QFsmTag
*me
);
37 typedef QState (*QHsmState
) (struct QHsmTag
*me
);
39 typedef QState QSTATE
;
41 typedef struct QFsmTag
{
46 typedef struct QHsmTag
{
51 typedef struct QHsmDerivedTag
{
56 QHsmDerived AO_derived
;
59 state_1 (QHsmDerived
*me
) Q_REENTRANT
61 if (Q_SIG (me
) == Q_INIT_SIG
)
68 state_2 (QHsmDerived
*me
) Q_REENTRANT
70 if (Q_SIG (me
) == Q_USER_SIG
)
71 return (QSTATE
)state_1
;
77 QHsm_dispatch (QHsm
*me
) Q_REENTRANT
79 QHsmState path
[QEP_MAX_NEST_DEPTH
];
81 QHsmState t
= me
->state
;
83 path
[1] = t
; /* save the current state in case a transition is taken */
85 do /* process the event hierarchically... */
89 /********************************************************************
91 * The call which fails when s is copied from the stack frame
93 ********************************************************************/
94 t
= (QHsmState
)((*s
) (me
)); /* invoke state handler s */
97 while (t
!= (QHsmState
)0);
99 if (me
->evt
.sig
== (QSignal
)0) /* transition taken? */
101 QHsmState src
= s
; /* the source of the transition */
102 int8_t ip
= (int8_t)(-1); /* transition entry path index */
104 path
[0] = me
->state
; /* save the new state */
105 me
->state
= path
[1]; /* restore the current state */
107 /* exit current state to the transition source src... */
108 for (s
= path
[1]; s
!= src
; )
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 */
114 s
= t
; /* t points to superstate */
116 else /* exit action handled */
118 Q_SIG (me
) = (QSignal
)QEP_EMPTY_SIG
;
119 s
= (QHsmState
)(*s
) (me
); /* find superstate of s */
123 t
= path
[0]; /* target of the transition */
131 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15)
132 AO_derived
.super
.state
= (QHsmState
)state_2
;
133 AO_derived
.super
.evt
.sig
= 2;
135 QHsm_dispatch ((QHsm
*)&AO_derived
);
137 ASSERT (1); /*if we don't get here the regression test will timeout */