[= AutoGen5 Template -*- Mode: Text -*- # AutoGen copyright 1992-2006 Bruce Korb =][= (define event-string "") =][= DEFINE state-table =] /* STATE [= (get "st_ix") =]: [= (. PFX)=]_ST_[= (string-upcase! (get "state")) =] */ { [= (shellf "state=%s" (string-upcase! (get "state"))) =][= FOR event "\n " =][= (set! fmt (shellf "eval echo \\\"\\$FSM_TRANS_${state}_%s%s\\\"" (string-upcase! (get "event")) (if (last-for?) "" ",") )) (set! event-string (if (exist? (get "event")) (get (get "event")) (get "event") )) (sprintf "%-47s /* EVT: %s */" fmt event-string ) =][= ENDFOR =] }[= ENDDEF =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= DEFINE enumerate-transitions =] /* * Enumeration of the valid transition types * Some transition types may be common to several transitions. */ typedef enum { [=(string-upcase! (shellf "sed '$s/,$//;s/^/ %s_TR_/' .fsm.xlist" PFX))=] } te_[=(. pfx)=]_trans; #define [=(. PFX)=]_TRANSITION_CT [= `tct="\`wc -l < .fsm.xlist\`" echo $tct`=] /* * the state transition handling map * This table maps the state enumeration + the event enumeration to * the new state and the transition enumeration code (in that order). * It is indexed by first the current state and then the event code. */ typedef struct [=(. pfx)=]_transition [= (. t-trans) =]; struct [=(. pfx)=]_transition { te_[=(. pfx)=]_state next_state; te_[=(. pfx)=]_trans transition; }; [= IF (exist? "use_ifdef") =] #ifndef DEFINE_FSM extern const [= (. t-trans) =] [=(. pfx)=]_trans_table[ [=(. PFX) =]_STATE_CT ][ [=(. PFX)=]_EVENT_CT ]; extern int [=(. pfx)=]_invalid_transition( te_[=(. pfx)=]_state st, te_[= (. pfx)=]_event evt ); #else [= ELSE =]static [= ENDIF =]const [= (. t-trans) =] [=(. pfx)=]_trans_table[ [=(. PFX) =]_STATE_CT ][ [=(. PFX)=]_EVENT_CT ] = {[= state-table state = init st_ix = "0" =][= FOR state =], [= state-table st_ix = (+ 1 (for-index)) =][= ENDFOR =] };[= IF (exist? "use_ifdef") =][= emit-invalid-msg =] #endif /* DEFINE_FSM */[= ENDIF =][= ENDDEF =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= DEFINE callback-transitions =] /* * This is the prototype for the callback routines. They are to * return the next state. Normally, that should be the value of * the "maybe_next" argument. */ typedef te_[=(. pfx)=]_state ([=(. pfx)=]_callback_t)([= emit-cookie-args =] te_[=(. pfx)=]_state initial, te_[=(. pfx)=]_state maybe_next, te_[=(. pfx)=]_event trans_evt ); static [=(. pfx)=]_callback_t [=(shellf "sed '$s/,$/;/;s/^/ %s_do_/' .fsm.xlist" pfx)=] /* * This declares all the state transition handling routines */ typedef struct transition [= (. t-trans) =]; struct transition {[= (set! fmt (sprintf "\n %%-%ds %%s;" (+ (string-length pfx) 14) )) (sprintf (string-append fmt fmt) (string-append "te_" pfx "_state") "next_state" (string-append pfx "_callback_t*") "trans_proc") =] }; /* * This table maps the state enumeration + the event enumeration to * the new state and the transition enumeration code (in that order). * It is indexed by first the current state and then the event code. */ static const [= (. t-trans) =] [=(. pfx)=]_trans_table[ [=(. PFX) =]_STATE_CT ][ [=(. PFX)=]_EVENT_CT ] = {[= state-table state = init st_ix = "0" =][= FOR state =],[= state-table st_ix = (+ 1 (for-index)) =][= ENDFOR =] };[= ENDDEF =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= DEFINE machine-step =][= (if (=* (get "method") "case") (begin (define trans-name "trans") (define trans-field "transition") (define trans-valu (string-append PFX "_TR_INVALID")) ) (begin (define trans-name "pT ") (define trans-field "trans_proc") (define trans-valu (string-append pfx "_do_invalid")) )) =] if (trans_evt >= [=(. PFX)=]_EV_INVALID) { nxtSt = [=(. PFX)=]_ST_INVALID; [=(. trans-name)=] = [=(. trans-valu)=]; } else { const [= (. t-trans) =]* pTT = [=(. pfx)=]_trans_table[ [=(. pfx)=]_state ] + trans_evt; #ifdef DEBUG firstNext = /* next line */ #endif nxtSt = pTT->next_state; [=(. trans-name)=] = pTT->[=(. trans-field)=]; } #ifdef DEBUG printf( "in state %s(%d) step %s(%d) to %s(%d)\n", [=(. PFX)=]_STATE_NAME( [=(. pfx)=]_state ), [=(. pfx)=]_state, [=(. PFX)=]_EVT_NAME( trans_evt ), trans_evt, [=(. PFX)=]_STATE_NAME( nxtSt ), nxtSt ); #endif[= IF (=* (get "method") "case") =][= run-switch =][= ELSE =][= run-callback =][= ENDIF =] #ifdef DEBUG if (nxtSt != firstNext) printf( "transition code changed destination state to %s(%d)\n", [=(. PFX)=]_STATE_NAME( nxtSt ), nxtSt ); #endif[= IF (not (=* (get "type") "reent")) =] [=(. pfx)=]_state = nxtSt;[= ENDIF =] [= ENDDEF machine-step =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= DEFINE fsm-proc-variables =] #ifdef DEBUG te_[=(. pfx)=]_state firstNext; #endif te_[=(. pfx)=]_state nxtSt;[= IF (=* (get "method") "call") =] [=(. pfx)=]_callback_t* pT;[= ELSE =] te_[=(. pfx)=]_trans trans;[= ENDIF =][= ENDDEF =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= DEFINE make-loop-proc =] /* * Run the FSM. Will return [=(. PFX)=]_ST_DONE or [=(. PFX)=]_ST_INVALID */ [=mode=]te_[=(. pfx)=]_state [=(. pfx)=]_run_fsm([= IF (exist? "cookie") =][= FOR cookie "," =] [=cookie=][= ENDFOR=][= ELSE=] void[=ENDIF=] )[= ENDDEF make-loop-proc =][= DEFINE looping-machine =][= make-loop-proc mode = "" =] { te_[=(. pfx)=]_state [=(. pfx)=]_state = [=(. PFX)=]_ST_INIT; te_[=(. pfx)=]_event trans_evt;[= fsm-proc-variables =] while ([=(. pfx)=]_state < [=(. PFX)=]_ST_INVALID) { [=(extract fsm-source " /* %s == FIND TRANSITION == %s */" "" " trans_evt = GET_NEXT_TRANS();" )=] [= (out-push-new ".fsm.cktbl")=][= machine-step =][= (out-pop) (shell "sed 's/^ / /;s/ / /' .fsm.cktbl") =] } return [=(. pfx)=]_state; }[= ENDDEF =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= DEFINE make-step-proc =] /* * Step the FSM. Returns the resulting state. If the current state is * [=(. PFX)=]_ST_DONE or [=(. PFX)=]_ST_INVALID, it resets to * [=(. PFX)=]_ST_INIT and returns [=(. PFX)=]_ST_INIT. */ [=mode=]te_[=(. pfx)=]_state [=(. pfx)=]_step([= IF (=* (get "type") "reent") =] te_[= (. pfx) =]_state [= (. pfx) =]_state,[= ENDIF =] te_[= (. pfx) =]_event trans_evt[= FOR cookie =], [=cookie=][= ENDFOR=] )[= ENDDEF make-step-proc =][= DEFINE stepping-machine =][= make-step-proc mode = "" =] {[= fsm-proc-variables =] if ((unsigned)[=(. pfx)=]_state >= [=(. PFX)=]_ST_INVALID) {[= IF (=* (get "type") "step") =] [=(. pfx)=]_state = [=(. PFX)=]_ST_INIT;[= ENDIF =] return [=(. PFX)=]_ST_INIT; } [= machine-step =] [=(extract fsm-source " /* %s == FINISH STEP == %s */")=] return nxtSt; }[= ENDDEF =]