#ifndef __FmRegExp_h
#define __FmRegExp_h

#pragma warning(disable: 4786)	// C4786_xZkqqHx_iMhIiNjAiCpAiPgPiCmIiCkNiClHiCoJiBeC_xHqqkZx_
#pragma warning(disable: 4503)	// C4503_xZkqqHx_iMhIiNjAiCpAiPgPiCmIiCkNiClHiCoJiBeC_xHqqkZx_

#include <map>			// For map.
#include <string>		// For wstring.

// STL_xZkqqHx_iCmMjGlMjBePiLpDiKnEiCpAjAnNjCoIiBeC_xHqqkZx_
using namespace std;

#include "../FmRegExpNFAW.h"

/*************************************************************************
 * <_xZkqqHx_iDeOiDiJiDfI_xHqqkZx_>	FmError
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	FMTL_xZkqqHx_jCiGiCmFjEkNjAlGiClHiCoJiDeHiDiJiBfLiCpAiDfIiDiNiBfLiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.11 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
class FmError
{
public:
	// _xZkqqHx_iDeHiDiJiBfLiDiBiDgCiDfKiBfLiDfHiIoKjHjHiBeC_xHqqkZx_
	enum ErrCode
	{
// 06.12.22 Fukushiro M. 1_xZkqqHx_iNhDjFmPiNfI_xHqqkZx_ ()
//		NONE,
		NONE = 0,
		WRONG_SEARCH_FORMULA,	// _xZkqqHx_iMjPiNpFjFlGiOjKjHpBiCmJiMoLiCoIiCkKiCkAiCoIiCnMiClHiBeC_xHqqkZx_
		WRONG_REPLACE_FORMULA,	// _xZkqqHx_jChFiKlHjFlGiOjKjHpBiCmJiMoLiCoIiCkKiCkAiCoIiCnMiClHiBeC_xHqqkZx_
		CANNOT_LOAD_DLL,		// _xZkqqHx_jAlDiLeLjFfMiMlLiMjPiNpFiDiJiDeDiDhFiDiJiDiKiCkKjDmHiCnNiNjOiCnPiCnMiClJiCpBiBeC_xHqqkZx_
		WRONG_FORM_DLL,			// _xZkqqHx_jAlDiLeLjFfMiMlLiMjPiNpFiDiJiDeDiDhFiDiJiDiKiCmJjGoCjBoIiCkKiCkAiCoIiCnMiClHiBeC_xHqqkZx_
	};

public:
	/*************************************************************************
	 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FmError
	 *
	 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDfCiDjDiDfIiDgHiDiJiDeOiDfOiBeC_xHqqkZx_
	 *
	 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	errCode		:_xZkqqHx_iDeHiDiJiBfLiDfCiBfLiDgIiCpAiOhHjCoIiBeC_xHqqkZx_
	 *			wcpMessage	:_xZkqqHx_iDeHiDiJiBfLiDiBiDgCiDfKiBfLiDfHiCpAiOhHjCoIiBeC_xHqqkZx_
	 *
	 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.11 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
	 *************************************************************************/
	FmError (ErrCode errCode, const wchar_t* wcpMessage)
		:	m_errCode(errCode),
			m_wstrMessage(wcpMessage) {}

	/*************************************************************************
	 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	Throw
	 *
	 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDeHiDiJiBfLiCpAiDfIiDiNiBfLiClHiCoJiBeC_xHqqkZx_
	 *
	 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	errCode		:_xZkqqHx_iDeHiDiJiBfLiDfCiBfLiDgIiCpAiOhHjCoIiBeC_xHqqkZx_
	 *			wcpMessage	:_xZkqqHx_iDeHiDiJiBfLiDiBiDgCiDfKiBfLiDfHiCpAiOhHjCoIiBeC_xHqqkZx_
	 *
	 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.11 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
	 *************************************************************************/
	static void	Throw (ErrCode errCode, const wchar_t* wcpMessage)
		{
			throw new FmError(errCode, wcpMessage);
		}

public:
	ErrCode	m_errCode;		// _xZkqqHx_iDeHiDiJiBfLiDfCiBfLiDgIiBeC_xHqqkZx_
	wstring	m_wstrMessage;	// _xZkqqHx_iDeHiDiJiBfLiDiBiDgCiDfKiBfLiDfHiBeC_xHqqkZx_
}; // class FmError.

