

/*!
  @author d金魚
*/


#ifndef DKINGYO_MACRO____//一回だけ読み込む
#define DKINGYO_MACRO____

#include "dkutilCompileOption.h"

#ifdef USE_DKINGYO_INCLUDE_SETTING_LIKE_BOOST
#	include <dkutil/config/dkutilConfig.h>
#else
#	if DKUTIL_COMPILE_OPTION_MSVC
#		include "config/dkutilConfig.h"
#	else
#		include "dkutilConfig.h"
#	endif
#endif

///GetLastError 可視化
#define VISUAL_LASTERROR() \
{\
  LPVOID lpMsgBuf;\
  FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,\
			   NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL );\
  ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );\
  LocalFree( lpMsgBuf );\
}



#ifdef _DEBUG
/*!
<PRE>
注意：
例えば以下のようにしないこと
if(hogehoge == hoge) DEBUGMB("ERROR");
訂正
if(hogehoge == hoge) { DEBUGMB("ERROR"); }
</PRE>
*/
///デバッグ時のみのメッセージボックス
#	define DEBUGMB(s) ::MessageBox(NULL,s,"DEBUG MESSAGE BOX",MB_OK)
///デバッグ時のみのOutputDebugString 注意:DEBUGMB()を見てください。
#	define DEBUGODS(s) ::OutputDebugString(s)
///デバッグ時のみのassart
#	include <assert.h>
#	define DEBUGASSERT(s) assert(s)
#else
#	define DEBUGMB(s) {} //念のため{}でもつけておく
#	define DEBUGODS(s) {}
#	define DEBUGASSERT(s) {}
#endif


/*!
SET_VA_LISTの文字列の最後に'\n'を付け足すバージョン<br>
文字列バッファが全部埋まっている場合でも強制的に付け足す。<br>
また、strncatにバッファ数を指定しても文字列最後のNULL文字を破壊する行為)も回避します。<br>
@param s[out] char *のバッファを入れる
@param snum[in] バッファの数
@param origin[in] 元の文字列
*/
///SET_VA_LISTの文字列の最後に'\n'を付け足すバージョン
///警告･･･これにバッファオーバーフロウの危険性があるかも！？誰か指摘してクレイ･･･
#define SET_VA_LIST_INSERT_YEN_N(s,snum,origin) \
	{\
		SET_VA_LIST(s,snum,origin);\
		size_t len = strlen(s);\
		bool isYen = s[len-1] != '\n';\
		if(len >= snum - 1){\
			if(isYen){\
				s[len-1]='\n';\
			}\
		}else{\
			if(isYen){\
				s[len] = '\n';\
				s[len + 1] = '\0';\
			}\
		}\
	}
/*
#define SET_VA_LIST_INSERT_YEN_N(s,snum,origin) \
	{\
		SET_VA_LIST(s,snum,origin);\
		size_t len = strlen(s);\
		if(s[len-1] != '\n'){\
			if(len >= snum - 1){\
				s[len-1]='\n';\
			}else{\
				strncat(s,"\n",len);\
			}\
		}\
	}*/
/*
//可変引数関数を作る時,文字列バッファを使う場合に必要なバッファの数を得る
#define GET_VALIST_CHAR_BUFF_NUM(origin) \
	{
		va_list VaList;\
		va_start( VaList , origin ) ;\
		int len = strlen(origin);
		for(int i=0;i<len;i++){
			if (_ismbblead((int) origin[i])){
				i++;
				continue;
			}
			if(origin[i] == '%'){//％を見つけたなり
				if(!(i + 1 >= len)){//バッファオーバーフローしないようであれば
					switch(origin[i+1]){
					case 'c'://文字
					case 's'://文字列
					case 'd'://
					case 'u':

				 printf("%i : %o - 符号付8進数（%dと冗長）と符号なし8進数\n" , 0xff , 0xff);
        printf("%x : %X - 符号なし16進数、小文字と大文字\n" , 0xff , 0xff);

        printf("%e : %E - [-]d.dddd e [sign]ddd 形式符号付きの値\n" , 1.24 , 1.24);
        printf("%f - [-]dddd.dddd 形式の符号付きの値\n" , 1.24);
        printf("%g : %G - f,eうち精度を表現できる短い方の書式\n" , 1.24 , 1.24);

        printf("%s : %S - ヌル文字までの文字列\n", STR , STR);

        printf("Kitty%n <- ここまでの出力数を保存\n" , &i);
        printf("%d - ストリームまたはバッファに書き込まれた文字数\n" , i);
        printf("%p - ポインタを表示\n" , i);
*/
/*!
@param result[out] 成功したかどうかを返す true = 成功 false = 失敗
@prama s[out] char *　の変数を渡す。これに文字列を格納する内部でmallocするのでEND_GET_MANY_ARGを呼び出すこと
@param add[in] size_t (unsigned long)型の文字列拡張バッファのbyte単位の数を渡す。大体200前後が目安(凄い長い文字列の場合はやっぱりかなり必要になりそう
@param str[in] 元の文字列を渡す
*/
///沢山引数をつける関数のサポート(高機能版)
#define BEGIN_GET_MANY_ARG(result,s,add,str) \
	{ \
		size_t strnum = strlen(str) + add;\
		s = (char *)::malloc(strnum);\
		result = false;\
		if(s){\
			SET_VA_LIST(s,strnum,str);\
			result = true;\
		}\
	}
