/*
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 *  SCR_Err.h
 *  Scripts, Beaudet Christophe
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 *
 */
 
#ifndef __SCR_Err_h__Types
#define __SCR_Err_h__Types
 
#ifndef __Only_Types__
#define __SCR_Err_h__Undef
#define __Only_Types__
#endif /* !__Only_Types__ */
 
/*
 *=================================================================================================
 *  Includes.
 *=================================================================================================
 */
 
#include <setjmp.h>
#include "SCR_Cfg.h"
 
#ifdef __SCR_Err_h__Undef
#undef __Only_Types__
#undef __SCR_Err_h__Undef
#endif /* __SCR_Err_h__Undef */
 
/*
 *=================================================================================================
 *  Constants.
 *=================================================================================================
 */
 
/*
 *  To export code.
 */
#undef CPA_EXPORT
#if defined(CPA_WANTS_IMPORT)
#define CPA_EXPORT __declspec(dllimport)
#elif defined(CPA_WANTS_EXPORT)
#define CPA_EXPORT __declspec(dllexport)
#else /* CPA_WANTS_IMPORT */
#define CPA_EXPORT
#endif /* CPA_WANTS_IMPORT */
 
/*
 *  Mode for errors.
 */
#define SCR_CM_Err_Normal               0x0000              /* Normal mode */
#define SCR_CM_Err_NotDisplayInfos      0x0001              /* Not display info to user */
#define SCR_CM_Err_NotUpdateLog         0x0002              /* Not update log file */
 
/*
 *=================================================================================================
 *  Types.
 *=================================================================================================
 */
 
/*
 *  Enum that describes the list of all errors Id.
 */
typedef enum SCR_tde_Err_Identification_
{
    SCR_EI_Err_None,
    /* 
     *  Errors.
     */
#ifdef _DEBUG
    SCR_EI_Err_AssertionFailed,
#endif /* _DEBUG */
    SCR_EI_Err_EndSectionAlone,
    SCR_EI_Err_MissingEndSection,
    SCR_EI_Err_MissingEndSectionMark,
    SCR_EI_Err_MissingEndFormatMark,
    SCR_EI_Err_MissingEndPostFormatMark,
    SCR_EI_Err_MissingEndStringMark,
    SCR_EI_Err_MissingEndVarMark,
    SCR_EI_Err_MissingEndParamsMark,
    SCR_EI_Err_MissingParameters,
    SCR_EI_Err_MissingDirectiveName,
    SCR_EI_Err_CorruptEndOfLine,
    SCR_EI_Err_ReadFile,                        
    SCR_EI_Err_OpenFile,                        
    SCR_EI_Err_CloseFile,
    SCR_EI_Err_WriteFile,
    SCR_EI_Err_CreatePath,
    SCR_EI_Err_UnknownSection,                  
    SCR_EI_Err_NotEnoughMemory,                 
    SCR_EI_Err_AlreadyRegistered,               
    SCR_EI_Err_UnknownDirective,                
    SCR_EI_Err_UnknownVariable,                 
    SCR_EI_Err_UnknownFormat,
    SCR_EI_Err_BadCharacter,
    SCR_EI_Err_BadNumParamsAR,
    SCR_EI_Err_UnknownDynamicFlag,
    SCR_EI_Err_CantConvertScanfFormat,
    SCR_EI_Err_BadNumParamsScanf,
 
    /* 
     *  Warnings.
     *  Error callback is not called.
     *  Dialog box not appeared.
     .  .LOG file is update if it is not disable.
     */
    SCR_EI_Err_UnnecessaryDirective,            
    SCR_EI_Err_SectionWithoutCallback,
 
	/*
	 *	Others...
	 */
	SCR_EI_Err_BadFileName,			/* Fatal error */
} SCR_tde_Err_Identification;
 
/*
 *  Structure that associated an error to an info string.
 */
typedef struct SCR_tdst_Err_Description_
{
    SCR_tde_Err_Identification  eErrorId;               /* Id of error */
    char                        *p_szInfoString;        /* Info string of error */
} SCR_tdst_Err_Description;
 
/*
 *  To describe an error.
 */
typedef struct SCR_tdst_Err_GlobalError_
{
    SCR_tde_Err_Identification  eErrorId;                                   /* Id of error */
    char                        *p_szFileName;                              /* Source file where error occured */
    int                         iLineInFile;                                /* Line in source file where error  occured */
    char                        a_szBufferOut[SCR_CV_ui_Cfg_MaxLenError];   /* To print all optionnal infos */
    char                        a_szBufferTmp[SCR_CV_ui_Cfg_MaxLenError];
    char                        a_szBufferTmp1[SCR_CV_ui_Cfg_MaxLenError];  /* Optionnal infos temp */
    char                        a_szBufferTmp2[SCR_CV_ui_Cfg_MaxLenError];  /* Optionnal infos temp */
} SCR_tdst_Err_GlobalError;
 
/*
 *  To describe a script error handler.
 */
typedef void (* SCR_tdpfn_Err_Callback)(SCR_tdst_Err_GlobalError *);
 
/*
 *  An error context.
 */
