/**
 * @file  osw_error.c
 * @brief osw error ヘッダー
 * osw のエラーに関する機能をまとめたヘッダーファイルです.
 *
 * Copyright (c)  2003 - 2015  Nomura Kei
 * License : THE MIT License <http://opensource.org/licenses/mit-license.php>
 */
#include <osw_error.h>
#include <error.h>



/**
 * 最後に発生したエラー番号を取得します.
 *
 * @return エラー番号
 */
osw_error_t osw_geterror(void)
{
#if (OSW_isWindows)
	return GetLastError();
#else
	return errno;
#endif
}



/**
 * エラー番号を設定します.
 *
 * @param errnum エラー番号
 */
void osw_seterror(osw_error_t errnum)
{
#if (OSW_isWindows)
	SetLastError(errnum);
#else
	errno = errnum;
#endif
}



/**
 * 指定されたエラーコードに対する, エラーメッセージを取得します.
 *
 * @param msgbuf メッセージ格納用のバッファ
 * @param buflen バッファのサイズ
 * @param errnum エラー番号
 * @return true/false (取得成功/失敗)
 */
bool osw_geterrormsg(char* msgbuf, size_t buflen, osw_error_t errnum)
{
#if (OSW_isWindows)
	/* Windows の場合												*/
	int ret = FormatMessage(
			FORMAT_MESSAGE_FROM_SYSTEM,		/* 動作フラグ			*/
			NULL,							/* エラーコード			*/
			errnum,							/* エラー番号			*/
			0,								/* 言語ID				*/
			msgbuf,							/* バッファアドレス		*/
			buflen,							/* バッファサイズ		*/
			NULL							/* 挿入句				*/
			);
	if (ret == 0)
	{	/* メッセージ取得失敗	*/
		return false;
	}
	return true;

#elif ((_POSIX_C_SOURCE >= 200112L || __XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
	/* XSI 準拠 strerror_r が提供されている場合						*/
	int ret = strerror_r(errnum, msgbuf,buflen);
	if (ret == 0)
	{	/* メッセージ取得成功	*/
		return true;
	}
	return false;

#else
	/* 上記以外の場合, ANSI 準拠 strerror(errnum) を使用する		*/
	char*  tmpmsg = strerror(errnum);
	size_t size   = strlen(tmpmsg) + 1;
	if (size > buflen)
	{	/* バッファサイズが足りない	*/
		osw_seterror(ERANGE);
		return false;
	}
	strncpy(msgbuf, tmpmsg, buflen);
	return true;

#endif	/* OSW_isWindows	*/
}



