home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / FSM.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  3KB  |  107 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /* =======================================================================
  4.     FSM.c           Finite State machines.
  5.                     Version 0.22x, 93-08-05.
  6.  
  7.  _____              This version is Public Domain.
  8.  /_|__|             A.Reitsma, Delft, Nederland.
  9. /  | \  --------------------------------------------------------------- */
  10.  
  11. #include <stdlib.h>
  12. #include "ll_defs.h"
  13. #include "fsm.h"
  14.  
  15. /* tmp definitions until error module is finished */
  16. #define MEMORY      -1
  17. #define Error(x)    return x
  18.  
  19. /*  --- Local definitions and data ------------------------------------ */
  20. struct state_info
  21. {
  22.     struct FSMstate_entry * table ;
  23.     int entries ;
  24. };
  25.  
  26. static int state ;      /* the machine's state or it's maximum in setup */
  27. static struct state_info * info ;  /* derived info in a handier format  */
  28.  
  29. /*  --- Setup and action functions ------------------------------------ */
  30.  
  31. int FSMsetup( struct FSMstate_entry * StateEntry )
  32. {
  33.     struct FSMstate_entry * Entry = StateEntry ;
  34.     struct state_info * data ;
  35.  
  36.     /*  Find 'highest' state number. Negative number is end of list.
  37.         Gaps allowed. Must be sorted on state number in current version.
  38.         Prepared for non-sorted version though.
  39.     */
  40.     state = 0 ;
  41.     do
  42.     {
  43.         if( state < Entry->state )
  44.             state = Entry->state ;
  45.  
  46.     }while( (++Entry)->state >= 0 );
  47.  
  48.     /*  Create info 'array'
  49.     */
  50.     if( NULL == (info = MALLOC( state+1, struct state_info )))
  51.         Error( MEMORY );
  52.  
  53.     /*  Setup info 'array': split into sub-lists with size info.
  54.         First entry:
  55.     */
  56.     data = info ;
  57.     data->table = StateEntry ;
  58.     data->entries = 1 ;
  59.     /*  ... and the second and following entries:
  60.     */
  61.     while( (++StateEntry)->state >= 0 )
  62.     {
  63.         if( data->table->state == StateEntry->state )
  64.             data->entries ++ ;          /* same state */
  65.         else
  66.         {                               /* new state  */
  67.             data = info + StateEntry->state ;
  68.             data->table = StateEntry ;
  69.             data->entries = 1 ;
  70.         }
  71.     }
  72.  
  73.     state = 0 ; /* initial state for state machine */
  74.  
  75.     return 0 ;
  76. }
  77.  
  78. int FSMaction( int Cond )
  79. {
  80.     int count ;
  81.     struct FSMstate_entry * Table = info[ state ].table ;
  82.  
  83.     /*  Find matching condition in second or higher entry in table.
  84.     */
  85.     for( count = 1 ; count < info[ state ].entries ; count ++ )
  86.     {
  87.         Table ++;
  88.         if( Cond == Table->cond )
  89.         {
  90.             state = Table->next ;      /* match found: adjust state,    */
  91.                                        /* and execute non-NULL funtion. */
  92.             if( NULL != Table->action )
  93.                 return Table->action( Cond );
  94.             else
  95.                 return 0 ;
  96.         }
  97.     }
  98.  
  99.     /*  No matching condition found: use first entry as default action.
  100.     */
  101.     Table = info[ state ].table ;
  102.     state = Table->next ;
  103.     return Table->action( Cond );
  104. }
  105.  
  106. /* === FSM.c ========================================================== */
  107.