typedef struct SCR_tdst_Err_Context_
{
    unsigned int    uiCurrentContext;
    jmp_buf         stMark;
} SCR_tdst_Err_Context;
 
 
#endif /* !__SCR_Err_h__Types */
 
/*
 *=================================================================================================
 *  Global variables.
 *=================================================================================================
 */
 
#if !defined(__SCR_Err_h__Globals) && !defined(__Only_Types__)
#define __SCR_Err_h__Globals
 
extern SCR_tdst_Err_Description             g_a_st_Err_ListErrors[];
CPA_EXPORT extern SCR_tdst_Err_GlobalError  g_st_Err_GlobalError;
extern SCR_tdst_Err_Context                 g_a_st_Err_Context[];
extern int                                  g_i_Err_CurrentContext;
CPA_EXPORT extern SCR_tdpfn_Err_Callback    SCR_g_pfn_Err_Callback;
CPA_EXPORT extern unsigned short            SCR_g_uw_Err_Mode;
CPA_EXPORT extern int						g_i_Err_GlobalReturn;
 
 
#endif /* !__SCR_Err_h__Globals && !__Only_Types__ */
 
/*
 *=================================================================================================
 *  Macros.
 *=================================================================================================
 */
 
#if !defined(__SCR_Err_h__Macros) && !defined(__Only_Types__)
#define __SCR_Err_h__Macros
 
/*
 *  To raise an error.
 *  _Error  :   Error id.
 */
#define SCR_M_Err_RaiseError(_Error)\
{\
    g_st_Err_GlobalError.eErrorId = _Error;\
    g_st_Err_GlobalError.p_szFileName = __FILE__;\
    g_st_Err_GlobalError.iLineInFile = __LINE__;\
    fn_v_Err_SetError();\
}
 
/*
 *  To raise a warning.
 *  _Error  :   Error id.
 */
#define SCR_M_Err_RaiseWarning(_Error)\
{\
    g_st_Err_GlobalError.eErrorId = _Error;\
    g_st_Err_GlobalError.p_szFileName = __FILE__;\
    g_st_Err_GlobalError.iLineInFile = __LINE__;\
    fn_v_Err_SetWarning();\
}
 
/*
 *  To update a_szBufferTmp of global error with the current parsed
 *  file.
 */
#define SCR_M_Err_UpdateSyntaxError()\
{\
    SCR_tdst_Cxt_Description    *_p_stContext_;\
    _p_stContext_ = fnp_st_Cxt_Compute(0);\
    SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext_);\
    sprintf\
    (\
        g_st_Err_GlobalError.a_szBufferTmp1,\
        "Parser stopped in file \"%s\" at line \"%d\".\n",\
        _p_stContext_->p_stOpenFile->stFile.a_szFileName,\
        _p_stContext_->stPosition.uiLineInFile\
    );\
    *g_st_Err_GlobalError.a_szBufferTmp2 = '\0';\
}
 
/*
 *  Equivalent to try and catch of C++.
 */
#define SCR_BEGIN \
{\
    g_i_Err_CurrentContext++;\
    g_a_st_Err_Context[g_i_Err_CurrentContext].uiCurrentContext = SCR_g_st_Cxt_Array.uiNumValues;\
    if(setjmp(g_a_st_Err_Context[g_i_Err_CurrentContext].stMark) == 0)\
    {
 
/*--*/
#define SCR_CATCH \
    }\
    else\
    {
 
/*--*/
#define SCR_END(_Return)\
        if(g_i_Err_CurrentContext != -1)\
            SCR_M_Err_RestoreContext();\
        SCR_RETURN(_Return);\
    }\
    SCR_RETURN(_Return);\
}
 
/*--*/
#define SCR_CEND(_Return)\
    SCR_CATCH\
        if(g_i_Err_CurrentContext != -1)\
            SCR_M_Err_RestoreContext();\
        return _Return;\
    }\
    SCR_RETURN(_Return);\
}
 
/*--*/
#define SCR_RETURN(_Return)\
{\
    g_i_Err_CurrentContext--;\
    return _Return;\
}
    
/*
 *  To restore error context.
 */
#define SCR_M_Err_RestoreContext()\
{\
    g_i_Err_CurrentContext--;\
    SCR_g_st_Cxt_Array.uiNumValues = g_a_st_Err_Context[g_i_Err_CurrentContext + 1].uiCurrentContext;\
    longjmp(g_a_st_Err_Context[g_i_Err_CurrentContext + 1].stMark, 1);\
}
 
#endif /* !__SCR_Err_h__Macros && !__Only_Types__ */
 
/*
 *=================================================================================================
 *  Protos.
 *=================================================================================================
 */
 
#if !defined(__SCR_Err_h__Protos) && !defined(__Only_Types__)
#define __SCR_Err_h__Protos
 
extern void				fn_v_Err_InitModule(void);
extern void				fn_v_Err_CloseModule(void);
 
extern void             fn_v_Err_InitGlobalError(void);
CPA_EXPORT extern void  fn_v_Err_SetError(void);
CPA_EXPORT extern void  fn_v_Err_SetWarning(void);
 
extern void				fn_v_Err_UpdateLogFile(void);
extern int				fn_i_Err_DisplayError(char *, char *);
 
#endif /* !__SCR_Err_h__Protos && !__Only_Types__ */
