//********************************************************************************************
/**
 * @file		checktxt.cpp
 * @brief		誤植検索
	
		
 * 
 * @author		N.Takeda
 * @date		2007/03/05
 * @date		2011/03/31(木) 11:15:08	N.Takeda	解説文を結果に出力するように修正
 */
//********************************************************************************************

#define	SW_MODULE_CHECKTXT


//#include <stdio.h>
//#include <winsock2.h>


#if 0//ndef _UNICODE
//	設定ファイルを httpから得るテスト.
Int32	_http()
{
	char	*deststr = "www.google.co.jp";
//	char	*deststr = "yyp.jp";
	
	WSADATA				wsaData;
	struct sockaddr_in	stServer;
	SOCKET				sock;
	char				buf[32];
	unsigned int		**addrptr;
	Int32				iErr;
	
	
	if( (iErr = WSAStartup( MAKEWORD( 2,0 ), &wsaData )) != 0 )
	{
		switch(iErr)
		{
			Message_printf("WSAStartup failed : ");
			case WSASYSNOTREADY:
				Message_printf("ネットワークサブシステムがネットワークへの接続を準備できていない\n");
				break;
			case WSAVERNOTSUPPORTED:
				Message_printf("要求されたwinsockのバージョンがサポートされていない\n");
				break;
			case WSAEINPROGRESS:
				Message_printf("ブロッキング操作の実行中であるか、またはサービスプロバイダがコールバック関数を処理している\n");
				break;
			case WSAEPROCLIM:
				Message_printf("winsockが処理できる最大プロセス数に達した\n");
				break;
			case WSAEFAULT:
				Message_printf("第二引数であるlpWSAData は有効なポインタではない\n");
				break;
		}
		return 1;
	}
	
	sock = socket( AF_INET, SOCK_STREAM, 0 );
	if (sock == INVALID_SOCKET) {
		Message_printf("socket : %d\n", WSAGetLastError());
		return 1;
	}

	stServer.sin_family = AF_INET;
	stServer.sin_port = htons(80);	// HTTPのポートは80番です

	stServer.sin_addr.S_un.S_addr = inet_addr(deststr);
	
	if( stServer.sin_addr.S_un.S_addr == 0xffffffff )
	{
		struct hostent	*host;
		
		host = gethostbyname( deststr );
		if (host == NULL) {
			if (WSAGetLastError() == WSAHOST_NOT_FOUND) {
				Message_printf("host not found : %s\n", deststr);
			}else
				Message_printf("unknown error : %s\n", deststr);
			return 1;
		}
		
		addrptr = (unsigned int **)host->h_addr_list;
		
		while( *addrptr != NULL )
		{
			stServer.sin_addr.S_un.S_addr = *(*addrptr);
			Message_printf( "hostent = %s\n", inet_ntoa(stServer.sin_addr) );
			
			// connect()が成功したらloopを抜けます
			if( connect( sock, (struct sockaddr *)&stServer, sizeof(stServer) ) == 0 ){
				break;
			}
			addrptr++;
			// connectが失敗したら次のアドレスで試します
		}
		// connectが全て失敗した場合
		if( *addrptr == NULL ){
			Message_printf( "all connect : %d\n", WSAGetLastError() );
			return 1;
		}
	} else {
		if( connect( sock, (struct sockaddr *)&stServer, sizeof(stServer) ) != 0 ){
			Message_printf("connect : %d\n", WSAGetLastError());
			return 1;
		}
	}

	// HTTPで「/」をリクエストする文字列を生成
	memset( buf, 0, sizeof(buf) );
//	_snprintf( buf, sizeof(buf), "GET / HTTP/1.0\r\n\r\n" );
	STRING_printf( buf, sizeof(buf), TEXT("GET / HTTP/1.0\r\n\r\n") );

	// HTTPリクエスト送信
	Int32	n = send( sock, buf, (Int32)strlen(buf), 0 );
	if( n < 0 ){
		Message_printf( "send : %d\n", WSAGetLastError() );
		return 1;
	}

	// サーバからのHTTPメッセージ受信
	while( n > 0 ){
		memset( buf, 0, sizeof(buf) );
		n = recv(sock, buf, sizeof(buf), 0);
		if( n < 0 ){
			Message_printf( "recv : %d\n", WSAGetLastError() );
			return 1;
		}
		
		// 受信結果を表示
		Message_printf( "%s\n", buf );
	}
	
	closesocket( sock );
	WSACleanup();
	
	return 0;
}
#endif	// _UNICODE


//	ワーニングID.
enum EnWARNING
{
	enWARNING_ENDofSENTENCE1,	//!< 末尾が有効な文字で終っていない
	enWARNING_ANNOTATEMISS,		//!< 注釈抜けの可能性
	enWARNING_NOTLINETOPCHAR,	//!< 行頭に無効な文字
	enWARNING_PARENTHESIZE,		//!< 括弧の数が合わない
	enWARNING_SYMBLESPACE,		//!< 記号に続く空白なし
	enWARNING_EXT,		//!< 
	enWARNING_Max,
};

enum EnNOTETYPE
{
	enNOTETYPE_Script,
	enNOTETYPE_Novel,
	enNOTETYPE_LightNovel,
	enNOTETYPE_Max,
};


#define		SYMBLE_STRING	('\"')

#define		MARKS2D		//!< mark single to dubble 有効にすると既存の '(シングルクォーテーション) を "(ダブルクォーテーション) に変換


#define		POINT_ARROW		TEXT("		←")	//!< ポイント表記記号.

/// 禁止語句カテゴリーの最大数
#define		CATEGORY_MAX		(256)

#define		TITLE_LENGTH		(64)



/// 禁止語句情報.
typedef struct
{
	TCHAR	*m_pWords;					//!< カテゴリーの語句の塊バッファ.
	Int32	m_iEntry;					//!< カテゴリー内のエントリ数.
	TCHAR	m_sTitle[ TITLE_LENGTH ];	//!< カテゴリーの名前.
	
}StWordsCategory;


#ifdef	_DEBUG
//	#define	CHECKLIST_TRACE
#endif


//********************************************************************************************
/**
 * @class		CHECKTXT
 * @brief		スクリプトコマンドクラス
 * @author		N.Takeda
 * @date		2007/03/05
 */
//********************************************************************************************
class CHECKTXT
{
private:
	enum{	enBLongStringMax = 1024	};
	enum{	enBLongMax = 4	};
	struct StBLong
	{
		TCHAR			m_sString[ enBLongStringMax ];
		Int32			m_iLength;
		UInt32			m_uLine;
		TCHAR			m_sPath[ _MAX_PATH ];
	};
	
	enum{	enStringMax = 256	};