/*!
@param mem[in] BEGIN_GET_MANY_ARGのsでもらったものを渡す
*/
///沢山引数をつける関数のサポートを終了する
#define END_GET_MANY_ARG(mem) \
	{\
		if(mem){::free(mem);mem=NULL;}\
	}

//	WARNINGマクロ(yane SDKより
#ifdef _DEBUG
#	define DK_WARNING(s) {\
	CHAR buf[256];				\
	wsprintf(buf,"%sファイルの%d行 \n%s",__FILE__,__LINE__,s);	\
	MessageBox(NULL,buf,"WARNING!!",MB_OK);	\
	* LPLONG(0x00000000) = 0;	\
	}
#	define YANE_WARNING(b,s)				\
		if(b) {						\
			CHAR buf[256];				\
			wsprintf(buf,"%sファイルの%d行 %s\n",__FILE__,__LINE__,s);	\
			MessageBox(NULL,buf,"WARNING!!",MB_OK);	\
			* LPLONG(0xcdcdcdcd) = 0;	\
		}
	//	最後の* LPLONG(0xcdcdcdcd) = 0;の部分は、メモリエラーをわざと起こすコード
#else
#	define YANE_WARNING(var,s) {}
#	define DK_WARNING(s) 
#endif

//**********************************************************
//その他もろもろのセッティング
//**********************************************************

///状況に応じてインラインを作る(dkutilはC++オンリーだからすでにもう無用のものかも！？
#ifdef __cplusplus
#	define DINLINE inline
#	if _MSC_VER >= 1200
#		undef DINLINE
#		define DINLINE __inline
#	endif//end of __inline
#else
#	define DINLINE 
#endif//end of __cplusplus

//ユーザーが例外処理を使うかどうか？
#ifdef USE_DKINGYO_THROW
///ユーザーが例外処理を使うかどうか？しない場合はMessageBoxが表示されるその後強制終了。
#	define DK_THROW(str) throw str
///USE_DKINGYOTHROWが定義されていた場合std::bad_alloc()は有効
#	define DK_BAD_ALLOC() std::bad_alloc()

#	include <assert.h>
///assがTRUEの時アサートする。USE_DKINGYO_THROWが定義されていたらTHROWする。
#	define DK_TRUE_ASSERT_OR_THROW(ass,thr) \
	{if(ass){\
		throw thr;\
	}}

#else
#	define DK_THROW(str) { \
	char buff[2056];\
	_snprintf(buff,"例外処理が発生しました. -> %s",str);\
	MessageBox(NULL,buff,"例外発生",MB_OK);\ 
	ERROR_BOX("file:%s \nline : %d",__FILE__,__LINE__);
	exit(-1);\
}
#	define DK_BAD_ALLOC() ((void)0)

#	define DK_TRUE_ASSERT_OR_THROW(ass,thr) \
	{if(ass){\
		assert(!ass);\
	}}
#endif//end of USE_DKINGYO_THROW



#ifndef BOOST_NO_PRIVATE_IN_AGGREGATE //なぜか boost 対応･･･

#	define BOOST_PROTECTED public
#	define BOOST_PRIVATE public

#else
#	define BOOST_PROTECTED protected
#	define BOOST_PRIVATE private
#endif

#ifndef numof
#	define numof(s) ( sizeof(s) / sizeof(s[0]) )
#endif

#endif//end of DKINGYO_MACRO____ once include defined