/* * EDIT THIS FILE WITH CAUTION (example-fsm.c) * * It has been AutoGen-ed December 28, 2011 at 05:05:29 PM by AutoGen 5.14 * From the definitions example.def * and the template file fsm * * Automated Finite State Machine * * copyright (c) 2001-2007 by Bruce Korb - all rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name ``Bruce Korb'' nor the name of any other * contributor may be used to endorse or promote products derived * from this software without specific prior written permission. * * AutoFSM IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define DEFINE_FSM #include "example-fsm.h" #include <stdio.h> #include <ctype.h> /* * Do not make changes to this file, except between the START/END * comments, or it will be removed the next time it is generated. */ /* START === USER HEADERS === DO NOT CHANGE THIS COMMENT */ /* END === USER HEADERS === DO NOT CHANGE THIS COMMENT */ #ifndef NULL # define NULL 0 #endif /* * Enumeration of the valid transition types * Some transition types may be common to several transitions. */ typedef enum { EX_TR_DASH_COMMA, EX_TR_DASH_EOL, EX_TR_DASH_NUM, EX_TR_INIT_BANG, EX_TR_INIT_DASH, EX_TR_INIT_NUM, EX_TR_INVALID, EX_TR_LONUM_COMMA, EX_TR_LONUM_DASH, EX_TR_LONUM_EOL, EX_TR_NOOP } te_ex_trans; #define EX_TRANSITION_CT 11 /* * 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 ex_transition t_ex_transition; struct ex_transition { te_ex_state next_state; te_ex_trans transition; }; static const t_ex_transition ex_trans_table[ EX_STATE_CT ][ EX_EVENT_CT ] = { /* STATE 0: EX_ST_INIT */ { { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: , */ { EX_ST_LONUM, EX_TR_INIT_NUM }, /* EVT: num */ { EX_ST_DASH, EX_TR_INIT_DASH }, /* EVT: - */ { EX_ST_INIT, EX_TR_INIT_BANG }, /* EVT: ! */ { EX_ST_INVALID, EX_TR_INVALID } /* EVT: End-Of-Line */ }, /* STATE 1: EX_ST_LONUM */ { { EX_ST_INIT, EX_TR_LONUM_COMMA }, /* EVT: , */ { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: num */ { EX_ST_DASH, EX_TR_LONUM_DASH }, /* EVT: - */ { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: ! */ { EX_ST_DONE, EX_TR_LONUM_EOL } /* EVT: End-Of-Line */ }, /* STATE 2: EX_ST_DASH */ { { EX_ST_INIT, EX_TR_DASH_COMMA }, /* EVT: , */ { EX_ST_HINUM, EX_TR_DASH_NUM }, /* EVT: num */ { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: - */ { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: ! */ { EX_ST_DONE, EX_TR_DASH_EOL } /* EVT: End-Of-Line */ }, /* STATE 3: EX_ST_HINUM */ { { EX_ST_INIT, EX_TR_NOOP }, /* EVT: , */ { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: num */ { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: - */ { EX_ST_INVALID, EX_TR_INVALID }, /* EVT: ! */ { EX_ST_DONE, EX_TR_NOOP } /* EVT: End-Of-Line */ } }; #define ExFsmErr_off 19 #define ExEvInvalid_off 75 #define ExStInit_off 83 static char const zExStrings[127] = /* 0 */ "** OUT-OF-RANGE **\0" /* 19 */ "FSM Error: in state %d (%s), event %d (%s) is invalid\n\0" /* 75 */ "invalid\0" /* 83 */ "init\0" /* 88 */ "lonum\0" /* 94 */ "dash\0" /* 99 */ "hinum\0" /* 105 */ ",\0" /* 107 */ "num\0" /* 111 */ "-\0" /* 113 */ "!\0" /* 115 */ "End-Of-Line"; static const size_t aszExStates[4] = { 83, 88, 94, 99 }; static const size_t aszExEvents[6] = { 105, 107, 111, 113, 115, 75 }; #define EX_EVT_NAME(t) ( (((unsigned)(t)) >= 6) \ ? zExStrings : zExStrings + aszExEvents[t]) #define EX_STATE_NAME(s) ( (((unsigned)(s)) >= 4) \ ? zExStrings : zExStrings + aszExStates[s]) #ifndef EXIT_FAILURE # define EXIT_FAILURE 1 #endif static int ex_invalid_transition( te_ex_state st, te_ex_event evt ); /* * * * * * * * * THE CODE STARTS HERE * * * * * * * * * * Print out an invalid transition message and return EXIT_FAILURE */ static int ex_invalid_transition( te_ex_state st, te_ex_event evt ) { /* START == INVALID TRANS MSG == DO NOT CHANGE THIS COMMENT */ char const * fmt = zExStrings + ExFsmErr_off; fprintf( stderr, fmt, st, EX_STATE_NAME(st), evt, EX_EVT_NAME(evt)); /* END == INVALID TRANS MSG == DO NOT CHANGE THIS COMMENT */ return EXIT_FAILURE; } /* * Run the FSM. Will return EX_ST_DONE or EX_ST_INVALID */ te_ex_state ex_run_fsm( void* cookie ) { te_ex_state ex_state = EX_ST_INIT; te_ex_event trans_evt; te_ex_state nxtSt; te_ex_trans trans; while (ex_state < EX_ST_INVALID) { /* START == FIND TRANSITION == DO NOT CHANGE THIS COMMENT */ trans_evt = GET_NEXT_TRANS(); /* END == FIND TRANSITION == DO NOT CHANGE THIS COMMENT */ if (trans_evt >= EX_EV_INVALID) { nxtSt = EX_ST_INVALID; trans = EX_TR_INVALID; } else { const t_ex_transition* pTT = ex_trans_table[ ex_state ] + trans_evt; nxtSt = pTT->next_state; trans = pTT->transition; } switch (trans) { case EX_TR_DASH_COMMA: /* START == DASH_COMMA == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_DASH_COMMA(); /* END == DASH_COMMA == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_DASH_EOL: /* START == DASH_EOL == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_DASH_EOL(); /* END == DASH_EOL == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_DASH_NUM: /* START == DASH_NUM == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_DASH_NUM(); /* END == DASH_NUM == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_INIT_BANG: /* START == INIT_BANG == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_INIT_BANG(); /* END == INIT_BANG == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_INIT_DASH: /* START == INIT_DASH == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_INIT_DASH(); /* END == INIT_DASH == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_INIT_NUM: /* START == INIT_NUM == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_INIT_NUM(); /* END == INIT_NUM == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_INVALID: /* START == INVALID == DO NOT CHANGE THIS COMMENT */ exit( ex_invalid_transition( ex_state, trans_evt )); /* END == INVALID == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_LONUM_COMMA: /* START == LONUM_COMMA == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_LONUM_COMMA(); /* END == LONUM_COMMA == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_LONUM_DASH: /* START == LONUM_DASH == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_LONUM_DASH(); /* END == LONUM_DASH == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_LONUM_EOL: /* START == LONUM_EOL == DO NOT CHANGE THIS COMMENT */ nxtSt = HANDLE_LONUM_EOL(); /* END == LONUM_EOL == DO NOT CHANGE THIS COMMENT */ break; case EX_TR_NOOP: break; default: /* START == BROKEN MACHINE == DO NOT CHANGE THIS COMMENT */ exit( ex_invalid_transition( ex_state, trans_evt )); /* END == BROKEN MACHINE == DO NOT CHANGE THIS COMMENT */ } ex_state = nxtSt; } return ex_state; } /* * Local Variables: * mode: C * c-file-style: "stroustrup" * indent-tabs-mode: nil * End: * end of example-fsm.c */