	BOOL			m_bInitialized;
	BOOL			m_bImplemented;
	BOOL			m_FullInit;
	
	
	Int32			m_iLine;
	EnNOTETYPE		m_eNoteType;
	Bool			m_bParentNoStart;					//!< 「で始まっていない」
	Bool			m_bParentNoMatch;					//!< 括弧の数が合っていない.
	Bool			m_bBestLongAll;						//!< 長い文検出を全体で行う.
	
	StBLong			m_stBLong[ enBLongMax ];			//!< 長い文の検出.
	
	TCHAR			m_sParentPear[ enStringMax ];		//!< 括弧文字.
	TCHAR			m_sLineTopChar[ enStringMax ];		//!< 行頭になくてはならない文字.
	TCHAR			m_sIllegalSymbol[ enStringMax ];	//!< 行頭に置いてはいけない記号をチェックする.
	TCHAR			m_sEnableEndChar[ enStringMax ];	//!< 。で終わっていなくてもエラーにしない文字.
	TCHAR			m_sSymbleSpace[ enStringMax ];		//!< 続く空白なしをチェックする文字.
	TCHAR			m_sSymbleOk[ enStringMax ];			//!< ↑の例外として認める文字.
	TCHAR			m_sBestLong[ enStringMax ];			//!< 長い文検出時の境界とする文字.
	
	StWordsCategory	*m_stWdCt;							//!< 語句カテゴリー.
	Int32			m_iWcEntry;							//!< 語句カテゴリーエントリ.
	
	TCHAR			m_sRemLine[ 8 ];					//!< 単行注釈記号.
	TCHAR			m_sRemSt[ 8 ];						//!< 範囲注釈開始記号.
	TCHAR			m_sRemEd[ 8 ];						//!< 範囲注釈終端記号.
	
protected:
	void			Initialize( LPCTSTR _pIniFile, LPCTSTR _pParam );
	
	Int32			string_FreeCmp( LPCTSTR ptr, LPCTSTR string );
	Int32			char_check( LPCTSTR ptr, LPCTSTR string );
	void			put_string( Int32 _iLv, LPCTSTR _pPath, LPCTSTR _pMessage, LPCTSTR _pPtr = NULL );
	
	Int32			check_string( LPCTSTR _pPath, LPCTSTR _pPtr, Int32 _iLen );
	Int32			setup( LPCTSTR _pIniFile );
	
	void			mojiCpy( LPTSTR _out, Int32 &_ii, LPCTSTR _mem, Int32 &_jj );
	
	Int32			filt_StringLine( LPTSTR _pBuff, const UInt32 _uBuffMax );
	Int32			filt_StringLine2( LPTSTR _pBuff, const UInt32 _uBuffMax );
	Int32			readInit( LPTSTR &pMem, LPCTSTR _pIniFile );
	
	//! ------- setters ---------
	void	SetLine( const Int32 _iLine ){	m_iLine = _iLine;	}
	//! ------- getters ---------
	Int32	GetLine() const {	return m_iLine;	}
	
public:
	virtual Int32	Func( LPCTSTR _sParamString );
	virtual void	Quit( BOOL _bExit );
	
	CHECKTXT();
	virtual ~CHECKTXT();
	
};

//	アプリケーション起動時
CHECKTXT::CHECKTXT()
 : m_iLine( 1 )
 , m_eNoteType( enNOTETYPE_Script )
 , m_bParentNoStart( FALSE )
 , m_bParentNoMatch( FALSE )
 , m_bBestLongAll( TRUE )		///< 長い文検出を全体で行う.
 , m_stBLong()
 , m_iWcEntry( 0 )	//!< 語句カテゴリーエントリ.
{
	m_FullInit = FALSE;
	m_bInitialized = FALSE;
	m_bImplemented = FALSE;
	
}
//	アプリケーション終了時
CHECKTXT::~CHECKTXT()
{
	
}


//==============================================================================================================================================
//	初期化と開放
//		1ファイルに1つの処理でコンプリートするような場合は修正する必要ありません
//		注釈となっている Message_printf を有効にして sample.swb を実行すると動きがよく分かると思います。
//==============================================================================================================================================

