File: C:/Ruby27-x64/msys64/usr/share/autogen/fsm-trans.tlib
[= AutoGen5 Template -*- Mode: Text -*-
## This file is part of AutoGen.
## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved
##
## AutoGen is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by the
## Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## AutoGen is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
## See the GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along
## with this program. If not, see <http://www.gnu.org/licenses/>.
=][=
(make-tmp-dir)
(define get-up (lambda (nm)
(string-upcase! (string->c-name! (get nm))) ))
(define get-down (lambda (nm)
(string-downcase! (string->c-name! (get nm))) ))
(define stack-up (lambda (nm)
(string-upcase! (string->c-name! (join "\n" (stack nm)))) ))
(define event-string "") =][=
DEFINE state-table =]
/* STATE [= (get "st_ix") =]: [=
(define STATE-NAME (get-up "state"))
(shellf "state=%s" STATE-NAME)
(string-append PFX "_ST_" STATE-NAME) =] */
{ [=
FOR event "\n " =][=
(set! event-string (get-up "event"))
(set! fmt (shellf "echo ${FSM_TRANS_%s_%s}%s"
STATE-NAME event-string (if (last-for?) "" ",") ))
(if (exist? event-string) (set! event-string (get event-string)))
(sprintf "%-47s /* EVT: %s */" fmt event-string ) =][=
ENDFOR
=]
}[=
ENDDEF state-table
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
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_/' ${tmp_dir}/xlist" PFX))=]
} te_[=(. pfx)=]_trans;
#define [=(. PFX)=]_TRANSITION_CT [=
`tct="\`wc -l < ${tmp_dir}/xlist\`"
echo $tct`=]
/**
* State transition handling map. Map the state enumeration and 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 enumerate-transitions
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
DEFINE callback-transitions
=]
/**
* Callback routine prototype. They 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_/' ${tmp_dir}/xlist" pfx)=]
/**
* Declare 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") =]
};
/**
* State transition maps. Map the enumeration and 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 callback-transitions
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
DEFINE machine-step =][=
(define trans-name "trans")
(define trans-field "transition")
(define trans-valu (string-append PFX "_TR_INVALID"))
(if (not (=* (get "method") "case")) (begin
(set! trans-name "pT ")
(set! trans-field "trans_proc")
(set! trans-valu (string-append pfx "_do_invalid"))
) )
=]
#ifndef __COVERITY__
if (trans_evt >= [=(. PFX)=]_EV_INVALID) {
nxtSt = [=(. PFX)=]_ST_INVALID;
[=(. trans-name)=] = [=(. trans-valu)=];
} else
#endif /* __COVERITY__ */
{
const [= (. t-trans) =] * ttbl =
[=(. pfx)=]_trans_table[ [=(. pfx)=]_state ] + trans_evt;
[= IF (exist? "debug-flag") \=]
#ifdef [= (get "debug-flag") =]
firstNext = /* next line */
#endif /* [= debug-flag =] */
[= ENDIF \=]
nxtSt = ttbl->next_state;
[=(. trans-name)=] = ttbl->[=(. trans-field)=];
}
[= IF (exist? "debug-flag") \=]
#ifdef [= (get "debug-flag") =]
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 /* [= debug-flag =] */
[= ENDIF \=][=
IF (not (=* (get "method") "case")) =][=
INVOKE run-callback =][=
ELIF (exist? "handler-file") =]
#define FSM_SWITCH_CODE
#include "[= handler-file =]"
#undef FSM_SWITCH_CODE[=
ELSE =][=
INVOKE run-switch =][=
ENDIF
=]
[= IF (exist? "debug-flag") \=]
#ifdef [= (get "debug-flag") =]
if (nxtSt != firstNext)
printf( "transition code changed destination state to %s(%d)\n",
[=(. PFX)=]_STATE_NAME( nxtSt ), nxtSt );
#endif /* [= debug-flag =] */
[= ENDIF \=][=
IF (not (=* (get "type") "reent")) =]
[=(. pfx)=]_state = nxtSt;[=
ENDIF =]
[=
ENDDEF machine-step
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
DEFINE fsm-proc-variables
=]
[= IF (exist? "debug-flag") \=]
#ifdef [= (get "debug-flag") =]
te_[=(. pfx)=]_state firstNext;
#endif
[= ENDIF \=]
te_[=(. pfx)=]_state nxtSt;[=
IF (=* (get "method") "call") =]
[=(. pfx)=]_callback_t * pT;[=
ELSE =]
te_[=(. pfx)=]_trans trans;[=
ENDIF =][=
ENDDEF fsm-proc-variables
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
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
=][= INVOKE make-loop-proc mode = "" =]
{
te_[=(. pfx)=]_state [=(. pfx)=]_state = [=(. PFX)=]_ST_INIT;
te_[=(. pfx)=]_event trans_evt;[=
INVOKE fsm-proc-variables =][=
IF (exist? "cookie") =]
[= (shell (string-append
"cookies='" (stack-join "\n" "cookie") "'
echo \"$cookies\" | \
sed -e 's/^/ /' \
-e 's@\\([a-zA-Z0-9_]*\\)*$@saved_\\1 = \\1;@'
echo \"$cookies\" | \
sed -e 's@.*[^a-z0-9_A-Z]\\([a-zA-Z0-9_]*\\)*$@\\1;@' \
-e 's/^/ (void)saved_/'" ))
=][=
ENDIF=]
while ([=(. pfx)=]_state < [=(. PFX)=]_ST_INVALID) {
[=IF (exist? "handler-file")=]
#define FSM_FIND_TRANSITION
#include "[= handler-file =]"
#undef FSM_FIND_TRANSITION[=
ELSE =]
[=(extract fsm-source " /* %s == FIND TRANSITION == %s */" ""
" trans_evt = GET_NEXT_TRANS();" ) =][=
ENDIF =]
[= (out-push-new (string-append tmp-dir "/cktbl"))=][=
INVOKE machine-step =][=
(out-pop) (shell
"sed 's/^ / /;s/ / /' ${tmp_dir}/cktbl")
=]
}
return [=(. pfx)=]_state;
}[=
ENDDEF looping-machine
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
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
=][= INVOKE 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;
}
[=INVOKE machine-step =][=
IF (exist? "handler-file")=]
#define FSM_FINISH_STEP
#include "[= handler-file =]"
#undef FSM_FINISH_STEP[=
ELSE =]
[=(extract fsm-source " /* %s == FINISH STEP == %s */")=][=
ENDIF =]
return nxtSt;
}[=
ENDDEF stepping-machine
# end of agen5/fsm-trans.tlib =]