LCOV - code coverage report
Current view: top level - artdaq/Application/detail - statemap.h (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 64.5 % 107 69
Test Date: 2025-09-04 00:45:34 Functions: 48.3 % 29 14

            Line data    Source code
       1              : #ifndef _H_STATEMAP
       2              : #define _H_STATEMAP
       3              : 
       4              : //
       5              : // The contents of this file are subject to the Mozilla Public
       6              : // License Version 1.1 (the "License"); you may not use this file
       7              : // except in compliance with the License. You may obtain a copy
       8              : // of the License at http://www.mozilla.org/MPL/
       9              : //
      10              : // Software distributed under the License is distributed on an
      11              : // "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
      12              : // implied. See the License for the specific language governing
      13              : // rights and limitations under the License.
      14              : //
      15              : // The Original Code is State Machine Compiler (SMC).
      16              : //
      17              : // The Initial Developer of the Original Code is Charles W. Rapp.
      18              : // Portions created by Charles W. Rapp are
      19              : // Copyright (C) 2000 - 2007. Charles W. Rapp.
      20              : // All Rights Reserved.
      21              : //
      22              : // Contributor(s):
      23              : //
      24              : // Namespace
      25              : //      statemap
      26              : //
      27              : // Description
      28              : //  This namespace contains the finite state machine context
      29              : //  class. The user can derive FSM contexts from this class and
      30              : //  interface to them with the methods of this class.
      31              : //
      32              : // Notes
      33              : //  The finite state machine needs to be initialized to the
      34              : //  starting state of the FSM.  This must be done manually in
      35              : //  the constructor of the derived class.
      36              : //
      37              : // Author
      38              : //      C. W. Rapp
      39              : //
      40              : // RCS ID
      41              : // Id: statemap.h,v 1.19 2014/09/06 19:31:28 fperrad Exp
      42              : //
      43              : // CHANGE LOG
      44              : // (See bottom of file)
      45              : //
      46              : 
      47              : #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
      48              : #if defined(SMC_USES_IOSTREAMS)
      49              : #include <iostream>
      50              : #endif  // SMC_USES_IOSTREAMS
      51              : #if defined(SMC_NO_EXCEPTIONS)
      52              : #include <cassert>
      53              : #endif  // SMC_NO_EXCEPTIONS
      54              : #include <cstdio>
      55              : #elif defined(WIN32)
      56              : #if defined(SMC_USES_IOSTREAMS)
      57              : #include <iostream>
      58              : #endif  // SMC_USES_IOSTREAMS
      59              : #if defined(SMC_NO_EXCEPTIONS)
      60              : #include <cassert>
      61              : #endif  // SMC_NO_EXCEPTIONS
      62              : #include <windows.h>
      63              : #else
      64              : #if defined(SMC_USES_IOSTREAMS)
      65              : #include <iostream.h>
      66              : #endif  // SMC_USES_IOSTREAMS
      67              : #if defined(SMC_NO_EXCEPTIONS)
      68              : #include <assert.h>
      69              : #endif  // SMC_NO_EXCEPTIONS
      70              : #include <stdio.h>
      71              : #endif
      72              : #if !defined(SMC_NO_EXCEPTIONS)
      73              : #include <cstring>
      74              : #include <stdexcept>
      75              : #endif
      76              : 
      77              : // Limit names to 100 ASCII characters.
      78              : // Why 100? Because it is a round number.
      79              : #define MAX_NAME_LEN 100
      80              : 
      81              : namespace statemap {
      82              : //---------------------------------------------------------------
      83              : // Routines.
      84              : //
      85              : 
      86              : #ifdef SMC_FIXED_STACK
      87              : // When static memory is used, a string has only one copy.
      88              : inline char* copyString(const char* s)
      89              : {
      90              :         // Cast your const upon the waters and see what blows up.
      91              :         return (const_cast<char*>(s));
      92              : }
      93              : #else   // ! SMC_FIXED_STACK
      94           21 : inline char* copyString(const char* s)
      95              : {
      96           21 :         char* retval = NULL;
      97              : 
      98           21 :         if (s != NULL)
      99              :         {
     100           21 :                 retval = new char[MAX_NAME_LEN + 1];
     101           21 :                 retval[MAX_NAME_LEN] = '\0';
     102           21 :                 (void)std::strncpy(retval, s, MAX_NAME_LEN);
     103              :         }
     104              : 
     105           21 :         return (retval);
     106              : }
     107              : #endif  // ! SMC_FIXED_STACK
     108              : 
     109              : //---------------------------------------------------------------
     110              : // Exception Classes.
     111              : //
     112              : 
     113              : #ifndef SMC_NO_EXCEPTIONS
     114              : // Base class for all SMC exceptions.
     115              : class SmcException : public std::runtime_error
     116              : {
     117              :         //-----------------------------------------------------------
     118              :         // Member methods
     119              :         //
     120              : public:
     121              :         // Destructor.
     122            0 :         virtual ~SmcException() throw(){};
     123              : 
     124              : protected:
     125              :         // Constructor.
     126            0 :         SmcException(const std::string& reason)
     127            0 :             : std::runtime_error(reason){};
     128              : 
     129              : private:
     130              :         // Default construction not allowed.
     131              :         SmcException();
     132              : 
     133              :         //-----------------------------------------------------------
     134              :         // Member data.
     135              :         //
     136              : public:
     137              : protected:
     138              : private:
     139              : };
     140              : 
     141              : #ifdef SMC_FIXED_STACK
     142              : class PushOnFullStateStackException : public SmcException
     143              : {
     144              :         //-----------------------------------------------------------
     145              :         // Member methods.
     146              :         //
     147              : public:
     148              :         // Default constructor.
     149              :         PushOnFullStateStackException()
     150              :             : SmcException("cannot push on full state stack"){};
     151              : 
     152              :         // Destructor.
     153              :         virtual ~PushOnFullStateStackException() throw(){};
     154              : 
     155              : protected:
     156              : private:
     157              :         //-----------------------------------------------------------
     158              :         // Member data.
     159              :         //
     160              : public:
     161              : protected:
     162              : private:
     163              : };
     164              : #endif
     165              : 
     166              : // This class is thrown when a pop is issued on an empty
     167              : // state stack.
     168              : class PopOnEmptyStateStackException : public SmcException
     169              : {
     170              :         //-----------------------------------------------------------
     171              :         // Member methods.
     172              :         //
     173              : public:
     174              :         // Default constructor.
     175            0 :         PopOnEmptyStateStackException()
     176            0 :             : SmcException("no state to pop from state stack"){};
     177              : 
     178              :         // Destructor.
     179            0 :         virtual ~PopOnEmptyStateStackException() throw(){};
     180              : 
     181              : protected:
     182              : private:
     183              :         //-----------------------------------------------------------
     184              :         // Member data.
     185              :         //
     186              : public:
     187              : protected:
     188              : private:
     189              : };
     190              : 
     191              : // This class is thrown when a transition is issued
     192              : // but there is no current state. This happens when
     193              : // a transition is issued from within a transition
     194              : // action.
     195              : class StateUndefinedException : public SmcException
     196              : {
     197              :         //-----------------------------------------------------------
     198              :         // Member methods.
     199              :         //
     200              : public:
     201              :         // Default constructor.
     202            0 :         StateUndefinedException()
     203            0 :             : SmcException("transition invoked while in transition"){};
     204              : 
     205              :         // Destructor.
     206            0 :         virtual ~StateUndefinedException() throw(){};
     207              : 
     208              : protected:
     209              : private:
     210              :         //-----------------------------------------------------------
     211              :         // Member data.
     212              :         //
     213              : public:
     214              : protected:
     215              : private:
     216              : };
     217              : 
     218              : // This class is thrown when a transition is issued
     219              : // but there is no code to handle it.
     220              : class TransitionUndefinedException : public SmcException
     221              : {
     222              :         //-----------------------------------------------------------
     223              :         // Member methods.
     224              :         //
     225              : public:
     226              :         // Default constructor.
     227              :         TransitionUndefinedException()
     228              :             : SmcException("no such transition in current state"), _state(NULL), _transition(NULL){};
     229              : 
     230              :         // Construct an exception using the specified state
     231              :         // and transition.
     232            0 :         TransitionUndefinedException(const char* state,
     233              :                                      const char* transition)
     234            0 :             : SmcException("no such transition in current state"), _state(copyString(state)), _transition(copyString(transition)){};
     235              : 
     236              :         // Copy constructor.
     237              :         TransitionUndefinedException(
     238              :             const TransitionUndefinedException& ex)
     239              :             : SmcException("no such transition in current state"), _state(copyString(ex._state)), _transition(copyString(ex._transition)){};
     240              : 
     241              :         // Destructor.
     242            0 :         virtual ~TransitionUndefinedException() throw()
     243            0 :         {
     244            0 :                 if (_state != NULL)
     245              :                 {
     246            0 :                         delete[] _state;
     247            0 :                         _state = NULL;
     248              :                 }
     249              : 
     250            0 :                 if (_transition != NULL)
     251              :                 {
     252            0 :                         delete[] _transition;
     253            0 :                         _transition = NULL;
     254              :                 }
     255            0 :         };
     256              : 
     257              :         // Assignment operator.
     258              :         const TransitionUndefinedException&
     259              :         operator=(const TransitionUndefinedException& ex)
     260              :         {
     261              :                 // Don't do self assignment.
     262              :                 if (this != &ex)
     263              :                 {
     264              :                         if (_state != NULL)
     265              :                         {
     266              :                                 delete[] _state;
     267              :                                 _state = NULL;
     268              :                         }
     269              : 
     270              :                         if (_transition != NULL)
     271              :                         {
     272              :                                 delete[] _transition;
     273              :                                 _transition = NULL;
     274              :                         }
     275              : 
     276              :                         _state = copyString(ex._state);
     277              :                         _transition = copyString(ex._transition);
     278              :                 }
     279              : 
     280              :                 return (*this);
     281              :         };
     282              : 
     283              :         // Returns the state. May be NULL.
     284              :         const char* getState() const
     285              :         {
     286              :                 return (_state);
     287              :         };
     288              : 
     289              :         // Returns the transition. May be NULL.
     290              :         const char* getTransition() const
     291              :         {
     292              :                 return (_transition);
     293              :         };
     294              : 
     295              : protected:
     296              : private:
     297              :         //-----------------------------------------------------------
     298              :         // Member data.
     299              :         //
     300              : public:
     301              : protected:
     302              : private:
     303              :         char* _state;
     304              :         char* _transition;
     305              : };
     306              : 
     307              : // This class is thrown when a state ID is either less than
     308              : // the minimal value or greater than the maximal value.
     309              : class IndexOutOfBoundsException : public SmcException
     310              : {
     311              :         //-----------------------------------------------------------
     312              :         // Member methods.
     313              :         //
     314              : public:
     315              :         // Default constructor.
     316              :         IndexOutOfBoundsException()
     317              :             : SmcException("index out of bounds"), _index(0), _minIndex(0), _maxIndex(0){};
     318              : 
     319              :         // Constructs an exception using the specified index,
     320              :         // minimum index and maximum index.
     321              :         IndexOutOfBoundsException(const int index,
     322              :                                   const int minIndex,
     323              :                                   const int maxIndex)
     324              :             : SmcException("index out of bounds"), _index(index), _minIndex(minIndex), _maxIndex(maxIndex){};
     325              : 
     326              :         // Copy constructor.
     327              :         IndexOutOfBoundsException(
     328              :             const IndexOutOfBoundsException& ex)
     329              :             : SmcException("index out of bounds"), _index(ex._index), _minIndex(ex._minIndex), _maxIndex(ex._maxIndex){};
     330              : 
     331              :         // Destructor.
     332              :         virtual ~IndexOutOfBoundsException() throw(){};
     333              : 
     334              :         // Assignment operator.
     335              :         const IndexOutOfBoundsException&
     336              :         operator=(const IndexOutOfBoundsException& ex)
     337              :         {
     338              :                 // Don't do self assignment.
     339              :                 if (this != &ex)
     340              :                 {
     341              :                         _index = ex._index;
     342              :                         _minIndex = ex._minIndex;
     343              :                         _maxIndex = ex._maxIndex;
     344              :                 }
     345              : 
     346              :                 return (*this);
     347              :         };
     348              : 
     349              :         // Returns the out-of-bounds index.
     350              :         int getIndex() const
     351              :         {
     352              :                 return (_index);
     353              :         };
     354              : 
     355              :         // Returns the minimum allowed index value.
     356              :         int getMinIndex() const
     357              :         {
     358              :                 return (_minIndex);
     359              :         };
     360              : 
     361              :         // Returns the maximum allowed index value.
     362              :         int getMaxIndex() const
     363              :         {
     364              :                 return (_maxIndex);
     365              :         };
     366              : 
     367              : protected:
     368              : private:
     369              :         //-----------------------------------------------------------
     370              :         // Member data.
     371              :         //
     372              : public:
     373              : protected:
     374              : private:
     375              :         int _index;
     376              :         int _minIndex;
     377              :         int _maxIndex;
     378              : };
     379              : #endif  // !SMC_NO_EXCEPTIONS
     380              : 
     381              : //
     382              : // end of Exception Classes.
     383              : //---------------------------------------------------------------
     384              : 
     385              : class State
     386              : {
     387              :         //-----------------------------------------------------------
     388              :         // Member functions.
     389              :         //
     390              : public:
     391           18 :         const char* getName() const
     392              :         {
     393           18 :                 return (_name);
     394              :         };
     395              : 
     396              :         int getId() const
     397              :         {
     398              :                 return (_stateId);
     399              :         }
     400              : 
     401              : protected:
     402           21 :         State(const char* name, int stateId)
     403           21 :             : _name(NULL), _stateId(stateId)
     404              :         {
     405           21 :                 if (name != NULL)
     406              :                 {
     407           21 :                         _name = copyString(name);
     408              :                 }
     409              :                 else
     410              :                 {
     411            0 :                         _name = copyString("NAME NOT SET");
     412              :                 }
     413           21 :         };
     414              : 
     415           21 :         virtual ~State()
     416           21 :         {
     417              : #ifndef SMC_FIXED_STACK
     418           21 :                 if (_name != NULL)
     419              :                 {
     420              :                         // Delete the string iff static memory is
     421              :                         // *not* used.
     422           21 :                         delete[] _name;
     423           21 :                         _name = NULL;
     424              :                 }
     425              : #endif
     426           21 :         };
     427              : 
     428              : private:
     429              :         // Make the default and copy constructors private to
     430              :         // prevent their use.
     431              :         State(){};
     432              :         State(const State&){};
     433              : 
     434              :         //-----------------------------------------------------------
     435              :         // Member data.
     436              :         //
     437              : public:
     438              : protected:
     439              :         // This state's printable name.
     440              :         char* _name;
     441              : 
     442              :         // This state's unique identifier.
     443              :         int _stateId;
     444              : 
     445              : private:
     446              : };
     447              : 
     448              : class FSMContext
     449              : {
     450              :         //-----------------------------------------------------------
     451              :         // Nested classes.
     452              :         //
     453              : public:
     454              : protected:
     455              : private:
     456              :         // Implements the state stack.
     457              :         class StateEntry
     458              :         {
     459              :                 //-------------------------------------------------------
     460              :                 // Member functions.
     461              :                 //
     462              :         public:
     463            2 :                 StateEntry(State* state, StateEntry* next)
     464            2 :                     : _state(state), _next(next){};
     465              : 
     466            2 :                 ~StateEntry()
     467              :                 {
     468            2 :                         _state = NULL;
     469            2 :                         _next = NULL;
     470            2 :                 };
     471              : 
     472            2 :                 State* getState()
     473              :                 {
     474            2 :                         return (_state);
     475              :                 };
     476              : 
     477            2 :                 StateEntry* getNext()
     478              :                 {
     479            2 :                         return (_next);
     480              :                 };
     481              : 
     482              :         protected:
     483              :         private:
     484              :                 //-------------------------------------------------------
     485              :                 // Member data.
     486              :                 //
     487              :         public:
     488              :         protected:
     489              :         private:
     490              :                 State* _state;
     491              :                 StateEntry* _next;
     492              : 
     493              :                 //-------------------------------------------------------
     494              :                 // Friends
     495              :                 //
     496              :                 friend class FSMContext;
     497              :         };  // end of class StateEntry
     498              : 
     499              :         //-----------------------------------------------------------
     500              :         // Member functions
     501              :         //
     502              : public:
     503              :         // Destructor.
     504            1 :         virtual ~FSMContext()
     505            1 :         {
     506              : #ifdef SMC_FIXED_STACK
     507              :                 _transition = NULL;
     508              : #else   // ! SMC_FIXED_STACK
     509              :                 StateEntry* state;
     510              : 
     511            1 :                 if (_transition != NULL)
     512              :                 {
     513            0 :                         delete[] _transition;
     514            0 :                         _transition = NULL;
     515              :                 }
     516              : 
     517              :                 // But we did allocate the state stack.
     518            2 :                 while (_state_stack != NULL)
     519              :                 {
     520            0 :                         state = _state_stack;
     521            0 :                         _state_stack = _state_stack->_next;
     522            0 :                         delete state;
     523              :                 }
     524              : #endif  // ! SMC_FIXED_STACK
     525            1 :         };
     526              : 
     527              :         // Comparison and assignment operators
     528              :         // Assignment operator
     529              :         FSMContext& operator=(const FSMContext& fsm)
     530              :         {
     531              :                 // Don't do the assignment if the left and right
     532              :                 // hand sides are the same object.
     533              :                 if (this != &fsm)
     534              :                 {
     535              :                         _state = fsm._state;
     536              :                 }
     537              : 
     538              :                 return (*this);
     539              :         };
     540              : 
     541              :         // Starts the finite state machine running by executing
     542              :         // the initial state's entry actions.
     543              :         virtual void enterStartState() = 0;
     544              : 
     545              :         // Exact same object (is it me?)
     546              :         int same(const FSMContext& fsm) const
     547              :         {
     548              :                 return (this == &fsm);
     549              :         };
     550              : 
     551              :         // Returns the debug flag's current setting.
     552              :         bool getDebugFlag()
     553              :         {
     554              :                 return (_debug_flag);
     555              :         };
     556              : 
     557              :         // Sets the debug flag. A true value means debugging
     558              :         // is on and false means off.
     559              :         void setDebugFlag(bool flag)
     560              :         {
     561              :                 _debug_flag = flag;
     562              :                 return;
     563              :         };
     564              : 
     565              : #ifdef SMC_USES_IOSTREAMS
     566              :         // Returns the stream to which debug output is written.
     567              :         std::ostream& getDebugStream()
     568              :         {
     569              :                 return (*_debug_stream);
     570              :         };
     571              : 
     572              :         // Sets the debug output stream.
     573              :         void setDebugStream(std::ostream& debug_stream)
     574              :         {
     575              :                 _debug_stream = &debug_stream;
     576              :                 return;
     577              :         }
     578              : #endif  // SMC_USES_IOSTREAMS
     579              : 
     580              :         // Is this state machine already inside a transition?
     581              :         // Yes if state is null.
     582              :         bool isInTransition() const
     583              :         {
     584              :                 return (_state == NULL ? true : false);
     585              :         };
     586              : 
     587              :         // Returns the current transition's name.
     588              :         // Used only for debugging purposes.
     589            0 :         char* getTransition()
     590              :         {
     591            0 :                 return (_transition);
     592              :         };
     593              : 
     594              :         // Saves away the transition name only if debugging
     595              :         // is turned on.
     596              :         void setTransition(const char* transition)
     597              :         {
     598              : #ifndef SMC_FIXED_STACK
     599              :                 if (_transition != NULL)
     600              :                 {
     601              :                         delete[] _transition;
     602              :                         _transition = NULL;
     603              :                 }
     604              : #endif  // ! SMC_FIXED_STACK
     605              : 
     606              :                 _transition = copyString(transition);
     607              : 
     608              :                 return;
     609              :         };
     610              : 
     611              :         // Clears the current state.
     612            2 :         void clearState()
     613              :         {
     614            2 :                 _previous_state = _state;
     615            2 :                 _state = NULL;
     616            2 :         };
     617              : 
     618              :         // Returns the state which a transition left.
     619              :         // May be NULL.
     620              :         State* getPreviousState()
     621              :         {
     622              :                 return (_previous_state);
     623              :         }
     624              : 
     625              :         // Sets the current state to the specified state.
     626            8 :         void setState(const State& state)
     627              :         {
     628              :                 // clearState() is not called when a transition has
     629              :                 // no actions, so set _previous_state to _state in
     630              :                 // that situation. We know clearState() was not
     631              :                 // called when _state is not null.
     632            8 :                 if (_state != NULL)
     633              :                 {
     634            6 :                         _previous_state = _state;
     635              :                 }
     636              : 
     637            8 :                 _state = const_cast<State*>(&state);
     638              : 
     639            8 :                 if (_debug_flag == true)
     640              :                 {
     641              : #ifdef SMC_USES_IOSTREAMS
     642            0 :                         *_debug_stream << "ENTER STATE     : "
     643            0 :                                        << _state->getName()
     644            0 :                                        << std::endl;
     645              : #else
     646              :                         TRACE("ENTER STATE     : %s\n",
     647              :                               _state->getName());
     648              : #endif  // SMC_USES_IOSTREAMS
     649              :                 }
     650            8 :         };
     651              : 
     652              : #ifdef SMC_FIXED_STACK
     653              :         // Returns true if the state stack is empty and false
     654              :         // otherwise.
     655              :         bool isStateStackEmpty() const
     656              :         {
     657              :                 return (_state_stack_depth == 0);
     658              :         }
     659              : 
     660              :         // Returns the state stack's depth.
     661              :         int getStateStackDepth() const
     662              :         {
     663              :                 return (_state_stack_depth);
     664              :         }
     665              : 
     666              :         // Push the current state on top of the state stack
     667              :         // and make the specified state the current state.
     668              :         void pushState(const State& state)
     669              :         {
     670              : #ifdef SMC_NO_EXCEPTIONS
     671              :                 assert(_state_stack_depth < SMC_STATE_STACK_SIZE);
     672              : #else
     673              :                 if (_state_stack_depth == SMC_STATE_STACK_SIZE)
     674              :                 {
     675              :                         throw PushOnFullStateStackException();
     676              :                 }
     677              : #endif
     678              : 
     679              :                 // Do the push only if there is a state to be pushed
     680              :                 // on the stack.
     681              :                 if (_state != NULL)
     682              :                 {
     683              :                         _state_stack[_state_stack_depth] = _state;
     684              :                         ++_state_stack_depth;
     685              :                 }
     686              : 
     687              :                 _previous_state = _state;
     688              :                 _state = const_cast<State*>(&state);
     689              : 
     690              :                 if (_debug_flag == true)
     691              :                 {
     692              : #ifdef SMC_USES_IOSTREAMS
     693              :                         *_debug_stream << "PUSH TO STATE   : "
     694              :                                        << _state->getName()
     695              :                                        << std::endl;
     696              : #else
     697              :                         TRACE("PUSH TO STATE   : %s\n",
     698              :                               _state->getName());
     699              : #endif  // SMC_USES_IOSTREAMS
     700              :                 }
     701              :         };
     702              : 
     703              :         // Make the state on top of the state stack the
     704              :         // current state.
     705              :         void popState()
     706              :         {
     707              :                 // Popping when there was no previous push is an error.
     708              : #ifdef SMC_NO_EXCEPTIONS
     709              :                 assert(_state_stack_depth > 0);
     710              : #else
     711              :                 if (_state_stack_depth == 0)
     712              :                 {
     713              :                         throw PopOnEmptyStateStackException();
     714              :                 }
     715              : #endif
     716              : 
     717              :                 _previous_state = _state;
     718              :                 --_state_stack_depth;
     719              :                 _state = _state_stack[_state_stack_depth];
     720              : 
     721              :                 if (_debug_flag == true)
     722              :                 {
     723              : #ifdef SMC_USES_IOSTREAMS
     724              :                         *_debug_stream << "POP TO STATE    : "
     725              :                                        << _state->getName()
     726              :                                        << std::endl;
     727              : #else
     728              :                         TRACE("POP TO STATE    : %s\n",
     729              :                               _state->getName());
     730              : #endif  // SMC_USES_IOSTREAMS
     731              :                 }
     732              :         };
     733              : 
     734              :         // Remove all states from the state stack.
     735              :         void emptyStateStack()
     736              :         {
     737              :                 _state_stack_depth = 0;
     738              :         };
     739              : #else  // ! SMC_FIXED_STACK
     740              : 
     741              :         // Returns true if the state stack is empty and false otherwise.
     742              :         bool isStateStackEmpty() const
     743              :         {
     744              :                 return (_state_stack == NULL);
     745              :         }
     746              : 
     747              :         // Returns the state stack's depth.
     748              :         int getStateStackDepth() const
     749              :         {
     750              :                 StateEntry* state_ptr;
     751              :                 int retval;
     752              : 
     753              :                 for (state_ptr = _state_stack, retval = 0;
     754              :                      state_ptr != NULL;
     755              :                      state_ptr = state_ptr->getNext(), ++retval)
     756              :                         ;
     757              : 
     758              :                 return (retval);
     759              :         }
     760              : 
     761              :         // Push the current state on top of the state stack
     762              :         // and make the specified state the current state.
     763            2 :         void pushState(const State& state)
     764              :         {
     765              :                 StateEntry* new_entry;
     766              : 
     767              :                 // Do the push only if there is a state to be pushed
     768              :                 // on the stack.
     769            2 :                 if (_state != NULL)
     770              :                 {
     771            2 :                         new_entry = new StateEntry(_state, _state_stack);
     772            2 :                         _state_stack = new_entry;
     773              :                 }
     774              : 
     775            2 :                 _previous_state = _state;
     776            2 :                 _state = const_cast<State*>(&state);
     777              : 
     778            2 :                 if (_debug_flag == true)
     779              :                 {
     780              : #ifdef SMC_USES_IOSTREAMS
     781            0 :                         *_debug_stream << "PUSH TO STATE   : "
     782            0 :                                        << _state->getName()
     783            0 :                                        << std::endl;
     784              : #else
     785              :                         TRACE("PUSH TO STATE   : %s\n",
     786              :                               _state->getName());
     787              : #endif  // SMC_USES_IOSTREAMS
     788              :                 }
     789            2 :         };
     790              : 
     791              :         // Make the state on top of the state stack the
     792              :         // current state.
     793            2 :         void popState()
     794              :         {
     795              :                 StateEntry* entry;
     796              : 
     797              :                 // Popping when there was no previous push is an error.
     798              : #ifdef SMC_NO_EXCEPTIONS
     799              :                 assert(_state_stack != NULL);
     800              : #else
     801            2 :                 if (_state_stack == NULL)
     802              :                 {
     803            0 :                         throw PopOnEmptyStateStackException();
     804              :                 }
     805              : #endif  // SMC_NO_EXCEPTIONS
     806              : 
     807            2 :                 _previous_state = _state;
     808            2 :                 _state = _state_stack->getState();
     809            2 :                 entry = _state_stack;
     810            2 :                 _state_stack = _state_stack->getNext();
     811            2 :                 delete entry;
     812              : 
     813            2 :                 if (_debug_flag == true)
     814              :                 {
     815              : #ifdef SMC_USES_IOSTREAMS
     816            0 :                         *_debug_stream << "POP TO STATE    : "
     817            0 :                                        << _state->getName()
     818            0 :                                        << std::endl;
     819              : #else
     820              :                         TRACE("POP TO STATE    : %s\n",
     821              :                               _state->getName());
     822              : #endif  // SMC_USES_IOSTREAMS
     823              :                 }
     824            2 :         };
     825              : 
     826              :         // Remove all states from the state stack.
     827              :         void emptyStateStack()
     828              :         {
     829              :                 StateEntry *state_ptr,
     830              :                     *next_ptr;
     831              : 
     832              :                 for (state_ptr = _state_stack;
     833              :                      state_ptr != NULL;
     834              :                      state_ptr = next_ptr)
     835              :                 {
     836              :                         next_ptr = state_ptr->getNext();
     837              :                         delete state_ptr;
     838              :                 }
     839              : 
     840              :                 _state_stack = NULL;
     841              :         };
     842              : #endif  // ! SMC_FIXED_STACK
     843              : 
     844              : protected:
     845              :         // Default constructor.
     846            1 :         FSMContext(const State& state)
     847            1 :             : _state(const_cast<State*>(&state)), _previous_state(NULL),
     848              : #ifdef SMC_FIXED_STACK
     849              :             _state_stack_depth(0)
     850              :             ,
     851              : #else
     852            1 :             _state_stack(NULL)
     853              :             ,
     854              : #endif
     855            1 :             _transition(NULL)
     856              :             ,
     857              : #ifdef SMC_USES_IOSTREAMS
     858            1 :             _debug_flag(false)
     859            1 :             , _debug_stream(&std::cerr)
     860              : #else
     861              :             _debug_flag(false)
     862              : #endif  // SMC_USES_IOSTREAMS
     863            1 :                   {};
     864              : 
     865              : private:
     866              :         // I don't believe that it makes sense to copy a
     867              :         // context. It may make sense to copy the application
     868              :         // class but the new object is *not* in the same
     869              :         // state as the old - the new object must start in
     870              :         // the FSM's initial state. Therefore, the copy
     871              :         // constructor is private in order to prevent it
     872              :         // being used.
     873              :         FSMContext(const FSMContext&){};
     874              : 
     875              :         //-----------------------------------------------------------
     876              :         // Member data
     877              :         //
     878              : public:
     879              : protected:
     880              :         // The current state of the finite state machine.
     881              :         State* _state;
     882              : 
     883              :         // Remember which state a transition left.
     884              :         State* _previous_state;
     885              : 
     886              :         // The stack of pushed states.
     887              : #ifdef SMC_FIXED_STACK
     888              :         State* _state_stack[SMC_STATE_STACK_SIZE];
     889              :         int _state_stack_depth;
     890              : #else
     891              :         StateEntry* _state_stack;
     892              : #endif
     893              : 
     894              :         // The current transition *name*. Use for debugging
     895              :         // purposes.
     896              :         char* _transition;
     897              : 
     898              : private:
     899              :         // When this flag is set to true, this class will print
     900              :         // out debug messages.
     901              :         bool _debug_flag;
     902              : 
     903              : // Include the following only if C++ iostreams are being used.
     904              : #ifdef SMC_USES_IOSTREAMS
     905              :         // When FSM debugging is on, debug messages will be
     906              :         // written to this output stream. This stream is set to
     907              :         // standard error by default.
     908              :         std::ostream* _debug_stream;
     909              : #endif  // SMC_USES_IOSTREAMS
     910              : 
     911              : };  // end of class FSMContext
     912              : }  // namespace statemap
     913              : 
     914              : //
     915              : // CHANGE LOG
     916              : // Log: statemap.h,v
     917              : // Revision 1.19  2014/09/06 19:31:28  fperrad
     918              : // remove hard tab
     919              : //
     920              : // Revision 1.18  2013/07/14 14:32:36  cwrapp
     921              : // check in for release 6.2.0
     922              : //
     923              : // Revision 1.17  2011/11/20 14:58:32  cwrapp
     924              : // Check in for SMC v. 6.1.0
     925              : //
     926              : // Revision 1.16  2010/09/11 19:09:38  fperrad
     927              : // remove \r from debug message
     928              : //
     929              : // Revision 1.15  2009/11/24 20:42:39  cwrapp
     930              : // v. 6.0.1 update
     931              : //
     932              : // Revision 1.14  2009/03/01 18:20:40  cwrapp
     933              : // Preliminary v. 6.0.0 commit.
     934              : //
     935              : // Revision 1.13  2008/05/20 18:31:12  cwrapp
     936              : // ----------------------------------------------------------------------
     937              : //
     938              : // Committing release 5.1.0.
     939              : //
     940              : // Modified Files:
     941              : //      Makefile README.txt smc.mk tar_list.txt bin/Smc.jar
     942              : //      examples/Ant/EX1/build.xml examples/Ant/EX2/build.xml
     943              : //      examples/Ant/EX3/build.xml examples/Ant/EX4/build.xml
     944              : //      examples/Ant/EX5/build.xml examples/Ant/EX6/build.xml
     945              : //      examples/Ant/EX7/build.xml examples/Ant/EX7/src/Telephone.java
     946              : //      examples/Java/EX1/Makefile examples/Java/EX4/Makefile
     947              : //      examples/Java/EX5/Makefile examples/Java/EX6/Makefile
     948              : //      examples/Java/EX7/Makefile examples/Ruby/EX1/Makefile
     949              : //      lib/statemap.jar lib/C++/statemap.h lib/Java/Makefile
     950              : //      lib/Php/statemap.php lib/Scala/Makefile
     951              : //      lib/Scala/statemap.scala net/sf/smc/CODE_README.txt
     952              : //      net/sf/smc/README.txt net/sf/smc/Smc.java
     953              : // ----------------------------------------------------------------------
     954              : //
     955              : // Revision 1.12  2007/12/28 12:34:40  cwrapp
     956              : // Version 5.0.1 check-in.
     957              : //
     958              : // Revision 1.11  2007/08/05 12:58:54  cwrapp
     959              : // Version 5.0.1 check-in. See net/sf/smc/CODE_README.txt for more information.
     960              : //
     961              : // Revision 1.10  2007/01/15 00:23:50  cwrapp
     962              : // Release 4.4.0 initial commit.
     963              : //
     964              : // Revision 1.9  2006/07/11 18:28:22  cwrapp
     965              : // Move SmcException::copyString() to a package-wide routine.
     966              : //
     967              : // Revision 1.8  2006/04/22 12:45:24  cwrapp
     968              : // Version 4.3.1
     969              : //
     970              : // Revision 1.7  2005/06/08 11:09:14  cwrapp
     971              : // + Updated Python code generator to place "pass" in methods with empty
     972              : //   bodies.
     973              : // + Corrected FSM errors in Python example 7.
     974              : // + Removed unnecessary includes from C++ examples.
     975              : // + Corrected errors in top-level makefile's distribution build.
     976              : //
     977              : // Revision 1.6  2005/05/28 18:44:13  cwrapp
     978              : // Updated C++, Java and Tcl libraries, added CSharp, Python and VB.
     979              : //
     980              : // Revision 1.2  2005/02/21 19:01:42  charlesr
     981              : // Changed State::_id to State::_stateId because of Object-C++
     982              : // reserved word conflict.
     983              : //
     984              : // Revision 1.1  2004/05/31 13:44:41  charlesr
     985              : // Added support for non-iostreams output.
     986              : //
     987              : // Revision 1.0  2003/12/14 20:37:49  charlesr
     988              : // Initial revision
     989              : 
     990              : #endif
        

Generated by: LCOV version 2.0-1