//********************************************************************************************
/**
 * @brief		スクリプトコマンドの初期化
 *				(特に必要ないなら変更の必要なし)
 *
 * @param[in]	LPCTSTR	_pIniFile	ファイル.
 * @param[in]	LPCTSTR	_pParam		.
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	CHECKTXT::Initialize( LPCTSTR _pIniFile, LPCTSTR _pParam )
{
	Int32		ii;
	LPTSTR		pp = NULL;
	
	if(m_bInitialized == TRUE)	return;
	m_bInitialized = TRUE;	//	初期済みフラグ
	
	if(m_FullInit == FALSE){
		m_FullInit = TRUE;
		//	全体を通して一度しか行わない初期化
		
		//Message_printf( TEXT("全体の初期化") );
		
#ifndef _UNICODE
	//	_http();
#endif
	}
	
	//	初期化処理
	//	１つのバッチに同じスクリプトが２度指定されていたならここには２度来る
	//Message_printf( TEXT("初期化") );
	
	m_stWdCt = NULL;
	mem_alloc( StWordsCategory, m_stWdCt, CATEGORY_MAX );
	memset( m_stWdCt, 0, sizeof(StWordsCategory) * CATEGORY_MAX );
	m_iWcEntry = 0;
	
	for( ii=0 ; ii<CATEGORY_MAX ; ii++ )
	{
		m_stWdCt[ii].m_pWords = NULL;
	}
	
	if( setup( _pIniFile ) == 0 )
	{
		Message_error( TEXT("設定ファイル %s が読めません"), _pIniFile );
		return;
	}
	
}


//------------------------------------------------------------------
//		スクリプトコマンドの終了
//			(特に必要ないなら変更の必要なし)
//------------------------------------------------------------------
void	CHECKTXT::Quit( BOOL _bExit )
{
	//	ここにはスクリプトを使っていなくても来るので注意
	
	if( m_bImplemented == FALSE )	return;		//	変換処理が実行されていないなら帰還
	m_bImplemented = FALSE;
	m_bInitialized = FALSE;
	
	//	終了処理
	//Message_printf( TEXT("完了") );
	
	if( m_bBestLongAll )
	{
		if( 0<STRING_len(m_sBestLong) )
		{
			for( Int32 ii = 0 ; ii < enBLongMax ; ii++ )
			{
				if( 0 == m_stBLong[ ii ].m_iLength )	continue;
				Message_printf( TEXT("長	%s(%d): %s"), m_stBLong[ ii ].m_sPath, m_stBLong[ ii ].m_uLine, m_stBLong[ ii ].m_sString );
			}
		}
	}
	
	for(Int32 ii=0 ; ii<CATEGORY_MAX ; ii++)
	{
		mem_del( m_stWdCt[ii].m_pWords );
	}
	mem_del( m_stWdCt );
	
	
	if( _bExit == TRUE )
	{
		//	次のスクリプトは存在しない、完全な終了
		//	１つのバッチに同じスクリプトに別パラメータを渡しての処理で
		//	逐一結果を出さず、全体で統合して結果を出したい場合などはここで
		
		//Message_printf( TEXT("終了") );
		
	}
	
}





//==============================================================================================================================================
//	変換処理部分
//==============================================================================================================================================

#define	CHECKTXT_OUTAREA		2	//	変換後の容量は仮に元の倍取っている　内容によって変更して下さい
#define	CHECKTXT_RANGE				//	このdefineを有効にすると範囲限定機能が有効になる




//------------------------------------------------------------------
//	変換フィルターサンプル　機能:無変換(ファイルコピー)
//			変換せず調査だけなら out に関する部分は不要
//------------------------------------------------------------------
Int32	CHECKTXT::Func( LPCTSTR _sParamString )
{
	CSwbParam	cParam( _sParamString );							//!< パラメータ処理.
	
	TCHAR		name[_MAX_FNAME], ext[_MAX_EXT], sTemp[_MAX_PATH];
	TCHAR		*pMem = NULL;
	Int32		ii, jj, iLen, iMaxLen, ll, ff;
	LPCTSTR		pPath;
	LPTSTR		pInifile, pParam;
	
	
	pPath    = cParam.GetPath();		//!< ターゲットファイル (GetFilePath(0)としても同じ).
	pInifile = cParam.GetString( 1 );	//!< 第1引数をファイルパスとして取得(%0等が変換されて得られる).★ezParamに入れ替える際も GetStringで
	pParam   = cParam.GetStringIndex( 2 );
	
	
	Initialize( pInifile, pParam );

	//	設定ファイルと同名の物はチェックしない
	FILE_split( pPath, NULL, NULL, name, ext );
	FILE_merge( sTemp, NULL, NULL, name, ext );
	STRING_ToBig( sTemp );
	STRING_ToBig( (LPTSTR)pInifile );
	if( STRING_cmp( pInifile, sTemp ) == 0 )	return FALSE;
	
	
	iLen = MEM_TextRead2( &pMem, pPath, 2 );		//!< 倍の容量を確保
	iMaxLen = iLen * 2;
	if(iLen == 0)	return FALSE;		//	ファイルがない
	
	m_bImplemented = TRUE;	//	実行済みフラグ
	
	
	iLen = FILT_deleteREM( pMem, iLen, m_sRemLine, m_sRemSt, m_sRemEd, SYMBLE_STRING );		//!< 行注釈記号,範囲注釈記号始点,範囲注釈記号終点,文字列とする記号.
	
#ifdef MARKS2D	//	'(シングルクォーテーション) は "(ダブルクォーテーション) に変換
	ii = 0;
	while( ii < iLen )
	{
		if(*(pMem+ii) == SYMBLE_STRING)
		{
			ii++;
			while(*(pMem+ii) != SYMBLE_STRING){
				if(++ii >= iLen)	break;
			}
			continue;
		}
#ifndef	_UNICODE
		if( STRING_IsMultiByte( pMem + ii ) )	ii+=2;	//	全角文字だ
		else
#endif
		{
			if(*(pMem+ii)=='\'')	*(pMem+ii) = SYMBLE_STRING;
			ii++;
		}
	}
#endif
	
	switch( m_eNoteType )
	{
		case enNOTETYPE_Script:
			iLen = FILT_StringRelief( pMem, iMaxLen, 0, FALSE );			//文字列化 # は注釈となる可能性があるので見ていない
			break;
		
		case enNOTETYPE_Novel:
			iLen = filt_StringLine( pMem, iMaxLen );
			break;
		
		case enNOTETYPE_LightNovel:
			iLen = filt_StringLine2( pMem, iMaxLen );
			break;
	}
	
	ii = 0;
	#ifdef	CHECKTXT_RANGE
	cRange.Init( pMem, iLen );						//範囲限定機能を有効にするにはこの初期化と
	while(cRange.Is( pMem, ii, iLen ))	ii++;		//　初回スキップ、下の[スキップ判定]が必要。スキップが必要な間trueが返りループしている
	#endif
	
	
	m_iLine = 1;
	jj = 0;
	while(ii < iLen)
	{
		#ifdef	CHECKTXT_RANGE
		while(cRange.Is(pMem,ii,iLen))	ii++;	//	スキップ判定
		#endif
		
		//	文字列までスキップ
		while( *(pMem+ii) != SYMBLE_STRING )
		{
			if(*(pMem+ii) == '\n')	m_iLine++;
			if(++ii >= iLen)	break;
		}
		
		ii++;	//	"の分
		if(ii >= iLen)	break;
		
		//	文字列に全角または\記号が入っているなら 検索対象とする
		ff = ll = 0;
		jj = ii;
		while(*(pMem+jj) != SYMBLE_STRING)
		{
			if(*(pMem+jj) == '\\')	ff = 1;
			if(STRING_IsMultiByte( pMem + jj ) ){
				ff = 1;
			}
			if(*(pMem+jj) == '\n')	ll++;
			if(++jj >= iLen)	break;
		}
		
		if(ff){	//	検索対象
			ii += check_string( pPath, pMem+ii, iLen-ii );
			ii++;	//	"の分
		}else{	//	検索対象外
			m_iLine += ll;
			ii = jj+1;
		}
		
	}

/*
	{
		TCHAR	cPath[_MAX_PATH],drive[_MAX_DRIVE],dir[_MAX_DIR],name[256],ext[_MAX_EXT];
		FILE_split( pPath,drive,dir,name,ext);
		FILE_merge( cPath,drive,dir,name,TEXT("_.txt"));	///<拡張子を".txt"に変えるサンプル.
		
		file_textwrite( cPath, pMem );
	}
*/
	//	メモリを開放
	mem_del(pMem);
	
	
	if( !m_bBestLongAll )
	{
		if( 0<STRING_len(m_sBestLong) )
		{
			for( ii = 0 ; ii < enBLongMax ; ii++ )
			{
				if( 0 == m_stBLong[ ii ].m_iLength )	continue;
				Message_printf( TEXT("長	%s(%d): %s"), m_stBLong[ ii ].m_sPath, m_stBLong[ ii ].m_uLine, m_stBLong[ ii ].m_sString );
				m_stBLong[ ii ].m_iLength = 0;
			}
		}
	}
	
	return TRUE;
}


