/*!
* \file $RCSfile$
* \version $Revision: 181806 $
* \date $Date:: 2018-10-02 19:14:05 +0300#$
* \author $Author: maxdm $
*
* \brief Расширение модуля atldef.h из библиотеки ATL Microsoft.
*
* Убираем предупреждения стандартных макросов.
*/
#ifndef _ATLDEF2_H_INCLUDED
#define _ATLDEF2_H_INCLUDED

#ifdef _WIN32_WCE
#pragma warning (disable:4201)
#include <atldefce.h>
#include <altcecrt.h>
#ifndef _DEBUG
#define _ASSERT_BASE(expr, expr_str) ((void)0)
#endif //_DEBUG
#endif //_WIN32_WCE

#ifndef _WIN32_WCE
#include <errno.h>
#endif //_WIN32_WCE

#ifdef __ATLDEF_H__
#error File "atldef2.h" must be included before <atldef.h>
#endif // __ATLDEF_H__

#define ATLASSERT(expr) _ASSERTE(expr)

// Иногда функция возвращает ошибку, оставляя GetLastError() == 0. Такое
// поведение, например, наблюдалось у CryptGetOIDFunctionAddress(). Чтобы
// избежать ошибок в этой ситуации нельзя завершать функцию возвратом
// GetLastError(), но можно воспользоваться следующим макросом.
#define LAST_ERROR_OR_E_FAIL \
    (::GetLastError() ? ::GetLastError() : E_FAIL)

#define ATLASSUME(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { ATLASSERT(expr); __analysis_assume(!!(expr)); } while(0) \
    __pragma(warning(pop))

#define ATLENSURE_THROW(expr, hr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do {                                       \
	int __atl_condVal=!!(expr);            \
	_ASSERT_BASE(__atl_condVal, _CRT_WIDE(#expr)); \
	if(!(__atl_condVal)) AtlThrow(hr);     \
    } while (0) \
    __pragma(warning(pop))

#define ATLENSURE_RETURN_VAL(expr, val) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do {                                           \
	int __atl_condVal=!!(expr);                \
	_ASSERT_BASE(__atl_condVal, _CRT_WIDE(#expr)); \
	if(!(__atl_condVal)) return val;            \
    } while (0) \
    __pragma(warning(pop))

#define ATLENSURE_RETURN_LASTWIN32HR(expr) \
    ATLENSURE_RETURN_VAL(expr, HRESULT_FROM_WIN32(LAST_ERROR_OR_E_FAIL));

#define ATLENSURE_THROW_LASTWIN32HR(expr) \
    ATLENSURE_THROW(expr, HRESULT_FROM_WIN32(LAST_ERROR_OR_E_FAIL));

// В файле atldef.h на WINCE нет макроса ATLENSURE_RETURN_VAL,
// зато есть макрос ATLENSURE_RETURN_HR, но т.к. здесь определены
// собственные версии этих макросов, нас этот факт уже не беспокоит.
// Это строка в основном для WINCE
#define ATLENSURE_RETURN_HR(expr, val) ATLENSURE_RETURN_VAL(expr, val)

#define ATLENSURE_RETURN_FALSE(expr) ATLENSURE_RETURN_VAL(expr, FALSE)

#define _ATL_FATAL_SHUTDOWN __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { ::TerminateProcess(::GetCurrentProcess(), 0); } while(0) \
    __pragma(warning(pop))

#ifndef UNIX

#define ATL_CRT_ERRORCHECK(expr) ATL::AtlCrtErrorCheck(expr)

#ifndef _WIN32_WCE
#define ATL_CRT_ERRORCHECK_SPRINTF(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { \
	errno_t _saveErrno = errno; \
	errno = 0; \
	(expr); \
	if(0 != errno) \
	{ \
		ATL::AtlCrtErrorCheck(errno); \
	} \
	else \
	{ \
		errno = _saveErrno; \
	} \
    } while (0) \
    __pragma(warning(pop))
#else //_WIN32_WCE
#undef ATL_CRT_ERRORCHECK_SPRINTF
#define ATL_CRT_ERRORCHECK_SPRINTF(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { expr; } while (0) \
    __pragma(warning(pop))
#endif //_WIN32_WCE

#endif //!UNIX

#define ATL_BOOL_ERRORCHECK_RETURN(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { \
	BOOL atldef2_res = (expr); \
	if(!atldef2_res) \
	{ \
	    return FALSE; \
	} \
    } while (0) \
    __pragma(warning(pop))

#define ATL_WIN32_ERRORCHECK_RETURN(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { \
	DWORD atldef2_res = (expr); \
	if(0 != atldef2_res) \
	{ \
	    return atldef2_res; \
	} \
    } while (0) \
    __pragma(warning(pop))

#define ATL_HR_ERRORCHECK_RETURN(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { \
	HRESULT atldef2_hr = (expr); \
	if(FAILED(atldef2_hr)) \
	{ \
	    return atldef2_hr; \
	} \
    } while (0) \
    __pragma(warning(pop))

#define ATL_HR_ERRORCHECK_RETURN_FALSE(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { \
	HRESULT atldef2_hr = (expr); \
	if(FAILED(atldef2_hr)) \
	{ \
	    return FALSE; \
	} \
    } while (0) \
    __pragma(warning(pop))

#define ATL_HR_ERRORCHECK_THROW(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { \
	HRESULT atldef2_hr = (expr); \
	ATLENSURE_SUCCEEDED(atldef2_hr); \
    } while (0) \
    __pragma(warning(pop))
#ifndef UNIX
#pragma warning (push)
#endif
# ifdef _AFX_WIN
#	include <afxwin.h>
# else  /*_AFX_WIN*/
#	include <atldef.h>
# endif /*_AFX_WIN*/
#ifndef UNIX
#pragma warning (pop)
#endif

#if defined(_SECURE_ATL) && (!_SECURE_ATL)
#undef ATL_CRT_ERRORCHECK
#define ATL_CRT_ERRORCHECK(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { expr; } while (0) \
    __pragma(warning(pop))

#undef ATL_CRT_ERRORCHECK_SPRINTF
#define ATL_CRT_ERRORCHECK_SPRINTF(expr) __pragma(warning(push)) \
    __pragma(warning(disable: 4127)) \
    do { expr; } while (0) \
    __pragma(warning(pop))
#endif //defined(_SECURE_ATL) && (!_SECURE_ATL)

#endif // _ATLDEF2_H_INCLUDED
