/*------------------------------------------------------------------------------*
 *	File Name: 	OCCompileUtils.h							 					*
 *	Purpose:																   	*
 *  Creation:	11/02/2004, AW													*
 *  	Copyright Originlab Corp. 2003, 2004,									*
 *	Modification log	                                                        *
 *	AW 11/02/04 QA80-6968 v8.0178 EXPORT_PRECOMPILE_UTIL_FUNCTION_FRO_OCH		*
 *	AW 03/0805 v8.0199 QA80-7472 MORE_ON_SPC_CHM_PRECOMPILE						*
 *------------------------------------------------------------------------------*/      

#ifndef _OCCOMPILEUTILS_H
#define _OCCOMPILEUTILS_H

#define SPC_CHM_PRECOMPILE

#ifdef __AFX_H__
	#ifdef OCOMPILER_AS_EXTDLL
		#define OC_API __declspec(dllexport)
	#else
		#define OC_API __declspec(dllimport)
	#endif
	extern "C" {
#else
	#define OC_API
	#define LPTSTR	LPSTR
	#pragma dll(OCompiler80)	// Associate all functions below to OCTree.dll which must be in the Origin EXE folder
#endif	//__AFX_H__

#ifdef SPC_CHM_PRECOMPILE

#define PRECOMPILING_ERROR			-1
#define PRECOMPILING_NEED_SAVING	0
#define PRECOMPILING_NO_SAVING		1


/**	Init precompile for CHM project
	1) Add a temp fildnode in CompileManager as current fileNode, so we can use it for macros
	2) Set version build, so, when we choose diff version number can make diff CHM result
*/
OC_API BOOL spc_init_precompiler(LPCSTR lpcszOCVerName,  LPCSTR lpcszOCVerContent);

/**	
	must be called at the end, release tempfilenode used for macros
*/
OC_API void spc_release_precompiler();

/**
	Add macro, no need line number and file name here.
*/
OC_API BOOL spc_pre_add_macro(LPCSTR lpszName,  LPCSTR lpszContent = NULL);

/**
	Parameters:
		lpsz:	line for parsing undef macro, no "#" started. 	
	Return: 
		NULL when it is not #undef, otherwise return undef macro name

*/
/// AW 03/0805 v8.0199 QA80-7472 MORE_ON_SPC_CHM_PRECOMPILE
// no need following 3 functions
//OC_API LPTSTR spc_get_undef_macro(LPTSTR lpsz);


/**	parsing #define macro (arg) body
	call this function need declare as following
		char		szName[3*MAXLINE];// to hold things like #define, and macroName(arg,arg,...)
	After call this function then call AddMacro(szName, nArgs, lpArgList, nLine, lpstr)) to finish Add Macro;
		LPCTSTR		lpArgList[MAX_NUM_OF_ARGS_ALLOWED];
   Arguments:
		lpsz = define macro....
	Return: 
		return TRUE if yes and OK
		return FALSE if not macro define, or syntax error (need to set *lpnErr to indicate)
			macro name = szName
			macro arg  = lpArgList, nArgs = 0 if no argument 
			macro body = lpstr
*/
//OC_API BOOL spc_get_define_macro(LPTSTR lpsz, UINT* lpnErr, LPCTSTR szName, LPCTSTR lpArgList, int& nArgs, LPTSTR lpstr);

/** handle the following
	#ifdef
	....
	#elif
	.....
	#elif
	.....
	#else
	.....
	#endif
	In fact, the #if, #elif, #else, and #endif Directives, like switch, 
	only one will be true, so I add lpUseLineState[] to record this state,

// return TRUE if proper ifdef etc
// return FALSE if no any of the ifdef type
// also return FALSE if mismatch endif, or syntax error (need to set *lpnErr to indicate)
when lpUseLineState[index] is not true, we need check if it is true,
otherwise, it is FALSE  
*/
//OC_API BOOL spc_is_ifdef_ifndef_else_endif(LPCTSTR lpszLine, LPINT lpIfDefCount, BOOL *lpUseLines, BOOL *lpUseLineState, UINT* lpnErr);
/// END MORE_ON_SPC_CHM_PRECOMPILE

/** handle precompile 1) #define, #if, etc
	Return:
		PRECOMPILING_ERROR: error, fatmet is wrong;
		PRECOMPILING_NEED_SAVING: useful line, need be saved;
		PRECOMPILING_NO_SAVING: unuseful line, no need saved;
*/
OC_API int spc_precompile_string(LPCTSTR lpcszLine, LPINT lpIfDefCount, BOOL *lpUseLines, BOOL *lpUseLineState);

///////////////////////////END//////////////////////////////////////

#endif //SPC_CHM_PRECOMPILE

#ifdef __AFX_H__
	}
#endif	//__AFX_H__

#endif //_OCTREEUTILS_H