//********************************************************************************************
/**
 * @brief		check文字列関数.
 *
 * @param[in]	LPCTSTR	_pPath	.
 * @param[in]	LPCTSTR	_pPtr	ポインタ.
 * @param[in]	Int32	_lLen	長さ.
 *
 * @return		Int32	
 */
//********************************************************************************************
Int32	CHECKTXT::check_string( LPCTSTR _pPath, LPCTSTR _pPtr, Int32 _lLen )
{
	Int32		ii, jj, nn, mm, iCt, res, iWordsTop, iCh[ 256 ];
	Bool		bAnnmiss;
	TCHAR		sWork[ 1024 ], sTemp[ 1024 ];
	LPCTSTR		pLast, pOldLast, pWriteSt;
	TCHAR		sMoji[ 4 ];
	
	for( ii=0 ; ii<256 ; ii++ )	iCh[ii] = 0;
	
	
	bAnnmiss = FALSE;
	if( STRING_IsMultiByte(_pPtr) ){	//全角
#ifndef	_UNICODE
		/// マルチバイト全角.
		sMoji[ 0 ] = *(_pPtr);
		sMoji[ 1 ] = *(_pPtr+1);
		sMoji[ 2 ] = 0;
#else
		sMoji[ 0 ] = *(_pPtr);
		sMoji[ 1 ] = 0;
#endif
		if( STRING_len(m_sIllegalSymbol)>0 && STRING_str( m_sIllegalSymbol, sMoji ) != NULL )
		{
			STRING_printf( sWork, 1024, TEXT("注釈記号抜けの可能性") );
			put_string( enWARNING_ANNOTATEMISS, _pPath, sWork );
			bAnnmiss = TRUE;	//!< これにかかると、まず末尾もかかるのでスキップするように.
		}
		
		if( STRING_len(m_sLineTopChar)>0 && STRING_str( m_sLineTopChar, sMoji ) == NULL )
		{
			STRING_printf( sWork, 1024, TEXT("行頭に無効な文字") );
			put_string( enWARNING_NOTLINETOPCHAR, _pPath, sWork );
		}
	}
	
	pOldLast = pLast = NULL;
	ii = 0;
	pWriteSt = _pPtr;
	while( *(_pPtr+ii) != SYMBLE_STRING )
	{
		for( iCt=0 ; iCt<m_iWcEntry ; iCt++ )
		{
			iWordsTop = 0;
			for( jj=0 ; jj<m_stWdCt[ iCt ].m_iEntry ; jj++ )
			{
				Int32	iWordsLength = STRING_len( m_stWdCt[ iCt ].m_pWords + iWordsTop );
				
				/// 改行、タブ、全半角空白をまたいだ文字列照合.
				if( (res = string_FreeCmp( _pPtr+ii, m_stWdCt[ iCt ].m_pWords + iWordsTop )) != 0 )
				{
					mm = 0;
					for( nn=0 ; nn<res ; nn++)
					{
						if( *(_pPtr+ii+nn) != '\r' && *(_pPtr+ii+nn) != '\n' )	//!< 改行を除いてコピー.
							sTemp[mm++] = *(_pPtr+ii+nn);
					}
					sTemp[mm] = 0;
					
					LPCTSTR	pBrief = m_stWdCt[ iCt ].m_pWords + iWordsTop + iWordsLength + 1;
					TCHAR	cSpc[2][8] = { TEXT(""), TEXT("  ") };							//!< 解説があるときの間スペース
					
					STRING_printf( sWork, 1024, TEXT("%sの可能性\"%s\"を含む%s%s"), m_stWdCt[ iCt ].m_sTitle, sTemp, cSpc[(*pBrief)!=0], pBrief );
					put_string( 'A'+iCt, _pPath, sWork, _pPtr );
				}
				/// 次の語句.
				iWordsTop += iWordsLength + 1;
				iWordsTop += STRING_len( m_stWdCt[ iCt ].m_pWords + iWordsTop ) + 1;	//!< 解説.
			}
		}
		
		if( 0 < STRING_len(m_sSymbleSpace) )
		{
			TCHAR	*pRes = STRING_chr( m_sSymbleSpace, *(_pPtr+ii) );
			if( pRes )
			{
				if( *(_pPtr+ii+1) != NULL && *(_pPtr+ii+1) != TEXT('"') && *(_pPtr+ii+1) != '\r' && *(_pPtr+ii+1) != '\n' && *(_pPtr+ii+1) != TEXT('　')/* && !STRING_chr( m_sSymbleSpace, *(_pPtr+ii+1) )*/ )
				{
					Bool	bEnd = FALSE;
					pRes = STRING_chr( m_sSymbleOk, *(_pPtr+ii+1) );
					if( !pRes )
					{
						STRING_printf( sWork, 1024, TEXT("\'%c\'の後に空白が無い"), *(_pPtr+ii) );
						put_string( enWARNING_SYMBLESPACE, _pPath, sWork );
					}
				}
			}
		}
		
		if( STRING_IsMultiByte( _pPtr+ii) )
		{
			TCHAR	*pRes = STRING_chr( m_sParentPear, *(_pPtr+ii) );
			if( pRes )
			{
				Int32	iPar = (pRes - m_sParentPear) / 2;
				Bool	bEnd = (pRes - m_sParentPear) % 2;
				
				if( !bEnd )	iCh[ iPar ]++;
				else{
					if( m_bParentNoStart && 0 == iCh[ iPar ] )
					{
						STRING_printf( sWork, 1024, TEXT("\'%c\'で始まっていない\'%c\'"), m_sParentPear[ iPar*2 ], m_sParentPear[ iPar*2+1 ] );
						put_string( enWARNING_PARENTHESIZE, _pPath, sWork );
					}else{
						iCh[ iPar ]--;
					}
				}
			}
			
			pOldLast = pLast;
			pLast = _pPtr+ii;
#ifndef	_UNICODE
			ii++;															//!< マルチバイト全角.
#endif
		}else{
			pOldLast = pLast;
			pLast = _pPtr+ii;
		}
		ii++;
		
		if( 0<STRING_len(m_sBestLong) && pLast )
		{
			//! 最も長い文の検出.
			Bool	bEnd = (STRING_chr( m_sBestLong, *(pLast) ) != NULL);
			if( *(_pPtr+ii) == SYMBLE_STRING || *(_pPtr+ii) == '\n' || (ii >= _lLen) || bEnd )
			{
				if( (_pPtr+ii-bEnd)-(pWriteSt) > m_stBLong[ 0 ].m_iLength )
				{
					BUF_copy( &m_stBLong[ 1 ], &m_stBLong[ 0 ], sizeof(StBLong) * (enBLongMax-1) );
					
					m_stBLong[ 0 ].m_iLength = (_pPtr+ii-bEnd) - pWriteSt;
					for( mm = 0 ; mm < m_stBLong[ 0 ].m_iLength && mm<enBLongStringMax-1 ; mm++ )	m_stBLong[ 0 ].m_sString[ mm ] = *(pWriteSt + mm);
					m_stBLong[ 0 ].m_sString[ mm ] = '\0';
					
					m_stBLong[ 0 ].m_uLine = m_iLine;
					STRING_cpy( m_stBLong[ 0 ].m_sPath, _pPath );
				}
				pWriteSt = _pPtr+ii;
				while( *pWriteSt == '\n' )	pWriteSt++;
			}
		}
		if( *(_pPtr+ii) == '\n' )
		{
			m_iLine++;
		}
		
		if( ii >= _lLen )	break;
	}
	
	if( 0 )
	{
		const Int32 Range = 8;
		struct StRange{
			Int32	m_iSt;
			Int32	m_iEd;
		};
		StRange	stRange[ 16 ];
		Int32	iRangeEntry = 0;
		
		for( Int32 iRange = Range ; iRange>1 ; iRange-- )
		{
			if( ii > iRange*2+1 )
			{
				for( jj=0 ; jj<ii-iRange*2 ; jj++ )
				{
					Bool	bHit = FALSE;
					for( Int32 nn=0 ; nn<iRangeEntry ; nn++ )
					{
						if( stRange[ nn ].m_iSt <= jj && jj+iRange <= stRange[ nn ].m_iEd )	bHit = TRUE;
					}
					if( bHit )	continue;
					
					STRING_cpy( sTemp, (_pPtr+jj), iRange );
					sTemp[ iRange ] = '\0';
					
					
					for( Int32 nn=jj+iRange+1 ; nn<ii-iRange+1 ; nn++ )
					{
						STRING_cpy( sWork, (_pPtr+nn), iRange );
						sWork[ iRange ] = '\0';
						
						if( STRING_buffcmp( _pPtr+nn, sTemp, NULL ) )
						{
							stRange[ iRangeEntry ].m_iSt = jj;
							stRange[ iRangeEntry ].m_iEd = jj + iRange;
							if( iRangeEntry<15 )	iRangeEntry++;
							
							STRING_printf( sWork, 1024, TEXT("\"%s\"複数同じ言葉"), sTemp );
							put_string( enWARNING_EXT, _pPath, sWork );
						}
					}
					
				}
			}
		}
	}
	
	if( m_bParentNoMatch )
	{
		Int32	iMax = STRING_len( m_sParentPear ) / 2;
		
		for( Int32 ii=0 ; ii<iMax ; ii++ )
		{
			if( iCh[ ii ] > 0 )
			{
				STRING_printf( sWork, 1024, TEXT("%c%cの数が合っていない"), m_sParentPear[ ii*2 ], m_sParentPear[ ii*2+1 ] );
				put_string( enWARNING_PARENTHESIZE, _pPath, sWork );
			}
		}
	}
	
	if( pLast != NULL && bAnnmiss == FALSE )
	{
		if( STRING_len(m_sEnableEndChar) > 0 && char_check( pLast, m_sEnableEndChar ) == 0 ){
			if(pLast-sizeof(TCHAR) != NULL)
			{
				put_string( enWARNING_ENDofSENTENCE1, _pPath, TEXT("末尾が有効な文字で終っていない") );
			}
		}
	}
	
	return ii;
}


