Pick three bugfixes from next branch to trunk for inclusion in 4.5.0 RC2, as discusse...
[sdcc.git] / sdcc / support / regression / tests / bug1908493.c
blob94d4678f11305bd6242bc4b599e2eb02b9841250
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 */
8 #include <testfwk.h>
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
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
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 {
30 QSignal sig;
31 } QEvent;
33 struct QFsmTag;
34 struct QHsmTag;
36 typedef void (*QState) (struct QFsmTag *me);
37 typedef QState (*QHsmState) (struct QHsmTag *me);
39 typedef QState QSTATE;
41 typedef struct QFsmTag {
42 QState state;
43 QEvent evt;
44 } QFsm;
46 typedef struct QHsmTag {
47 QHsmState state;
48 QEvent evt;
49 } QHsm;
51 typedef struct QHsmDerivedTag {
52 QHsm super;
53 char value;
54 } QHsmDerived;
56 QHsmDerived AO_derived;
58 QSTATE
59 state_1 (QHsmDerived *me) Q_REENTRANT
61 if (Q_SIG (me) == Q_INIT_SIG)
62 me->value = 3;
64 return (QSTATE)0;
67 QSTATE
68 state_2 (QHsmDerived *me) Q_REENTRANT
70 if (Q_SIG (me) == Q_USER_SIG)
71 return (QSTATE)state_1;
73 return (QSTATE)0;
76 void
77 QHsm_dispatch (QHsm *me) Q_REENTRANT
79 QHsmState path[QEP_MAX_NEST_DEPTH];
80 QHsmState s;
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... */
87 s = t;
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 */
126 #endif
128 void
129 testBug (void)
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 */
138 #endif