/* -*- C++ -*-  vim:set syntax=cpp: 
 *
 * (C) 2004-2010 Frank-Rene Schaefer
 * ABSOLUTELY NO WARRANTY              */
#ifndef __QUEX_INCLUDE_GUARD__ANALYZER__MODE
#define __QUEX_INCLUDE_GUARD__ANALYZER__MODE
#ifndef   QUEX_TYPE_ANALYZER
#   error "Macro QUEX_TYPE_ANALYZER must be defined before inclusion of this file."
#endif

#include <quex/code_base/definitions>

QUEX_NAMESPACE_MAIN_OPEN
    
#   if ! defined(__QUEX_OPTION_PLAIN_C)
    class QUEX_TYPE0_ANALYZER;
#   else
    QUEX_TYPE0_ANALYZER;   
#   endif

    typedef struct QUEX_SETTING_USER_CLASS_DECLARATION_EPILOG QUEX_NAME(Mode_tag) {  
        int                  id;
        const char*          name;

#   if      defined(QUEX_OPTION_INDENTATION_TRIGGER) \
       && ! defined(QUEX_OPTION_INDENTATION_DEFAULT_HANDLER)
        void (*on_indentation)(QUEX_TYPE_ANALYZER*    me, 
                               QUEX_TYPE_INDENTATION  Indentation, 
                               QUEX_TYPE_CHARACTER*   Begin);
#       endif
        void (*on_entry)(QUEX_TYPE_ANALYZER*, const struct QUEX_NAME(Mode_tag)* FromMode);
        void (*on_exit)(QUEX_TYPE_ANALYZER*, const struct QUEX_NAME(Mode_tag)* ToMode);
#       ifdef QUEX_OPTION_RUNTIME_MODE_TRANSITION_CHECK
        bool (*has_base)(const struct QUEX_NAME(Mode_tag)* Mode);
        bool (*has_entry_from)(const struct QUEX_NAME(Mode_tag)* Mode);
        bool (*has_exit_to)(const struct QUEX_NAME(Mode_tag)* Mode);
#       endif

        /* Choose the analyzer function to be the last, because it has a unique
         * signature. The function pointers are assigned in a table. If the 
         * content of this class changes, any mismatch of pointers is likely
         * to trigger a compilation error, thus signalling that the setup is
         * incorrect.                                                        */
        QUEX_NAME(AnalyzerFunctionP)    analyzer_function;
    } QUEX_NAME(Mode);
    
    QUEX_INLINE __QUEX_TYPE_ANALYZER_RETURN_VALUE
    QUEX_NAME(Mode_uncallable_analyzer_function)(QUEX_TYPE_ANALYZER*);

#   if ! defined(QUEX_OPTION_INDENTATION_DEFAULT_HANDLER)
    QUEX_INLINE void
    QUEX_NAME(Mode_on_indentation_null_function)(QUEX_TYPE_ANALYZER*, 
                                                 QUEX_TYPE_CHARACTER* LexemeBegin, 
                                                 QUEX_TYPE_CHARACTER* LexemeEnd);
#   endif

    QUEX_INLINE void
    QUEX_NAME(Mode_on_entry_exit_null_function)(QUEX_TYPE_ANALYZER*, const QUEX_NAME(Mode)*);

    typedef struct QUEX_SETTING_USER_CLASS_DECLARATION_EPILOG {
        QUEX_NAME(Mode)*  (begin[QUEX_SETTING_MODE_STACK_SIZE]);
        QUEX_NAME(Mode)** end;
        QUEX_NAME(Mode)** memory_end;
    } QUEX_NAME(ModeStack);
QUEX_NAMESPACE_MAIN_CLOSE


#endif /* __QUEX_INCLUDE_GUARD__ANALYZER__QUEX_MODE */