//********************************************************************************************
/**
 * @brief		char_check関数
 * @author		N.Takeda
 * @date		2009/08/18(火) 15:43:56
 *
 * @param[in]	LPCTSTR	_pPtr	ポインタ
 * @param[in]	LPCTSTR	_pString	文字列
 *
 * @return		Int32	
 */
//********************************************************************************************
Int32	CHECKTXT::char_check( LPCTSTR _pPtr, LPCTSTR _pString )
{
	Int32		ii;
	
	
#ifndef	_UNICODE
	/// マルチバイト全角.
	for( ii=0 ; ii<STRING_len(_pString) ; ii+=2 )
		if( *(_pPtr)==*(_pString+ii) && *(_pPtr+1)==*(_pString+ii+1) )	return 1;
#else
	for( ii=0 ; ii<STRING_len(_pString) ; ii++ )
	{
		if( *(_pPtr)==*(_pString+ii) )	return 1;
	}
#endif
	
	return 0;
}

//********************************************************************************************
/**
 * @brief		改行、タブ、全半角空白をまたいだ文字列照合
 * @author		N.Takeda
 * @date		2009/08/18(火) 15:44:40
 *
 * @param[in]	LPCTSTR	_pPtr	ポインタ
 * @param[in]	LPCTSTR	_pString	文字列
 *
 * @return		Int32	文字数
 */
//********************************************************************************************
Int32	CHECKTXT::string_FreeCmp( LPCTSTR _pPtr, LPCTSTR _pString )
{
	Int32		ii, jj, frg, iLen;
	
	
	//	いきなりタブ、改行、空白の場合は帰還
#ifndef	_UNICODE
	/// マルチバイト.
	if(*(_pPtr)=='\t' || *(_pPtr)=='\r' || *(_pPtr)=='\n' || *(_pPtr)==' ')	return 0;
	if(*((unsigned char*)_pPtr)==0x81 && *(_pPtr+1)==0x40)					return 0;
#else
	if(*(_pPtr)=='\t' || *(_pPtr)=='\r' || *(_pPtr)=='\n' || *(_pPtr)==' ' || *(_pPtr) == '　')	return 0;
#endif
	
	ii = jj = 0;
	iLen = STRING_len(_pString);
	while(jj < iLen){
		while( 1 )
		{
#ifndef	_UNICODE
			/// マルチバイト.
			if( STRING_IsMultiByte( _pString + jj ) ){	//全角
				if(*((unsigned char*)_pPtr+ii)==0x81 && *(_pPtr+ii+1)==0x40){	ii+=2;	continue;	}
			}else
				if(*(_pPtr+ii)=='\t' || *(_pPtr+ii)=='\r' || *(_pPtr+ii)=='\n' || *(_pPtr+ii)==' '){	ii++;	continue;	}
#else
			if( *(_pPtr+ii)=='\t' || *(_pPtr+ii)=='\r' || *(_pPtr+ii)=='\n' || *(_pPtr+ii)==' ' || *(_pPtr+ii)=='　' ){	ii++;	continue;	}
#endif
			break;
		}
		
		if(*(_pString+jj) == '['){	//正規表現もどき
			jj++;
			
			if(*(_pString+jj) == '^'){	//正規表現もどき
				jj++;
				
				frg = 1;
				do{
#ifndef	_UNICODE
					if( STRING_IsMultiByte( _pString + jj ) ){	//全角
						if(*(_pPtr+ii  ) == *(_pString+jj) && *(_pPtr+ii+1) == *(_pString+jj+1))	frg = 0;
						jj+=2;
					}else
#endif
					if(*(_pPtr+ii) == *(_pString+jj++))	frg = 0;
				}while(*(_pString+jj) != ']' && jj<iLen);
				
			}else{
				
				frg = 0;
				do{
#ifndef	_UNICODE
					if( STRING_IsMultiByte( _pString + jj ) ){	//全角
						if(*(_pPtr+ii  ) == *(_pString+jj) && *(_pPtr+ii+1) == *(_pString+jj+1))	frg = 1;
						jj+=2;
					}else
#endif
					if(*(_pPtr+ii) == *(_pString+jj++))	frg = 1;
				}while(*(_pString+jj) != ']' && jj<iLen);
				
			}
			jj++;
			if(frg == 0)	return 0;
			
#ifndef	_UNICODE
			if( STRING_IsMultiByte( _pPtr + ii ) )	ii++;	//全角
#endif
			ii++;
			
		}else{					//通常
			
#ifndef	_UNICODE
			if( STRING_IsMultiByte( _pString + jj ) )	//全角
				if(*(_pPtr+ii++) != *(_pString+jj++))	return 0;
#endif
			if(*(_pPtr+ii++) != *(_pString+jj++))	return 0;
			
		}
	}
	
	return ii;
}


