summaryrefslogtreecommitdiff
path: root/support/regression/tests/bug1908493.c
blob: f61fb656fc522559306c80ab78de2058ac487fbe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* Bug 1908493
 * Bug test contains code fragments from qpnano framework,
 * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.
 * and released under the GPL
 * See www.quantum-leaps.com/downloads/index.htm#QPN
 */

#include <testfwk.h>

#if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15)

#define Q_REENTRANT __reentrant
#define Q_ASSERT
#define Q_SIG(me_) (((QFsm *)(me_))->evt.sig)
#define int8_t char
#define QEP_MAX_NEST_DEPTH 5

#define QEP_EMPTY_SIG 0

enum QReservedSignals {
  Q_ENTRY_SIG = 1,  /**< signal for coding entry actions */
  Q_EXIT_SIG,       /**< signal for coding exit actions */
  Q_INIT_SIG,       /**< signal for coding nested initial transitions */
  Q_TIMEOUT_SIG,    /**< signal used by time events */
  Q_USER_SIG        /**< first signal that can be used in user applications */
};

typedef int8_t QSignal;
typedef struct QEventTag {
    QSignal sig;
} QEvent;

struct QFsmTag;
struct QHsmTag;

typedef void (*QState) (struct QFsmTag *me);
typedef QState (*QHsmState) (struct QHsmTag *me);

typedef QState QSTATE;

typedef struct QFsmTag {
    QState state;
    QEvent evt;
} QFsm;

typedef struct QHsmTag {
    QHsmState state;
    QEvent evt;
} QHsm;

typedef struct QHsmDerivedTag {
    QHsm super;
    char value;
} QHsmDerived;

QHsmDerived AO_derived;

QSTATE
state_1 (QHsmDerived *me) Q_REENTRANT
{
  if (Q_SIG (me) == Q_INIT_SIG)
    me->value = 3;

  return (QSTATE)0;
}

QSTATE
state_2 (QHsmDerived *me) Q_REENTRANT
{
  if (Q_SIG (me) == Q_USER_SIG)
    return (QSTATE)state_1;

  return (QSTATE)0;
}

void
QHsm_dispatch (QHsm *me) Q_REENTRANT
{
  QHsmState path[QEP_MAX_NEST_DEPTH];
  QHsmState s;
  QHsmState t = me->state;

  path[1] = t;    /* save the current state in case a transition is taken */

  do                               /* process the event hierarchically... */
    {
      s = t;

      /********************************************************************
       *
       *    The call which fails when s is copied from the stack frame
       *
       ********************************************************************/
      t = (QHsmState)((*s) (me));               /* invoke state handler s */

    }
  while (t != (QHsmState)0);

  if (me->evt.sig == (QSignal)0)                     /* transition taken? */
    {
      QHsmState src = s;                  /* the source of the transition */
      int8_t ip = (int8_t)(-1);            /* transition entry path index */

      path[0] = me->state;                          /* save the new state */
      me->state = path[1];                   /* restore the current state */

                    /* exit current state to the transition source src... */
      for (s = path[1]; s != src; )
        {
          Q_SIG (me) = (QSignal)Q_EXIT_SIG;
          t = (QHsmState)(*s) (me);               /* find superstate of s */
          if (t != (QHsmState)0)                 /* exit action unhandled */
            {
              s = t;                            /* t points to superstate */
            }
          else                                     /* exit action handled */
            {
              Q_SIG (me) = (QSignal)QEP_EMPTY_SIG;
              s = (QHsmState)(*s) (me);           /* find superstate of s */
            }
        }

        t = path[0];                            /* target of the transition */
    }
}
#endif

void
testBug (void)
{
#if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15)
    AO_derived.super.state = (QHsmState)state_2;
    AO_derived.super.evt.sig = 2;

    QHsm_dispatch ((QHsm *)&AO_derived);

    ASSERT (1);     /*if we don't get here the regression test will timeout */
#endif
}