/*************************************************************************
 * <_xZkqqHx_iDeOiDiJiDfI_xHqqkZx_>	_FmRegExp
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_jAlDiLeLjFfMiMlLiMjPiNpFiCpAiOmAiMlLiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.11 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
class _FmRegExp
{
public:
// 06.12.22 Fukushiro M. 1_xZkqqHx_iNhDjFmPiNfI_xHqqkZx_ ()
//	_FmRegExp ();
	_FmRegExp (const _TCHAR* tcpDirPath = NULL);
	~_FmRegExp ();
	BOOL	IsMatch (WStringConst& wscTextConst, const wchar_t* wcpExp, WORD wFlags = DREX_EXP_NONE);
	void	GetReplaceText (wstring& wstrRepText, const wchar_t* wcpRepForm) const;
	BOOL	GetBackReference (wstring& wstrRefText, int index) const;
	static void	ConvToReplaceForm (wstring& wstrRepForm, const wchar_t* wcpRepExp);
	static BOOL	ConvertEscStr (	wstring& wstrOut, const wchar_t*& wcpStr,
								const wchar_t wcaEndCode[], int iEndCodeSz);

protected:
	FmRegExpNFA*	GetObject (const wchar_t* wcpExp, WORD wFlags);

protected:
	map<wstring, FmRegExpNFA*>	m_mpExpToObject;// _xZkqqHx_iMjPiNpFiOkO_xHqqkZx_ -> _xZkqqHx_iMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCmMiDgOiDgCiDfGiDiFiBeC_xHqqkZx_
	FmRegExpNFA*	m_pLastObject;				// _xZkqqHx_iNmFiMoDiCmMiMjPiNpFiCmFiOgHiCoNiCoKiClNiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiBeC_xHqqkZx_

	static int				s_iModuleCount;		// _xZkqqHx_jAlDiLeLjFfMiMlLiDiJiDeDiDhFiDiJiDiK_xHqqkZx_(DLL)_xZkqqHx_iCmMiDiNiBfLiDgIiDeKiDeFiDjDiDfOiBeC_xHqqkZx_
	static HMODULE			s_hModule;			// _xZkqqHx_jAlDiLeLjFfMiMlLiDiJiDeDiDhFiDiJiDiK_xHqqkZx_(DLL)_xZkqqHx_iCmMiDiCiDfHiDiFiBfLiDiLiDgOiDjDiDgIiDiLiBeC_xHqqkZx_
	static FuncFmfCreate	s_pfnFmfCreate;		// DLL_xZkqqHx_iCmMiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiNoMjAkMiKnGjAjEiDhMiDeDiDjDiDfOiBeC_xHqqkZx_
	static FuncFmfDelete	s_pfnFmfDelete;		// DLL_xZkqqHx_iCmMiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiNoNiPjMiKnGjAjEiDhMiDeDiDjDiDfOiBeC_xHqqkZx_

	static const wchar_t	FDSP_WCH_DOLLAR;	// _xZkqqHx_jChFiKlHiDhEiDeIiBfLiDiAjCiGiCmFiOgHiCoNiCoKiCoJiBeBiMoDjFpLiOfBiPmG_xHqqkZx_'$'_xZkqqHx_iCpAjFfMiClHiDfCiBfLiDgIiBeC_xHqqkZx_
	static const wchar_t	FDST_CHR_ESC;		// '\'_xZkqqHx_iBeC_xHqqkZx_
}; // class _FmRegExp.

template<class T> int _FmRegExp<T>::s_iModuleCount = 0;
template<class T> HMODULE _FmRegExp<T>::s_hModule = NULL;
template<class T> FuncFmfCreate _FmRegExp<T>::s_pfnFmfCreate = NULL;
template<class T> FuncFmfDelete _FmRegExp<T>::s_pfnFmfDelete = NULL;
template<class T> const wchar_t _FmRegExp<T>::FDSP_WCH_DOLLAR = 0xffff;
template<class T> const wchar_t _FmRegExp<T>::FDST_CHR_ESC = L'\\';

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::_FmRegExp
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	tcpDirPath	:_xZkqqHx_jAlDiLeLjFfMiMlLiDiJiDeDiDhFiDiJiDiK_xHqqkZx_DLL_xZkqqHx_iCmMiDgGiDeCiDiMiDeOiDgHiDiKiDhAiDfIiCpAiOhHjCoIiBeC_xHqqkZx_
 *						 _xZkqqHx_iNmFiMoDiCmJ_xHqqkZx_'\'_xZkqqHx_iCkKjFhEiCkCiCmEiCkCiCmEiCoAiCkCiCmIiCkPiCoKiCmOiCmIiCoHiCmIiCkCiBeC_xHqqkZx_
 *						 NULL_xZkqqHx_iCmMiPoKiNiHiCmNiBeBiDgGiDhEiDeIiDiLiDgHiCkJiCoHiDiNiBfLiDgIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDgGiDhEiDeIiDiLiDgHiDfCiDjDiDfIiDgHiDiJiDeOiDfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	_xZkqqHx_iDeBiDhGiDiK_xHqqkZx_->DLL->FmRegExp _xZkqqHx_iCmGjHjIjHhAiClHiCoJiPoKiNiHiBeBiDgGiDhEiDeIiDiLiDgHiCmMiDhAiDfIiCmN_xHqqkZx_
 *			DLL_xZkqqHx_iCmFiCmNiCmIiCkNiDeBiDhGiDiKiCmMiDhAiDfIiCmJiCmIiCoJiClBiCmGiCmJjCiNiInDiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.10 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
// 06.12.22 Fukushiro M. 1_xZkqqHx_iNhDjFmPiNfI_xHqqkZx_ ()
//_FmRegExp<T>::_FmRegExp ()
_FmRegExp<T>::_FmRegExp (const _TCHAR* tcpDirPath)
{
	m_pLastObject = NULL;

	//----- _xZkqqHx_iDiJiDeDiDhFiDiJiDiKiCmMiDiNiBfLiDgI_xHqqkZx_ -----
	s_iModuleCount++;
	if (s_iModuleCount == 1)
	//----- _xZkqqHx_iNmFiPiJiCmMiDiJiDeDiDhFiDiJiDiKiDiNiBfLiDgIiCmMiPoKiNiH_xHqqkZx_ -----
	{
//----- 06.12.22 Fukushiro M. _xZkqqHx_jFmPiNfIjBeP_xHqqkZx_ ()-----
//		// _xZkqqHx_iDiJiDeDiDhFiDiJiDiK_xHqqkZx_(DLL)_xZkqqHx_iCpAiDiNiBfLiDgIiClHiCoJiBeC_xHqqkZx_
//		s_hModule = LoadLibrary(_T("FmRegExpNFAU.dll"));
//----- 06.12.22 Fukushiro M. _xZkqqHx_jFmPiNfIiMoD_xHqqkZx_ ()-----
		basic_string<_TCHAR> tstrPath;
		//----- _xZkqqHx_iDiJiDeDiDhFiDiJiDiKiCmMiDgGiDeCiDiMiDeOiDgHiDiKiCkKiOhHjCoIiClDiCoKiCmEiCkCiCoJiPoKiNiH_xHqqkZx_ -----
		if (tcpDirPath != NULL)
			tstrPath += tcpDirPath;
		tstrPath += _T("FmRegExpNFAU.dll");
		// _xZkqqHx_iDiJiDeDiDhFiDiJiDiK_xHqqkZx_(DLL)_xZkqqHx_iCpAiDiNiBfLiDgIiClHiCoJiBeC_xHqqkZx_
		s_hModule = LoadLibrary(tstrPath.c_str());
//----- 06.12.22 Fukushiro M. _xZkqqHx_jFmPiNfIiPeJ_xHqqkZx_ ()-----
		// _xZkqqHx_iDiNiBfLiDgIiCmJiOlIjEhDiClFiClNiPoKiNiHiCmNiDeHiDiJiBfLiBeC_xHqqkZx_
		if (s_hModule == NULL)
			FmError::Throw(FmError::CANNOT_LOAD_DLL, L"FmRegExpNFAU.dll");
		// _xZkqqHx_iKnGjAjEiCmMiDhMiDeDiDjDiDfOiCpAiOoGjDlOiBeC_xHqqkZx_
		s_pfnFmfCreate = (FuncFmfCreate)GetProcAddress(s_hModule, "FmfCreate");
		s_pfnFmfDelete = (FuncFmfDelete)GetProcAddress(s_hModule, "FmfDelete");
		// _xZkqqHx_iKnGjAjEiCmMiDhMiDeDiDjDiDfOiCkKiOoGjDlOiPgPjHiIiCmIiCkCiPoKiNiHiCmNiDeHiDiJiBfLiBeC_xHqqkZx_
		if (s_pfnFmfCreate == NULL || s_pfnFmfDelete == NULL)
			FmError::Throw(FmError::WRONG_FORM_DLL, L"FmRegExpNFAU.dll");
	}
} // _FmRegExp<T>::_FmRegExp (const _TCHAR* tcpDirPath);

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::~_FmRegExp
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDgGiDfIiDgHiDiJiDeOiDfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.10 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
_FmRegExp<T>::~_FmRegExp ()
{
	// _xZkqqHx_iMjPiNpFiOkO_xHqqkZx_ -> _xZkqqHx_iMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCmMiDgOiDgCiDfGiDiFiCpAiJpAjFpKiClHiCoJiBeC_xHqqkZx_
	map<wstring, FmRegExpNFA*>::iterator iEto;
	for (iEto = m_mpExpToObject.begin(); iEto != m_mpExpToObject.end(); iEto++)
		(*s_pfnFmfDelete)((*iEto).second);
	m_mpExpToObject.clear();
	m_pLastObject = NULL;

	//----- _xZkqqHx_iDiJiDeDiDhFiDiJiDiKiCmMiJpAjFpK_xHqqkZx_ -----
	s_iModuleCount--;
	if (s_iModuleCount == 0)
	//----- _xZkqqHx_iNmFiMoDiCmMiDiJiDeDiDhFiDiJiDiKiJpAjFpKiCmMiPoKiNiH_xHqqkZx_ -----
	{
		// _xZkqqHx_iDiJiDeDiDhFiDiJiDiKiCpAiJpAjFpKiBeC_xHqqkZx_
		FreeLibrary(s_hModule);
		s_hModule = NULL;
		s_pfnFmfCreate = NULL;
		s_pfnFmfDelete = NULL;
	}
} // _FmRegExp<T>::~_FmRegExp ();

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::IsMatch
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOhHjCoIiClDiCoKiClNiDgFiDeMiDfIiDgHiCpAiBeBiOhHjCoIiClDiCoKiClNiMjPiNpFiOkOiCmFiMjPiNpFiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	wscTextCount:_xZkqqHx_iMjPiNpFjBmOiPnLiCmMiDgFiDeMiDfIiDgHiCpAiOhHjCoIiBeCiMjPiNpFiCkKiDhBiDgCiDgHiClFiClNiPoKiNiHiCmN_xHqqkZx_
 *						 _xZkqqHx_iDhBiDgCiDgHiClFiClNjEmNiImNiCpAjFnEiClHiBeC_xHqqkZx_
 *			wcpExp		:_xZkqqHx_iMjPiNpFiOkOiCpAiOhHjCoIiBeC_xHqqkZx_
 *			wFlags		:_xZkqqHx_iMjPiNpFiDeJiDhGiDfGiDiHiDjDiCpAiOhHjCoIiBeC_xHqqkZx_
 *				DREX_EXP_TO_UPCASE	:_xZkqqHx_jBoFjFlGiOjKiBeBiPkMjFlGiOjKiCpAiLoGjFmKiClJiClIiMjPiNpFiBeC_xHqqkZx_
//----- 06.09.07 Fukushiro M. _xZkqqHx_jCmHiJmBiOgO_xHqqkZx_ ()-----
 *				DREX_EXP_ALLOW_SINGLE_ASSERTION
 *									:_xZkqqHx_iMlOjGlOiOhBiCmMjCfAjDmGjHjIjHhAiCpAiLjGiJmCiBeC_xHqqkZx_
//----- 06.09.07 Fukushiro M. _xZkqqHx_jCmHiJmBiPeJ_xHqqkZx_ ()-----
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iMjPiNpFiCkKiDhBiDgCiDgHiClFiClNiPoKiNiHiCmN_xHqqkZx_TRUE_xZkqqHx_iBeC_xHqqkZx_
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	wscTextCount _xZkqqHx_iCmFiCmNiBeB_xHqqkZx_GetBegin()_xZkqqHx_iBgA_xHqqkZx_GetEnd()_xZkqqHx_iCmMjEmNiImNiCmMiCnNiCpAiMjPiNpFiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.10 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
BOOL _FmRegExp<T>::IsMatch (WStringConst& wscTextConst, const wchar_t* wcpExp, WORD wFlags)
{
	// _xZkqqHx_iMjPiNpFiOkOiCkJiCoHiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCpAiOoGjDlOiBeC_xHqqkZx_
	// GetObject_xZkqqHx_iKnGjAjEjCiGiCmMiPiIjHjNiCmNiImIiJlKiBeC_xHqqkZx_
	// _xZkqqHx_iBjMiMjPiNpFiOkOiCmJiIoKjChGiClHiCoJiKpJjBlGiCmMiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCkKjBlGiNnNiClHiCoJiPoKiNiHiCmN_xHqqkZx_
	//   _xZkqqHx_iClLiCoKiCpAjFnEiClHiBeC_xHqqkZx_
	// _xZkqqHx_iBjMjBlGiNnNiClFiCmIiCkCiPoKiNiHiCmNiBeBjAfGiClFiCkNiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCpAiNoMjAkMiClFiBeB_xHqqkZx_
	//   wcpExp_xZkqqHx_iCpAjDgPjIfOiClHiCoJiBeC_xHqqkZx_
	m_pLastObject = GetObject(wcpExp, wFlags);
	// _xZkqqHx_iMjPiNpFiKeKiOgOiImKjChFiCmMiIoKiCmCjBePiCmMjFlGiOjKiCpAiOoGjDlOiBeC_xHqqkZx_
	WORD wPreChar = wscTextConst.GetAt(-1);
	// _xZkqqHx_iMjPiNpFiKeKiOgOiImKjChFiCpAiOoGjDlOiBeC_xHqqkZx_
	const wchar_t* wcpText = wscTextConst.GetBegin();
	while (wcpText != wscTextConst.GetEnd())
	//----- _xZkqqHx_iMjPiNpFjEmNiImNiCmMiPeJjCfLiCnMiCmF_xHqqkZx_ -----
	{
		// _xZkqqHx_iMjPiNpFiKeKiOgOiImKjChFiCpAiLeMjIfOiBeC_xHqqkZx_
		const wchar_t* wcpTextBackup = wcpText;
		// wcpText_xZkqqHx_iCmMiImKjChFiCkKiMjPiNpFiOkOiCmJiDhBiDgCiDgHiClHiCoJiCkJjClCiCnHiCoJiBeC_xHqqkZx_
		if (m_pLastObject->IsMatch(wPreChar, wcpText, wscTextConst.GetEnd()))
		//----- _xZkqqHx_iMjPiNpFiOkOiCmJiDhBiDgCiDgHiClHiCoJiPoKiNiH_xHqqkZx_ -----
		{
			// wcpText _xZkqqHx_iCmNiBeB_xHqqkZx_IsMatch_xZkqqHx_iKnGjAjEjCiGiCmFiDhBiDgCiDgHjEmNiImNiCmMiOjPiCnGjAgJiCnPiCoHiCoKiCmEiCkCiCoJiBeC_xHqqkZx_
			// wscTextConst _xZkqqHx_iCmJiDhBiDgCiDgHiClFiClNjEmNiImNiCpAjAnNjCoIiBeC_xHqqkZx_
			wscTextConst.SetBegin(wcpTextBackup);
			wscTextConst.SetEnd(wcpText);
			return TRUE;
		}
		// wcpText_xZkqqHx_iCmMiImKjChFiCmNiMjPiNpFiOkOiCmJiDhBiDgCiDgHiClFiCmIiCkJiCmBiClNiBeC_xHqqkZx_
		// wcpText_xZkqqHx_iCmMiImKjChFiCpAiIoKiCmCiMoDjFpLiCnGiInKjDkOiClFiBeBiClLiClBiCkJiCoHiMjPiNpFiCpAiClHiCoJiBeC_xHqqkZx_
		wPreChar = *wcpText;
		wcpText++;
	}
	return FALSE;
} // _FmRegExp<T>::IsMatch (WStringConst& wscTextConst, const wchar_t* wcpExp, WORD wFlags);

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::GetReplaceText
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	IsMatch_xZkqqHx_iCmFiMjPiNpFiOkOiCmJiDhBiDgCiDgHiClFiClNiPoKiNiHiBeBiDhBiDgCiDgHjEmNiImNiCpAjChFiKlHiClHiCoJiClNiCnPiCmM_xHqqkZx_
 *			_xZkqqHx_jFlGiOjKjHpBiCpAiNoMjAkMiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	wstrRepText	:_xZkqqHx_jChFiKlHjFlGiOjKjHpBiCpAjFnEiClHiBeC_xHqqkZx_
 *			wcpRepForm	:_xZkqqHx_jChFiKlHiDhEiDeIiBfLiDiAiCpAiOhHjCoIiBeCjChFiKlHiDhEiDeIiBfLiDiAiCmNjHfMiCnP_xHqqkZx_
 *						 ConvToReplaceForm_xZkqqHx_iKnGjAjEiCmFiNoMjAkMiClFiCmEiCkIiCkNiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	_xZkqqHx_iMoDjFpLiOfBiPmG_xHqqkZx_($1,$2,${1}_xZkqqHx_jDjJ_xHqqkZx_)_xZkqqHx_iCpAiOgHiCmBiCmEjChFiKlHjFlGiOjKjHpBiCpAiNoMjAkMiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.11 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
void _FmRegExp<T>::GetReplaceText (wstring& wstrRepText, const wchar_t* wcpRepForm) const
{
	// _xZkqqHx_jChFiKlHjFlGiOjKjHpBiCpAiLpDiCmJiBeC_xHqqkZx_
	wstrRepText.erase();
	while (*wcpRepForm != L'\0')
	//----- _xZkqqHx_jChFiKlHiDhEiDeIiBfLiDiAiCmMiPeJjHlJiImKjChFiCnMiCmF_xHqqkZx_ -----
	{
		if (*wcpRepForm == FDSP_WCH_DOLLAR)
		//----- _xZkqqHx_jChFiKlHiDhEiDeIiBfLiDiAiCkK_xHqqkZx_'$'_xZkqqHx_iCmMiPoKiNiH_xHqqkZx_ -----
		{
			// '$'_xZkqqHx_iCpAiDfIiDeMiDgCiDhGiBeC_xHqqkZx_
			wcpRepForm++;
			// *wcpRepForm_xZkqqHx_iCmJ_xHqqkZx_ $n(n_xZkqqHx_iCmNiOfBiPmGiDeDiDjDiDgGiDgCiDeOiDfI_xHqqkZx_)_xZkqqHx_iCmM_xHqqkZx_'n'_xZkqqHx_iCkKjFnLjBlGiClDiCoKiCmEiCkCiCoJiBeC_xHqqkZx_
			// _xZkqqHx_iOfBiPmGiDeDiDjDiDgGiDgCiDeOiDfIiCpAiOoGjDlOiBeC_xHqqkZx_
			int index = *wcpRepForm - 1;
			const wchar_t* wcpFrom;
			const wchar_t* wcpTo;
			// _xZkqqHx_iOfBiPmGiDeDiDjDiDgGiDgCiDeOiDfIiCmJjBmOiJjOiClHiCoJjFlGiOjKjHpB_xHqqkZx_(IsMatch_xZkqqHx_iCmFiDhBiDgCiDgH_xHqqkZx_)_xZkqqHx_iCpAiOoGjDlOiBeC_xHqqkZx_
			m_pLastObject->GetMatchStr(wcpFrom, wcpTo, index);
			// _xZkqqHx_iOfBiPmGjFlGiOjKjHpBiCkKjBlGiNnNiClHiCoJiPoKiNiHiCmNiBeBiClLiCmMjFlGiOjKjHpBiCpAjChFiKlHjFlGiOjKjHpBiCmJjBhNjDpMiBeC_xHqqkZx_
			if (wcpFrom != NULL)
				wstrRepText.insert(wstrRepText.end(), wcpFrom, wcpTo);
		} else
		//----- _xZkqqHx_jCmKiPoNiCmMjFlGiOjKiCmMiPoKiNiH_xHqqkZx_ -----
		{
			// _xZkqqHx_jChFiKlHjFlGiOjKjHpBiCmJjCmHiJmBiBeC_xHqqkZx_
			wstrRepText += *wcpRepForm;
		}
		// _xZkqqHx_jChFiKlHiDhEiDeIiBfLiDiAiCpAiIoKiCmCjAgJiCnPiCoJiBeC_xHqqkZx_
		wcpRepForm++;
	}
} // _FmRegExp<T>::GetReplaceText (wstring& wstrRepText, const wchar_t* wcpRepForm) const;

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::GetBackReference
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iMoDjFpLiOfBiPmGiCmMjFlGiOjKjHpBiCpAiOoGjDlOiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	wstrRefText	:_xZkqqHx_iMoDjFpLiOfBiPmGiDgFiDeMiDfIiDgHiCpAjFnEiClHiBeC_xHqqkZx_
 *			index		:_xZkqqHx_iMoDjFpLiOfBiPmGiDeDiDjDiDgGiDgCiDeOiDfIiCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iMoDjFpLiOfBiPmGiCmJiDhNiDgCiDgAiClHiCoJjFlGiOjKjHpBiCkKjBlGiNnNiClFiCmIiCkCiPoKiNiHiCmN_xHqqkZx_ FALSE_xZkqqHx_iBeC_xHqqkZx_
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	_xZkqqHx_iMjPiNpFiOkO_xHqqkZx_ "(.*)hello(.*)" _xZkqqHx_iCmFiMjPiNpFiClFiClNiPoKiNiHiBeB_xHqqkZx_index = 1 _xZkqqHx_iCmFiCmN_xHqqkZx_
 *			_xZkqqHx_iNmFiPiJiCmMiKiHiMmKiCmMiOfBiPmGiBeB_xHqqkZx_index = 2_xZkqqHx_iCmFiCmNiNmFiMoDiCmMiKiHiMmKiCmMiOfBiPmGiCpAiOoGjDlOiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.12 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
BOOL _FmRegExp<T>::GetBackReference (wstring& wstrRefText, int index) const
{
	const wchar_t* wcpFrom;
	const wchar_t* wcpTo;
	// _xZkqqHx_iOfBiPmGiDeDiDjDiDgGiDgCiDeOiDfIiCmJjBmOiJjOiClHiCoJjFlGiOjKjHpB_xHqqkZx_(IsMatch_xZkqqHx_iCmFiDhBiDgCiDgH_xHqqkZx_)_xZkqqHx_iCpAiOoGjDlOiBeC_xHqqkZx_
	m_pLastObject->GetMatchStr(wcpFrom, wcpTo, index - 1);
	// _xZkqqHx_iOfBiPmGjFlGiOjKjHpBiCkKjBlGiNnNiClFiCmIiCkCiPoKiNiHiCmN_xHqqkZx_ FALSE _xZkqqHx_iCpAjFnEiClHiBeC_xHqqkZx_
	if (wcpFrom == NULL) return FALSE;
	wstrRefText.clear();
	wstrRefText.insert(wstrRefText.end(), wcpFrom, wcpTo);
	return TRUE;
} // _FmRegExp<T>::GetBackReference (wstring& wstrRefText, int index) const;

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::ConvToReplaceForm
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_jChFiKlHiOkOiCpAiBeBjChFiKlHiDhEiDeIiBfLiDiAiCmJjFmPiKlHiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	wstrRepForm	:_xZkqqHx_jChFiKlHiDhEiDeIiBfLiDiAiCpAjFnEiClHiBeC_xHqqkZx_
 *			wcpRepExp	:_xZkqqHx_jChFiKlHiOkOiCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	IsMatch_xZkqqHx_iCmFiDhBiDgCiDgHiClHiCoJiClNiCnBiCmJiBeBjChFiKlHiOkOiCpAiJpAjAmNiClFiCmEjChFiKlHjFlGiOjKjHpBiCpAiNoMjAkM_xHqqkZx_
 *			_xZkqqHx_iClFiCmEiCkCiCmEiCmNiBeBiOjOiKnEiDiNiDfIiCkKjBoFiCkLiCkCiBeC_xHqqkZx_
 *			_xZkqqHx_jHfMiCnPiBeBjChFiKlHjFlGiOjKjHpBiCpAjAlGjAkMiClFiCoCiClHiCkCiMgAiOkOiBgJjChFiKlHiDhEiDeIiBfLiDiAiBgKiCmJjFmPiKlHiClFiCmE_xHqqkZx_
 *			_xZkqqHx_iCkIiCkCiCmEiBeB_xHqqkZx_IsMatch_xZkqqHx_iMoDiCmJiClHiCkOjChFiKlHjFlGiOjKjHpBiCkKjAlGjAkMiCmFiCkLiCoJiCoGiCkEiCmJiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.11 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
void _FmRegExp<T>::ConvToReplaceForm (wstring& wstrRepForm, const wchar_t* wcpRepExp)
{
	// _xZkqqHx_jChFiKlHiMoDjFlGiOjKjHpBiCpAiPmBiLiOiBeC_xHqqkZx_
	wstrRepForm.erase();
	wchar_t wcEndCode = L'\0';	// _xZkqqHx_iPeJjHlJjFlGiOjKiBeC_xHqqkZx_
	if (*wcpRepExp == L'/')
	//----- _xZkqqHx_iDfIiDiJiDgCiDfGiDiF_xHqqkZx_ '/' _xZkqqHx_iCmFiOgOiCnMiCoJiPoKiNiH_xHqqkZx_ -----
	{
		wcEndCode = L'/';
		wcpRepExp++;
	}
	// ConvertEscStr_xZkqqHx_iCmMiPeJjHlJiDfCiBfLiDgIiDiKiDfIiDgHiCpAiNoMjAkMiBeC_xHqqkZx_
	const wchar_t wcaEndCode[] = { L'$', wcEndCode };
	const int iEncodeSz = sizeof(wcaEndCode) / sizeof(wcaEndCode[0]);
	wstring wstrOut;
	for (;;)
	{
		// _xZkqqHx_iDeHiDfIiDfAiBfLiDhGiDfCiBfLiDgIiCpAjFmPiKlHiBeC_xHqqkZx_
		if (!ConvertEscStr(wstrOut, wcpRepExp, wcaEndCode, iEncodeSz))
			FmError::Throw(FmError::WRONG_REPLACE_FORMULA, wcpRepExp);
		// _xZkqqHx_jFmPiKlHjFlGiOjKjHpBiCpAjCmHiJmBiBeC_xHqqkZx_
		wstrRepForm.insert(wstrRepForm.end(), wstrOut.begin(), wstrOut.end());
		// _xZkqqHx_jFlGiOjKjHpB_xHqqkZx_ $ _xZkqqHx_iImIiKePiBgJiPeJjHlJiDfCiBfLiDgIiBgKiCmIiCoHiCmOiPeJjHlJiBeC_xHqqkZx_
		if (*wcpRepExp != L'$') break;
		//----- '$'_xZkqqHx_iCmMiPoKiNiH_xHqqkZx_ -----
		wstrRepForm += FDSP_WCH_DOLLAR;
		// '$'_xZkqqHx_iCpAiDfIiDeMiDgCiDhGiBeC_xHqqkZx_
		wcpRepExp++;
		if (*wcpRepExp == L'{')
		//----- ${n}_xZkqqHx_iMgAiOkOiCmMiPoKiNiH_xHqqkZx_ -----
		{
			// '{'_xZkqqHx_iCpAiDfIiDeMiDgCiDhGiBeC_xHqqkZx_
			wcpRepExp++;
			wchar_t idx = (wchar_t)wcstol(wcpRepExp, (wchar_t**)&wcpRepExp, 10);
			// ${_xZkqqHx_iCmMiMoDiCoLiCmNjFeLiClI_xHqqkZx_1_xZkqqHx_iImIiPoDiCmM_xHqqkZx_10_xZkqqHx_jAgJjAjEiCmFiCmIiCkPiCoKiCmOiCmIiCoHiCmIiCkCiBeC_xHqqkZx_
			if (idx == 0 || *wcpRepExp != L'}')
				FmError::Throw(FmError::WRONG_REPLACE_FORMULA, wcpRepExp);
			// '}'_xZkqqHx_iCpAiDfIiDeMiDgCiDhGiBeC_xHqqkZx_
			wcpRepExp++;
			wstrRepForm += idx;
		} else
		//----- $n_xZkqqHx_iMgAiOkOiCmMiPoKiNiH_xHqqkZx_ -----
		{
			wchar_t idx = (wchar_t)wcstol(wcpRepExp, (wchar_t**)&wcpRepExp, 10);
			// $_xZkqqHx_iCmMiMoDiCoLiCmNjFeLiClI_xHqqkZx_1_xZkqqHx_iImIiPoDiCmM_xHqqkZx_10_xZkqqHx_jAgJjAjEiCmFiCmIiCkPiCoKiCmOiCmIiCoHiCmIiCkCiBeC_xHqqkZx_
			if (idx == 0)
				FmError::Throw(FmError::WRONG_REPLACE_FORMULA, wcpRepExp);
			wstrRepForm += idx;
		}
	}
	wstrRepForm += L'\0';
} // _FmRegExp<T>::ConvToReplaceForm (wstring& wstrRepForm, const wchar_t* wcpRepExp);

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::ConvertEscStr
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	
 *
 * <_xZkqqHx_iPnKiNnH_xHqqkZx_>	
 *
 * <_xZkqqHx_jCiNiInD_xHqqkZx_>	
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.11 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
BOOL _FmRegExp<T>::ConvertEscStr (	wstring& wstrOut, const wchar_t*& wcpStr,
									const wchar_t wcaEndCode[], int iEndCodeSz)
{
	wstrOut.erase();
	// _xZkqqHx_jEpBiDeHiDfIiDfAiBfLiDhGiPpDjBnEiCpAjAnNjCoIiBeC_xHqqkZx_
	BOOL bEsc = FALSE;
	for (;;)
	{
		if (bEsc)
		//----- _xZkqqHx_iDeHiDfIiDfAiBfLiDhGiPpDjBnEiCmMiPoKiNiH_xHqqkZx_ -----
		{
			// _xZkqqHx_jEpBiDeHiDfIiDfAiBfLiDhGiPpDjBnEiCmJiBeC_xHqqkZx_
			bEsc = FALSE;
			switch (*wcpStr)
			{
			case L'\0':	// _xZkqqHx_iLpDjFlGiOjKiBeC_xHqqkZx_
				return FALSE;	// _xZkqqHx_iDeHiDiJiBfLiBeC_xHqqkZx_
			case L'r':	// _xZkqqHx_jFjMiLeBiBeC_xHqqkZx_
				wstrOut += L'\r';
				break;
			case L'n':	// _xZkqqHx_iJpMiNhDiBeC_xHqqkZx_
				wstrOut += L'\n';
				break;
			case L't':	// _xZkqqHx_iDfOiDhFiBeC_xHqqkZx_
				wstrOut += L'\t';
				break;
			default:
				wstrOut += *wcpStr;
			}
		} else
		//----- _xZkqqHx_jEpBiDeHiDfIiDfAiBfLiDhGiPpDjBnEiCmMiPoKiNiH_xHqqkZx_ -----
		{
			//----- _xZkqqHx_iPeJjHlJiDfCiBfLiDgIiCmMiMjPiNlI_xHqqkZx_ -----
			for (int iC = 0; iC < iEndCodeSz; iC++)
				if (*wcpStr == wcaEndCode[iC]) return TRUE;

			if (*wcpStr == FDST_CHR_ESC)
			//----- _xZkqqHx_iDeHiDfIiDfAiBfLiDhGjFlGiOjKiCmMiPoKiNiH_xHqqkZx_ -----
			{
				bEsc = TRUE;
			} else
			if (*wcpStr == L'\0')
			//----- _xZkqqHx_iLpDjFlGiOjKiCmMiPoKiNiH_xHqqkZx_ -----
			{
				return FALSE;	// _xZkqqHx_iDeHiDiJiBfLiBeC_xHqqkZx_
			} else
			{
				wstrOut += *wcpStr;
			}
		}
		// _xZkqqHx_iOjPiCmMjFlGiOjKiCmJiInKjDkOiBeC_xHqqkZx_
		wcpStr++;
	}
	return FALSE;
} // _FmRegExp<T>::ConvertEscStr.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	_FmRegExp<T>::GetObject
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	
 *
 * <_xZkqqHx_iPnKiNnH_xHqqkZx_>	
 *
 * <_xZkqqHx_jCiNiInD_xHqqkZx_>	
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.05.10 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
template<class T>
FmRegExpNFA* _FmRegExp<T>::GetObject (const wchar_t* wcpExp, WORD wFlags)
{
	// _xZkqqHx_jDgPjIfOiMgAiOkOiCmMiMjPiNpFiOkOiBeC_xHqqkZx_"i/XXXX" _xZkqqHx_iCmGiCkCiCkEiCoGiCkEiCmJiBeBjAoGjDkKiCmJiDhEiDiJiDePiCmG_xHqqkZx_/_xZkqqHx_iCpAjBhNjDpMiBeC_xHqqkZx_
	wstring wstrExp;
	// _xZkqqHx_iMjPiNpFiOkOiCmMjFlGiOjKjFjEjFkKiCpAjDoAjFjEiCmFjBoFjFlGiOjKiCnGjFmPiKlHiBeC_xHqqkZx_
	if (wFlags & DREX_EXP_TO_UPCASE) wstrExp += L'i';
	wstrExp += L'/';
	wstrExp += wcpExp;
	FmRegExpNFA* pObj = m_mpExpToObject[wstrExp];
	if (pObj == NULL)
	//----- _xZkqqHx_iMjPiNpFiOkOiCkKjGkCjDgPjIfOiCmMiPoKiNiH_xHqqkZx_ -----
	{
		// _xZkqqHx_iMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCpAiNoMjAkMiBeC_xHqqkZx_
		pObj = (*s_pfnFmfCreate)();
		// _xZkqqHx_iMjPiNpFiOkOiCpAiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCmJjAnNjCoIiBeC_xHqqkZx_
		if (!pObj->SetExpression(wcpExp, wFlags))
			FmError::Throw(FmError::WRONG_SEARCH_FORMULA, wcpExp);
		// _xZkqqHx_iMjPiNpFiOkOiCmGiMjPiNpFiDeJiDhFiDfHiDeGiDeOiDgHiCpAjDgPjIfOiBeC_xHqqkZx_
		m_mpExpToObject[wstrExp] = pObj;
	}
	return pObj;
} // _FmRegExp<T>::GetObject (const wchar_t* wcpExp, WORD wFlags);

typedef _FmRegExp<void> FmRegExp;

#endif __FmRegExp_h