//********************************************************************************************
/**
 * @brief		行番号の1行を抽出して表示.
 *				未加工のものを表示するために別途ファイルを開く
 * @author		N.Takeda
 *
 * @param[in]	Int32	_iLv		.
 * @param[in]	LPCTSTR	_pPath		該当のパス.
 * @param[in]	LPCTSTR	_pMessage	メッセージ.
 * @param[in]	LPCTSTR	_pPtr		ポインタ.
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	CHECKTXT::put_string( Int32 _iLv, LPCTSTR _pPath, LPCTSTR _pMessage, LPCTSTR _pPtr )
{
	static const Int32	iTmpMax = 1024;										//!< 一行抽出の最大.
	Int32		ii, jj, iLen;
	TCHAR		*pMem = NULL;
	TCHAR		cTemp[ iTmpMax ], cLevel[ 8 ];
	
	
	cTemp[ 0 ] = 0;
	
	iLen = MEM_TextRead( &pMem, _pPath );
	if( 0 >= iLen )
	{
		if( _pPtr )
		{
			/// 改行は除外.
			jj = 0;
			for( ii=0 ; ii<STRING_len(_pPtr) ; ii++ )
			{
				if( *(_pPtr + ii) >= ' ' )	cTemp[ jj++ ] = *(_pPtr + ii);
				if( jj >= iTmpMax-1 )	break;
			}
			cTemp[ jj ] = '\0';
		//	STRING_cpy( cTemp, _pPtr );
		}
	}
	else
	{
		jj = 1;
		ii = 0;
		while(ii < iLen){
			if( jj == m_iLine )	break;
			if(*(pMem+ii) == '\n')	jj++;
			
#ifndef	_UNICODE
			if( STRING_IsMultiByte( pMem + ii ) )	//全角
				ii++;
#endif
			ii++;
		}
		
		jj = 0;
		while(ii < iLen && jj<iTmpMax-1 ){
			cTemp[jj++] = *(pMem+ii++);
			if(*(pMem+ii)=='\r' || *(pMem+ii)=='\n')	break;
		}
		cTemp[jj] = 0;
	}
	
	if( 0 <= _iLv ){
		if(_iLv < enWARNING_Max)	wsprintf( cLevel, TEXT("%d	"), _iLv );
		else						wsprintf( cLevel, TEXT("%c	"), _iLv );
	}else{
		cLevel[0] = 0;
	}
	
	Message_printf( TEXT("%s%s(%d): %s%s%s"), cLevel, _pPath, m_iLine, cTemp, POINT_ARROW, _pMessage );
	
	mem_del( pMem );
	
}


//********************************************************************************************
/*!
 * @brief		一文章を"で括る(改行までを一文とする)
 * @author		N.Takeda
 * @date		2014/06/06(金) 19:23:18
 *
 * @param[in,out]	LPTSTR			_pBuff		バッファ.
 * @param[in]		const UInt32	_uBuffMax	バッファ最大数.
 *
 * @return		Int32	
 */
//********************************************************************************************
Int32	CHECKTXT::filt_StringLine( LPTSTR _pBuff, const UInt32 _uBuffMax )
{
	TCHAR		*pMem = NULL;
	Int32		ii, iLength = 0;
	Int32		iMax = STRING_len(_pBuff);
	Bool		bInner = FALSE;
	
	mem_alloc( TCHAR, pMem, _uBuffMax );
	
	ii = 0;
	while( (*(_pBuff + ii) == '\r' || *(_pBuff + ii) == '\n') && ii<iMax )	*(pMem + iLength++) = *(_pBuff + ii++);
	if( ii<iMax  ){
		*(pMem + iLength++) = TEXT('"');
		bInner = TRUE;
	}
	
	for( ; ii<iMax ; ii++ )
	{
		if( (*(_pBuff + ii) == '\r' || *(_pBuff + ii) == '\n') )
		{
			if( *(_pBuff + ii - 1) != '\n' )
			{
				*(pMem + iLength++) = TEXT('"');
				bInner = !bInner;
			}
			while( (*(_pBuff + ii) == '\r' || *(_pBuff + ii) == '\n') && ii<iMax )
			{
				*(pMem + iLength++) = *(_pBuff + ii++);
			}
			if( *(_pBuff + ii) != '\0' )
			{
				*(pMem + iLength++) = TEXT('"');
				bInner = !bInner;
			}
		}
		*(pMem + iLength++) = *(_pBuff + ii);
	}
	if( bInner )	*(pMem + iLength++) = TEXT('"');
	*(pMem + iLength) = '\0';
	
	BUF_copy( _pBuff, pMem, _uBuffMax * sizeof(TCHAR) );
#ifdef	_DEBUG
	FILE_TextWrite( TEXT("buff.txt"), _pBuff );
#endif
	
	del_alloc( pMem );
	
	return iLength;
}


//********************************************************************************************
/*!
 * @brief		一文章を"で括る(括弧を一文とする)
 * @author		N.Takeda
 * @date		2014/06/06(金) 19:23:18
 *
 * @param[in,out]	LPTSTR			_pBuff		バッファ.
 * @param[in]		const UInt32	_uBuffMax	バッファ最大数.
 *
 * @return		Int32	
 */
