/**
 * @file      nstdc_assert.h
 * @brief     アサーションを扱うヘッダーファイル
 * @author    Nomura Kei
 * @copyright 2003 - 2017  Nomura Kei
 * License: New BSD License (3-cclause BSD license)
 */
#ifndef NSTDC_ASSERT_H
#define NSTDC_ASSERT_H

#include <stddef.h>
#include <stdbool.h>

#include <config.h>
#include <nstdc.h>
#include <nstdc_compiler.h>


#ifdef NSTDC_DEBUG
#define nstdc_assert(val)				nstdc_assert_(    val   ,       #val, __FILE__, __LINE__, __func__)
#define nstdc_assert_num(v1, v2)		nstdc_assert_num_(v1, v2,       #v2 , __FILE__, __LINE__, __func__)
#define nstdc_assert_str(v1, v2)		nstdc_assert_str_(v1, v2,       #v2 , __FILE__, __LINE__, __func__)
#define nstdc_assert_mem(v1, v2, size)	nstdc_assert_mem_(v1, v2, size, #v2 , __FILE__, __LINE__, __func__)

#else
#define nstdc_assert(val)				UNUSED_VARIABLE(val)
#define nstdc_assert_num(v1, v2)		UNUSED_VARIABLE(v1);	UNUSED_VARIABLE(v2)
#define nstdc_assert_str(v1, v2)		UNUSED_VARIABLE(v1);	UNUSED_VARIABLE(v2)
#define nstdc_assert_mem(v1, v2, size)	UNUSED_VARIABLE(v1);	UNUSED_VARIABLE(v2);	UNUED_VARIABLE(size)

#endif	/* NSTDC_DEBUG		*/

#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
	/** 真偽判定時のアサーションエラー発生時に呼び出されるハンドラ関数.		*/
	void (*handler    )(long        val                            , const char* vname, const char* file, int line, const char* func);

	/** 数値比較時のアサーションエラー発生時に呼び出されるハンドラ関数.		*/
	void (*handler_num)(long        v1, long        v2             , const char* vname, const char* file, int line, const char* func);

	/** 文字列比較時のアサーションエラー発生時に呼び出されるハンドラ関数.	*/
	void (*handler_str)(const char* v1, const char* v2             , const char* vname, const char* file, int line, const char* func);

	/** メモリ比較時のアサーションエラー発生時に呼び出されるハンドラ関数.	*/
	void (*handler_mem)(const void* v1, const void* v2, size_t size, const char* vname, const char* file, int line, const char* func);

	/**
	 * アサーションの前処理として呼び出されるハンドラ関数.
	 * @param is_error true/false (アサーションエラー発生/エラーなし)
	 */
	void (*handler_bef)(bool is_error);

	/**
	 * アサーションの後処理として呼び出されるハンドラ関数.
	 * @param is_error true/false (アサーションエラー発生/エラーなし)
	 */
	void (*handler_aft)(bool is_error);

} NstdcAssertHandlers;

void nstdc_assert_    ( long        val                            , const char* vname, const char* file, int line, const char* func);
void nstdc_assert_num_( long        v1, long        v2             , const char* vname, const char* file, int line, const char* func);
void nstdc_assert_str_( const char* v1, const char* v2             , const char* vname, const char* file, int line, const char* func);
void nstdc_assert_mem_( const char* v1, const char* v2, size_t size, const char* vname, const char* file, int line, const char* func);
void nstdc_assert_set_handlers(NstdcAssertHandlers* handlers);


#ifdef __cplusplus
}
#endif

#endif	/* NSTDC_ASSERT_H	*/

