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
|