//********************************************************************************************
Int32	CHECKTXT::filt_StringLine2( LPTSTR _pBuff, const UInt32 _uBuffMax )
{
	TCHAR		*pMem = NULL;
	Int32		ii, iLength = 0;
	Int32		iMax = STRING_len(_pBuff);
	Int32		iCnt = 0;
	Bool		bInner = FALSE;
	
	
	mem_alloc( TCHAR, pMem, _uBuffMax );
	
	ii = 0;
	while( (*(_pBuff + ii) == '\r' || *(_pBuff + ii) == '\n') && ii<iMax )	*(pMem + iLength++) = *(_pBuff + ii++);
	if( ii<iMax  ){
		*(pMem + iLength++) = TEXT('"');
		bInner = TRUE;
	}
	
	for( ; ii<iMax ; ii++ )
	{
		TCHAR	*pRes = STRING_chr( m_sParentPear, *(_pBuff+ii) );
		if( pRes )
		{
			Bool	bEnd = (pRes - m_sParentPear) % 2;
			
			if( bEnd ){
				if(0<iCnt)	iCnt--;
			}else{
				iCnt++;
			}
		}
		
		if( iCnt == 0 && (*(_pBuff + ii) == '\r' || *(_pBuff + ii) == '\n') )
		{
			if( *(_pBuff + ii - 1) != '\n' )
			{
				*(pMem + iLength++) = TEXT('"');
				bInner = !bInner;
			}
			while( (*(_pBuff + ii) == '\r' || *(_pBuff + ii) == '\n') && ii<iMax )
			{
				*(pMem + iLength++) = *(_pBuff + ii++);
			}
			if( *(_pBuff + ii) != '\0' )
			{
				*(pMem + iLength++) = TEXT('"');
				bInner = !bInner;
			}
			ii--;
			continue;
		}
		*(pMem + iLength++) = *(_pBuff + ii);
	}
	if( bInner )	*(pMem + iLength++) = TEXT('"');
	*(pMem + iLength) = '\0';
	
	BUF_copy( _pBuff, pMem, _uBuffMax * sizeof(TCHAR) );
#ifdef	_DEBUG
	FILE_TextWrite( TEXT("buff.txt"), _pBuff );
#endif
	
	del_alloc( pMem );
	
	return iLength;
}


//********************************************************************************************
/*!
 * @brief		Initの読み込み.
 * @author		N.Takeda
 * @date		2014/08/19(火) 12:58:16
 *
 * @param[in]	LPCTSTR	_pIniFile	ファイル.
 *
 * @return		TCHAR*	
 */
//********************************************************************************************
Int32	CHECKTXT::readInit( LPTSTR &pMem, LPCTSTR _pIniFile )
{
	TCHAR	*pInit = NULL, *pp = NULL, *pPtr1, *pPtr2;
	TCHAR	cPath[ T_MAXPATH ], cTemp[ T_MAXPATH ], cDrive[ T_MAXDRIVE ], cDir[ T_MAXDIR ];
	Int32	iLen, iLength, ii, jj;
	
	
	FILE_split( _pIniFile, cDrive, cDir, NULL, NULL );
	
	iLength = iLen = MEM_TextRead( &pInit, _pIniFile );
//	iLen = FILT_deleteREM( pInit, iLen );		//	C言語注釈削除
	
	pp = pInit;
	while( pp && pp < pInit+iLen )
	{
		pp = STRING_str( pp, TEXT("FILE") );
		if( !pp )	break;
		
		pp += sizeof("FILE") - 1;
		while( *pp < ' ' && pp < pInit+iLen )	pp++;
		if( *pp == '=' )	pp++;
		while( *pp < ' ' && pp < pInit+iLen )	pp++;
		ii = 0;
		while( *pp >= ' ' )	cTemp[ii++] = *pp++;
		cTemp[ii] = '\0';
		
		FILE_merge( cPath, cDrive, cDir, cTemp, NULL );
		
		iLength += FILE_GetSize( cPath );
	}
	
	mem_alloc( TCHAR, pMem, iLength );
	jj = 0;
	
	pPtr1 = pMem;
	pPtr2 = pInit;
	while( pPtr2 && pPtr2 < pInit+iLen )
	{
		pp = STRING_str( pPtr2, TEXT("FILE") );
		if( !pp )	break;
		
		BUF_copy( pPtr1, pPtr2, (pp-pPtr2)*sizeof(TCHAR) );
		pPtr1 += (pp-pPtr2);
		*pPtr1 = '\0';
		
		
		pp += sizeof("FILE") - 1;
		while( *pp < ' ' && pp < pInit+iLen )	pp++;
		if( *pp == '=' )	pp++;
		while( *pp < ' ' && pp < pInit+iLen )	pp++;
		ii = 0;
		while( *pp >= ' ' )	cTemp[ii++] = *pp++;
		cTemp[ii] = '\0';
		
		FILE_merge( cPath, cDrive, cDir, cTemp, NULL );
		pPtr1 += FILE_TextRead( cPath, pPtr1 );
		
		pPtr2 = pp;
	}
	BUF_copy( pPtr1, pPtr2, (iLen-(pPtr2-pInit))*sizeof(TCHAR) );
	pPtr1 += (iLen-(pPtr2-pInit));
	*pPtr1 = '\0';
	
	mem_del( pInit );
	
	return STRING_len( pMem );
}


//********************************************************************************************
/**
 * @brief		setup関数.
 * @author		N.Takeda
 *
 * @param[in]	LPCTSTR	_pIniFile	ファイル.
 *
 * @return		Int32	
 */
