File: bug1908493.c

package info (click to toggle)
cc1111 2.9.0-4
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 38,692 kB
  • ctags: 132,262
  • sloc: ansic: 442,650; cpp: 37,006; sh: 10,334; makefile: 5,511; asm: 5,279; yacc: 2,953; lisp: 1,524; perl: 807; awk: 493; python: 468; lex: 447
file content (126 lines) | stat: -rw-r--r-- 3,606 bytes parent folder | download | duplicates (5)
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
/* 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>

#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 */

    }
}

void
testBug (void)
{
    AO_derived.super.state = 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 */
}