/*..........................................................................*/ void QFsm_dispatch(QFsm *me, QEvent const *e) { QStateHandler s = me->state; /* save the current state */ QS_INT_LOCK_KEY_ QState r = (*s)(me, e); /* call the event handler */ if (r == Q_RET_TRAN) { /* transition taken? */ QS_BEGIN_(QS_QEP_TRAN, QS_smObj_, me) QS_TIME_(); /* time stamp */ QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(s); /* the source of the transition */ QS_FUN_(me->state); /* the new active state */ QS_END_() (void)QEP_TRIG_(s, Q_EXIT_SIG); /* exit the source */ (void)QEP_TRIG_(me->state, Q_ENTRY_SIG); /* enter the target */ } else { /* transition not taken */ #ifdef Q_SPY if (r == Q_RET_HANDLED) { QS_BEGIN_(QS_QEP_INTERN_TRAN, QS_smObj_, me) QS_TIME_(); /* time stamp */ QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(s); /* the state that handled the event */ QS_END_() } else {
/*..........................................................................*/ void QHsm_init(QHsm *me, QEvent const *e) { QHsmState s; /* this state machine must be initialized with QHsm_ctor_() */ Q_REQUIRE(((QFsm *)me)->state__.fsm != (QState)0); s = &QHsm_top; /* an HSM starts in the top state */ /* trigger the initial transition */ (*((QFsm *)me)->state__.fsm)((QFsm *)me, e); do { /* drill into the target... */ QHsmState path[QEP_MAX_NEST_DEPTH_]; int8_t ip = (int8_t)0; /* transition entry path index */ QHsmState t = ((QFsm *)me)->state__.hsm; QS_BEGIN_(QS_QEP_STATE_INIT, QS_smObj_, me); QS_OBJ_(me); /* this state machine object */ QS_FUN_(s); /* the source state */ QS_FUN_(((QFsm *)me)->state__.hsm); /* the target */ QS_END_(); path[0] = t; for (t = QEP_TRIG_(t, QEP_EMPTY_SIG_); t != s; t = QEP_TRIG_(t, QEP_EMPTY_SIG_)) { path[++ip] = t; } /* entry path must not overflow */ Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); do { /* retrace the entry path in reverse (desired) order... */ /* enter path[ip] */ if (QEP_TRIG_(path[ip], Q_ENTRY_SIG) == (QHsmState)0) { QS_BEGIN_(QS_QEP_STATE_ENTRY, QS_smObj_, me); QS_OBJ_(me); /* this state machine object */ QS_FUN_(path[ip]); /* the entered state */ QS_END_(); } } while (--ip >= (int8_t)0); s = ((QFsm *)me)->state__.hsm; } while (QEP_TRIG_(s, Q_INIT_SIG) == (QHsmState)0); QS_BEGIN_(QS_QEP_INIT_TRAN, QS_smObj_, me); QS_TIME_(); /* time stamp */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(((QFsm *)me)->state__.hsm); /* the new active state */ QS_END_(); }
/*..........................................................................*/ void QHsm_init(QHsm * const me, QEvt const * const e) { QStateHandler t = me->state.fun; QS_CRIT_STAT_ Q_REQUIRE((me->vptr != (QMsmVtbl const *)0) /* ctor must be executed */ && (me->temp.fun != Q_STATE_CAST(0)) /* ctor must be executed */ && (t == Q_STATE_CAST(&QHsm_top))); /*initial tran. NOT taken */ /* the top-most initial transition must be taken */ Q_ALLEGE((*me->temp.fun)(me, e) == (QState)Q_RET_TRAN); do { /* drill into the target... */ QStateHandler path[QEP_MAX_NEST_DEPTH_]; int_t ip = (int_t)0; /* transition entry path index */ QS_BEGIN_(QS_QEP_STATE_INIT, QS_priv_.smObjFilter, me) QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the source state */ QS_FUN_(me->temp.fun); /* the target of the initial transition */ QS_END_() path[0] = me->temp.fun; (void)QEP_TRIG_(me->temp.fun, QEP_EMPTY_SIG_); while (me->temp.fun != t) { ++ip; path[ip] = me->temp.fun; (void)QEP_TRIG_(me->temp.fun, QEP_EMPTY_SIG_); } me->temp.fun = path[0]; /* entry path must not overflow */ Q_ASSERT(ip < (int_t)QEP_MAX_NEST_DEPTH_); do { /* retrace the entry path in reverse (desired) order... */ QEP_ENTER_(path[ip]); /* enter path[ip] */ --ip; } while (ip >= (int_t)0); t = path[0]; /* current state becomes the new source */ } while (QEP_TRIG_(t, Q_INIT_SIG) == (QState)Q_RET_TRAN); QS_BEGIN_(QS_QEP_INIT_TRAN, QS_priv_.smObjFilter, me) QS_TIME_(); /* time stamp */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the new active state */ QS_END_() me->state.fun = t; /* change the current active state */ me->temp.fun = t; /* mark the configuration as stable */ }
/*..........................................................................*/ void QFsm_init_(QFsm * const me, QEvt const * const e) { QS_CRIT_STAT_ Q_REQUIRE((me->vptr != (QMsmVtbl const *)0) /* ctor must be executed */ && (me->temp.fun != Q_STATE_CAST(0)) /* ctor must be executed */ && (me->state.fun == Q_STATE_CAST(0)));/*init tran. NOT taken */ QS_BEGIN_(QS_QEP_STATE_INIT, QS_priv_.smObjFilter, me) QS_OBJ_(me); /* this state machine object */ QS_FUN_(Q_STATE_CAST(0)); /* source state (not defined for a FSM) */ QS_FUN_(me->temp.fun); /* the target of the transition */ QS_END_() /* execute the top-most initial transition */ Q_ALLEGE((*me->temp.fun)(me, e) == (QState)Q_RET_TRAN);/* must be taken */ (void)QEP_TRIG_(me->temp.fun, Q_ENTRY_SIG); /* enter the target */ me->state.fun = me->temp.fun; /* record the new active state */ QS_BEGIN_(QS_QEP_INIT_TRAN, QS_priv_.smObjFilter, me) QS_TIME_(); /* time stamp */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(me->state.fun); /* the new active state */ QS_END_() }
//............................................................................ void QHsm::init(QEvent const *e) { QStateHandler t; QS_INT_LOCK_KEY_ // the top-most initial transition must be taken Q_ALLEGE((*m_state)(this, e) == Q_RET_TRAN); t = (QStateHandler)&QHsm::top; // HSM starts in the top state do { // drill into the target... QStateHandler path[QEP_MAX_NEST_DEPTH_]; int8_t ip = (int8_t)0; // transition entry path index QS_BEGIN_(QS_QEP_STATE_INIT, QS::smObj_, this) QS_OBJ_(this); // this state machine object QS_FUN_(t); // the source state QS_FUN_(m_state); // the target of the initial transition QS_END_() path[0] = m_state; (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_); while (m_state != t) { ++ip; path[ip] = m_state; (void)QEP_TRIG_(m_state, QEP_EMPTY_SIG_); } m_state = path[0]; // entry path must not overflow Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); do { // retrace the entry path in reverse (desired) order... QEP_ENTER_(path[ip]); // enter path[ip] --ip; } while (ip >= (int8_t)0); t = path[0]; // current state becomes the new source } while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN); m_state = t; QS_BEGIN_(QS_QEP_INIT_TRAN, QS::smObj_, this) QS_TIME_(); // time stamp QS_OBJ_(this); // this state machine object QS_FUN_(m_state); // the new active state QS_END_() }
/** * \description * Dispatches an event for processing to a hierarchical state machine (HSM). * The processing of an event represents one run-to-completion (RTC) step. * * \arguments * \arg[in,out] \c me pointer (see \ref derivation) * \arg[in] \c e pointer to the event to be dispatched to the HSM * * \note * This function should be called only via the virtual table (see * QMSM_DISPATCH()) and should NOT be called directly in the applications. */ void QHsm_dispatch_(QHsm * const me, QEvt const * const e) { QStateHandler t = me->state.fun; QStateHandler s; QState r; QS_CRIT_STAT_ /** \pre the state configuration must be stable */ Q_REQUIRE_ID(100, t == me->temp.fun); QS_BEGIN_(QS_QEP_DISPATCH, QS_priv_.smObjFilter, me) QS_TIME_(); /* time stamp */ QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the current state */ QS_END_() /* process the event hierarchically... */ do { s = me->temp.fun; r = (*s)(me, e); /* invoke state handler s */ if (r == (QState)Q_RET_UNHANDLED) { /* unhandled due to a guard? */ QS_BEGIN_(QS_QEP_UNHANDLED, QS_priv_.smObjFilter, me) QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(s); /* the current state */ QS_END_() r = QEP_TRIG_(s, QEP_EMPTY_SIG_); /* find superstate of s */ } } while (r == (QState)Q_RET_SUPER); /* transition taken? */ if (r >= (QState)Q_RET_TRAN) { QStateHandler path[QHSM_MAX_NEST_DEPTH_]; int_fast8_t ip; path[0] = me->temp.fun; /* save the target of the transition */ path[1] = t; path[2] = s; /* exit current state to transition source s... */ for (; t != s; t = me->temp.fun) { if (QEP_TRIG_(t, Q_EXIT_SIG) == (QState)Q_RET_HANDLED) { QS_BEGIN_(QS_QEP_STATE_EXIT, QS_priv_.smObjFilter, me) QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the exited state */ QS_END_() (void)QEP_TRIG_(t, QEP_EMPTY_SIG_); /* find superstate of t */ } } ip = QHsm_tran_(me, path); #ifdef Q_SPY if (r == (QState)Q_RET_TRAN_HIST) { QS_BEGIN_(QS_QEP_TRAN_HIST, QS_priv_.smObjFilter, me) QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the source of the transition */ QS_FUN_(path[0]);/* the target of the tran. to history */ QS_END_() }
/*..........................................................................*/ void QHsm_dispatch(QHsm *me, QEvent const *e) { QStateHandler path[QEP_MAX_NEST_DEPTH_]; QStateHandler s; QStateHandler t; QState r; QS_INT_LOCK_KEY_ t = me->state; /* save the current state */ QS_BEGIN_(QS_QEP_DISPATCH, QS_smObj_, me) QS_TIME_(); /* time stamp */ QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the current state */ QS_END_() do { /* process the event hierarchically... */ s = me->state; r = (*s)(me, e); /* invoke state handler s */ } while (r == Q_RET_SUPER); if (r == Q_RET_TRAN) { /* transition taken? */ #ifdef Q_SPY QStateHandler src = s; /* save the transition source for tracing */ #endif int8_t ip = (int8_t)(-1); /* transition entry path index */ int8_t iq; /* helper transition entry path index */ path[0] = me->state; /* save the target of the transition */ path[1] = t; while (t != s) { /* exit current state to transition source s... */ if (QEP_TRIG_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {/*exit handled? */ QS_BEGIN_(QS_QEP_STATE_EXIT, QS_smObj_, me) QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the exited state */ QS_END_() (void)QEP_TRIG_(t, QEP_EMPTY_SIG_); /* find superstate of t */ } t = me->state; /* me->state holds the superstate */ } t = path[0]; /* target of the transition */ if (s == t) { /* (a) check source==target (transition to self) */ QEP_EXIT_(s) /* exit the source */ ip = (int8_t)0; /* enter the target */ } else { (void)QEP_TRIG_(t, QEP_EMPTY_SIG_); /* superstate of target */ t = me->state; if (s == t) { /* (b) check source==target->super */ ip = (int8_t)0; /* enter the target */ } else { (void)QEP_TRIG_(s, QEP_EMPTY_SIG_); /* superstate of src */ /* (c) check source->super==target->super */ if (me->state == t) { QEP_EXIT_(s) /* exit the source */ ip = (int8_t)0; /* enter the target */ } else { /* (d) check source->super==target */ if (me->state == path[0]) { QEP_EXIT_(s) /* exit the source */ } else { /* (e) check rest of source==target->super->super.. * and store the entry path along the way */ iq = (int8_t)0; /* indicate that LCA not found */ ip = (int8_t)1; /* enter target and its superstate */ path[1] = t; /* save the superstate of target */ t = me->state; /* save source->super */ /* find target->super->super */ r = QEP_TRIG_(path[1], QEP_EMPTY_SIG_); while (r == Q_RET_SUPER) { ++ip; path[ip] = me->state; /* store the entry path */ if (me->state == s) { /* is it the source? */ iq = (int8_t)1; /* indicate that LCA found */ /* entry path must not overflow */ Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); --ip; /* do not enter the source */ r = Q_RET_HANDLED; /* terminate the loop */ } else { /* it is not the source, keep going up */ r = QEP_TRIG_(me->state, QEP_EMPTY_SIG_); } } if (iq == (int8_t)0) { /* the LCA not found yet? */ /* entry path must not overflow */ Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); QEP_EXIT_(s) /* exit the source */ /* (f) check the rest of source->super * == target->super->super... */ iq = ip; r = Q_RET_IGNORED; /* indicate LCA NOT found */ do { if (t == path[iq]) { /* is this the LCA? */ r = Q_RET_HANDLED;/* indicate LCA found */ ip = (int8_t)(iq - 1);/*do not enter LCA*/ iq = (int8_t)(-1);/* terminate the loop */ } else { --iq; /* try lower superstate of target */ } } while (iq >= (int8_t)0); if (r != Q_RET_HANDLED) { /* LCA not found yet? */ /* (g) check each source->super->... * for each target->super... */ r = Q_RET_IGNORED; /* keep looping */ do { /* exit t unhandled? */ if (QEP_TRIG_(t, Q_EXIT_SIG) == Q_RET_HANDLED) { QS_BEGIN_(QS_QEP_STATE_EXIT, QS_smObj_, me) QS_OBJ_(me); QS_FUN_(t); QS_END_() (void)QEP_TRIG_(t, QEP_EMPTY_SIG_); } t = me->state; /* set to super of t */ iq = ip; do { if (t == path[iq]) {/* is this LCA? */ /* do not enter LCA */ ip = (int8_t)(iq - 1); iq = (int8_t)(-1);/*break inner */ r = Q_RET_HANDLED;/*break outer */ } else { --iq; } } while (iq >= (int8_t)0); } while (r != Q_RET_HANDLED); } } } } } } /* retrace the entry path in reverse (desired) order... */ for (; ip >= (int8_t)0; --ip) { QEP_ENTER_(path[ip]) /* enter path[ip] */ } t = path[0]; /* stick the target into register */ me->state = t; /* update the current state */ /* drill into the target hierarchy... */ while (QEP_TRIG_(t, Q_INIT_SIG) == Q_RET_TRAN) { QS_BEGIN_(QS_QEP_STATE_INIT, QS_smObj_, me) QS_OBJ_(me); /* this state machine object */ QS_FUN_(t); /* the source (pseudo)state */ QS_FUN_(me->state); /* the target of the transition */ QS_END_() ip = (int8_t)0; path[0] = me->state; (void)QEP_TRIG_(me->state, QEP_EMPTY_SIG_); /* find superstate */ while (me->state != t) { ++ip; path[ip] = me->state; (void)QEP_TRIG_(me->state, QEP_EMPTY_SIG_);/*find superstate*/ } me->state = path[0]; /* entry path must not overflow */ Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); do { /* retrace the entry path in reverse (correct) order... */ QEP_ENTER_(path[ip]) /* enter path[ip] */ --ip; } while (ip >= (int8_t)0); t = path[0]; } QS_BEGIN_(QS_QEP_TRAN, QS_smObj_, me) QS_TIME_(); /* time stamp */ QS_SIG_(e->sig); /* the signal of the event */ QS_OBJ_(me); /* this state machine object */ QS_FUN_(src); /* the source of the transition */ QS_FUN_(t); /* the new active state */ QS_END_() }
/*..........................................................................*/ void QHsm_dispatch(QHsm *me, QEvent const *e) { QHsmState s; QHsmState t = ((QFsm *)me)->state__.hsm; QHsmState path[QEP_MAX_NEST_DEPTH_]; path[2] = t; /* save the current state in case a transition is taken */ do { /* process the event hierarchically... */ s = t; t = (QHsmState)((*s)(me, e)); /* invoke state handler s */ } while (t != (QHsmState)0); if (((QFsm *)me)->tran__ != Q_TRAN_NONE_TYPE) { /* transition taken? */ struct QTran_ *stran; if ((((QFsm *)me)->tran__ & Q_TRAN_STA_TYPE) != 0) {/* static tran? */ stran = ((QFsm *)me)->state__.tran; } else { path[0] = ((QFsm *)me)->state__.hsm; /* save the new state */ stran = (struct QTran_ *)0; } ((QFsm *)me)->state__.hsm = path[2]; /* restore current state */ path[1] = s; /* save the transition source */ /* exit current state to the transition source path[1]... */ for (s = path[2]; s != path[1]; ) { t = QEP_TRIG_(s, Q_EXIT_SIG); if (t != (QHsmState)0) { /* exit action unhandled */ s = t; /* t points to superstate */ } else { /* exit action handled */ QS_BEGIN_(QS_QEP_STATE_EXIT, QS_smObj_, me); QS_OBJ_(me); /* this state machine object */ QS_FUN_(s); /* the exited state */ QS_END_(); s = QEP_TRIG_(s, QEP_EMPTY_SIG_);/* find out the superstate */ } } if (stran != (struct QTran_ *)0) { /* static transition? */ uint16_t a = (uint16_t)stran->actions[0]; if (a != (uint16_t)0) { /* transition initialized? */ QHsmState const *c = stran->chain; for (a = (uint16_t)((uint16_t)(a | (stran->actions[1] << 8)) >> 1); a != (uint16_t)0; a >>= 2) { uint8_t sig = (uint8_t)(a & 0x3); (void)(*(*c))(me, &QEP_reservedEvt_[sig]); QS_BEGIN_(sig + (uint8_t)QS_QEP_STATE_EMPTY, QS_smObj_, me); QS_OBJ_(me); /* this state machine object */ QS_FUN_(*c); /* entered/exited/initialized state */ if (sig == (QSignal)Q_INIT_SIG) { QS_FUN_(((QFsm *)me)->state__.hsm); /* target */ } QS_END_(); ++c; /* advance in the chain of the stored actions */ } ((QFsm *)me)->state__.hsm = *c; /* set the new state */ } else { /* the static transition object not initialized yet */
/*..........................................................................*/ void QHsm_execTran(QHsm *me, QHsmState path[], struct QTran_ *tran) { QHsmState s; QHsmState t = path[0]; /* target of the transition */ QHsmState const src = path[1]; /* source of the transition */ uint16_t actions = (uint16_t)0; /* actions bitmask for static tran. */ uint8_t ic = (uint8_t)0; /* static-transition chain index */ int8_t ip = (int8_t)(-1); /* transition entry path index */ int8_t iq; /* helper transition entry path index */ if (src == t) { /* (a) check source == target (transition to self) */ QEP_EXIT_AND_REC_(src); /* exit the source */ ++ip; /* enter the target */ } else { t = QEP_TRIG_(t, QEP_EMPTY_SIG_);/* put superstate of target into t */ if (src == t) { /* (b) check source == target->super */ ++ip; /* enter the target */ } else { s = QEP_TRIG_(src, QEP_EMPTY_SIG_);/*superstate of source into s*/ if (s == t) { /* (c) check source->super == target->super */ QEP_EXIT_AND_REC_(src); /* exit the source */ ++ip; /* enter the target */ } else { if (s == path[0]) { /* (d) check source->super == target */ QEP_EXIT_AND_REC_(src); /* exit the source */ } else { /* (e) check rest of source == target->super->super... * and store the entry path along the way */ iq = (int8_t)0; /* indicate that LCA not found */ ++ip; /* enter the target */ path[++ip] = t; /* enter the superstate of target */ t = QEP_TRIG_(t, QEP_EMPTY_SIG_); while (t != (QHsmState)0) { path[++ip] = t; /* store the entry path */ if (t == src) { /* is it the source? */ iq = (int8_t)1; /* indicate that the LCA found */ /* entry path must not overflow */ Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); --ip; /* do not enter the source */ t = (QHsmState)0; /* terminate the loop */ } else { /* it is not the source, keep going up */ t = QEP_TRIG_(t, QEP_EMPTY_SIG_); } } if (iq == (int8_t)0) { /* the LCA not found yet? */ /* entry path must not overflow */ Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); QEP_EXIT_AND_REC_(src); /* exit source */ /* (f) check the rest of source->super * == target->super->super... */ iq = ip; do { if (s == path[iq]) { /* is this the LCA? */ t = s; /* indicate that the LCA is found */ ip = (int8_t)(iq - 1); /* do not enter LCA */ iq = (int8_t)(-1); /* terminate the loop */ } else { --iq; /* try lower superstate of target */ } } while (iq >= (int8_t)0); if (t == (QHsmState)0) { /* the LCA not found yet? */ /* (g) check each source->super->... * for each target->super... */ do { t = QEP_TRIG_(s, Q_EXIT_SIG); /* exit s */ if (t != (QHsmState)0) { /* exit unhandled */ s = t; /* t points to superstate of s */ } else { /* exit action handled */ QS_BEGIN_(QS_QEP_STATE_EXIT, QS_smObj_, me); QS_OBJ_(me); QS_FUN_(s); QS_END_(); if (tran != (struct QTran_ *)0) { QEP_REC_(s, Q_EXIT_SIG); } s = QEP_TRIG_(s, QEP_EMPTY_SIG_); } iq = ip; do { if (s == path[iq]) {/* is this the LCA? */ /* do not enter the LCA */ ip = (int8_t)(iq - 1); iq = (int8_t)(-1);/*break inner loop*/ s = (QHsmState)0; /* and outer loop */ } else { --iq; } } while (iq >= (int8_t)0); } while (s != (QHsmState)0); } } } } } } /* retrace the entry path in reverse (desired) order... */ for (; ip >= (int8_t)0; --ip) { QEP_ENTER_AND_REC_(path[ip]); /* enter path[ip] */ } s = path[0]; /* stick the target into register */ ((QFsm *)me)->state__.hsm = s; /* update the current state */ while (QEP_TRIG_(s, Q_INIT_SIG) == (QHsmState)0) { /* drill into target */ t = ((QFsm *)me)->state__.hsm; QS_BEGIN_(QS_QEP_STATE_INIT, QS_smObj_, me); QS_OBJ_(me); /* this state machine object */ QS_FUN_(s); /* the source (pseudo)state */ QS_FUN_(t); /* the target of the transition */ QS_END_(); if (tran != (struct QTran_ *)0) { /* static tranistion? */ QEP_REC_(s, Q_INIT_SIG); } /* store the entry path to s */ path[0] = t; ip = (int8_t)0; for (t = QEP_TRIG_(t, QEP_EMPTY_SIG_); t != s; t = QEP_TRIG_(t, QEP_EMPTY_SIG_)) { path[++ip] = t; } /* entry path must not overflow */ Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_); do { /* retrace the entry path in reverse (correct) order... */ QEP_ENTER_AND_REC_(path[ip]); /* enter path[ip] */ --ip; } while (ip >= (int8_t)0); s = ((QFsm *)me)->state__.hsm; } if (tran != (struct QTran_ *)0) { /* static transition? */ /* transition chain must not overflow */ Q_ENSURE(ic < (uint8_t)Q_DIM(tran->chain)); tran->chain[ic] = s; /* store the ultimate target of the transition */ actions = (uint16_t)(actions >> (15 - (ic << 1))); tran->actions[1] = (uint8_t)(actions >> 8); tran->actions[0] = (uint8_t)(actions | 0x1); }