//********************************************************************************************
Int32	CHECKTXT::setup( LPCTSTR _pIniFile )
{
	TCHAR	*pMem = NULL, *pp = NULL;
	
	Int32	iLen, ii, jj, iIdx, iBufLen;
	const	TCHAR	cCategoryLabel[] = TEXT("STRING=");
#ifdef	CHECKLIST_TRACE
	Int32	iDebPos=0;
#endif
	
	iLen = readInit( pMem, _pIniFile );
//	iLen = MEM_TextRead( &pMem, _pIniFile );
	if(iLen == 0)	return 0;
#ifdef	_DEBUG
	FILE_TextWrite( TEXT("initFile.txt"), pMem );
#endif
	
	
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("REMLINE"), m_sRemLine, 8 );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("REMSTART"), m_sRemSt, 8 );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("REMEND"), m_sRemEd, 8 );
	
	iLen = FILT_deleteREM( pMem, iLen );		//	C言語注釈削除
	iLen = FILT_excessiveSPACE( pMem, iLen );
	
	m_eNoteType			= (EnNOTETYPE)PROBUFF_GetInt( pMem, iLen, TEXT("MAIN"), TEXT("NOTETYPE"), 0 );
	m_bParentNoStart	= PROBUFF_GetInt( pMem, iLen, TEXT("MAIN"), TEXT("PARENTNOSTART"), 0 );
	m_bParentNoMatch	= PROBUFF_GetInt( pMem, iLen, TEXT("MAIN"), TEXT("PARENTNOMATCH"), 0 );
	
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("PARENTPEAR"),	m_sParentPear,		enStringMax );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("ILLEGALSYMBOL"),	m_sIllegalSymbol,	enStringMax );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("LINETOPCHAR"),	m_sLineTopChar,		enStringMax );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("ENABLEENDCHAR"),	m_sEnableEndChar,	enStringMax );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("SYMBLESPACE"),	m_sSymbleSpace,		enStringMax );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("SYMBLEOK"),		m_sSymbleOk,		enStringMax );
	PROBUFF_GetString( pMem, iLen, TEXT("MAIN"), TEXT("SYMBESTLONG"),	m_sBestLong,		enStringMax );
	
	m_bBestLongAll	= PROBUFF_GetInt( pMem, iLen, TEXT("MAIN"), TEXT("BESTLONGALL"), 1 );
	
	ii = iIdx = 0;
	while( ii < iLen && iIdx < CATEGORY_MAX )
	{
#ifdef	CHECKLIST_TRACE
		iDebPos = 0;
#endif
		/// "STRING="を飛ばす.(冒頭の空白部分もここで飛ばされる)
		while(*(pMem+ii)!='=' && ii<iLen)	ii++;
		if(*(pMem+ii)=='=')	ii++;
		
		/// カテゴリー名取得
		jj = 0;
		while( *(pMem+ii) != '\t' && *(pMem+ii) != '\r' && *(pMem+ii) != '\n' && ii<iLen && jj<(TITLE_LENGTH-1) )
		{
			mojiCpy( m_stWdCt[ iIdx ].m_sTitle, jj, pMem, ii );
		}
		m_stWdCt[ iIdx ].m_sTitle[jj] = 0;
#ifdef	CHECKLIST_TRACE
		_str( TEXT("-------------") );
		_str( m_stWdCt[ iIdx ].m_sTitle );
#endif
		
		while( (*(pMem+ii)=='\r' || *(pMem+ii)=='\n') && ii<iLen )	ii++;
		
		
		/// エントリバッファの長さを調べる. 次のカテゴリー文字サーチ後、ポインタを戻して末端を求めている.
		iBufLen = 0;
		pp = STRING_str( pMem+ii, cCategoryLabel );
		iBufLen = ( pp ) ? (pp - (pMem+ii)) : (iLen - ii);
		while( (*(pMem+ii+iBufLen-1)=='\t' || *(pMem+ii+iBufLen-1)=='\r' || *(pMem+ii+iBufLen-1)=='\n') && iBufLen > 0 )	iBufLen--;
		
#ifdef	_DEBUG
//			FILE_TargetWrite( "ini.bin", pMem+ii, iBufLen );
#endif
		if( iBufLen <= 0 )
		{
			iIdx++;
			continue;
		}
		
		/// 語句バッファ確保.
		Int32	iBuffMax = 2 * iBufLen;	//!< 解説情報の追加分多く必要.
		mem_alloc( TCHAR, m_stWdCt[ iIdx ].m_pWords, iBuffMax+1 );
		T_ASSERTC( m_stWdCt[ iIdx ].m_pWords, TEXT("領域が確保できなかった") );
		
		
		Bool	bBrief = FALSE;			//!< 解説フラグ.
		jj = 0;
		m_stWdCt[ iIdx ].m_iEntry = 1;
		iBufLen += ii;
		while( ii < iBufLen )
		{
			if( *(pMem+ii) == '\t' || *(pMem+ii) == '\r' || *(pMem+ii) == '\n' )
			{
				/// 語句の行末.
				ii++;
				while( *(pMem+ii) == '\t' && ii < iBufLen)	ii++;
				if(*(pMem+ii) == '\n')
				{
					if( bBrief == FALSE )	m_stWdCt[ iIdx ].m_pWords[jj++] = '\0';	//!< 解説がない.
					bBrief = FALSE;		//!< 解説フラグリセット.
					ii++;
					m_stWdCt[ iIdx ].m_iEntry++;
				}else{
					if( bBrief == TRUE )	Message_error( TEXT("設定ファイルに複数の解説が記述されています"), _pIniFile );
					bBrief = TRUE;
				}
				m_stWdCt[ iIdx ].m_pWords[jj++] = '\0';
#ifdef	CHECKLIST_TRACE
				_str( m_stWdCt[ iIdx ].m_pWords + iDebPos );
				iDebPos = jj;
#endif
			}else{
				/// 語句をコピー..
				mojiCpy( m_stWdCt[ iIdx ].m_pWords, jj, pMem, ii );
			}
			
			T_ASSERTC( (jj<iBuffMax), TEXT("領域をオーバー") );
		}
		if(jj==0)	m_stWdCt[ iIdx ].m_iEntry = 0;
		
		if( bBrief == FALSE )	m_stWdCt[ iIdx ].m_pWords[jj++] = '\0';	//!< 解説がない.
		m_stWdCt[ iIdx ].m_pWords[jj] = '\0';
		
#ifdef	CHECKLIST_TRACE
		_str( m_stWdCt[ iIdx ].m_pWords + iDebPos );
#endif
		
#ifdef	_DEBUG
//			FILE_TargetWrite( "d.bin", m_stWdCt[ iIdx ].m_pWords, jj+1 );
#endif
		iIdx++;
	}
	
	m_iWcEntry = iIdx;
	
	mem_del( pMem );
	
	return 1;
}


//********************************************************************************************
/**
 * @brief		1文字コピー(UNICODE考慮)
 * @author		N.Takeda
 * @date		2011/03/30(水) 19:11:25
 *
 * @param[in,out]	LPTSTR	_out	.
 * @param[in,out]	Int32&	_ii		.
 * @param[in]		LPCTSTR	_mem	.
 * @param[in,out]	Int32&	_jj		.
 *
 * @return		Int32	
 */
//********************************************************************************************
void	CHECKTXT::mojiCpy( LPTSTR _out, Int32 &_jj, LPCTSTR _mem, Int32 &_ii )
{
	T_ASSERTC( _out, TEXT("コピー先が不正") );
	T_ASSERTC( _mem, TEXT("コピー元が不正") );
	
#ifndef	_UNICODE
	if( STRING_IsMultiByte( _mem + _ii ) )	//!< 全角.
	{
		*(_out + _jj++) = *(_mem + _ii++);
	}
#endif
	*(_out + _jj++) = *(_mem + _ii++);
}

CHECKTXT	*pC_checktxt = NULL;

#undef	SYMBLE_STRING
