Merge pull request #10953 from akallabeth/cast-split-improve

[winpr,cast] split cast macros to header
This commit is contained in:
Martin Fleisz 2024-12-18 15:33:33 +01:00 committed by GitHub
commit 6111ac458c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 396 additions and 274 deletions

View File

@ -0,0 +1,98 @@
/**
* WinPR: Windows Portable Runtime
* Runtime ASSERT macros
*
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
* Copyright 2021 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <winpr/config.h>
#include <winpr/platform.h>
#if defined(WITH_VERBOSE_WINPR_ASSERT) && (WITH_VERBOSE_WINPR_ASSERT != 0)
#define winpr_internal_assert(cond, file, fkt, line) \
do \
{ \
if (!(cond)) \
winpr_int_assert(#cond, (file), (fkt), (line)); \
} while (0)
#else
#define winpr_internal_assert(cond, file, fkt, line) assert(cond)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* this function meant only to be used by WINPR_ASSERT
* it needs to be exported as our assert implementation calls this for debug logging.
*
* also export when WITH_VERBOSE_WINPR_ASSERT is disabled as other software might compile with
* it enabled
*/
WINPR_API WINPR_NORETURN(void winpr_int_assert(const char* condstr, const char* file,
const char* fkt, size_t line));
#ifdef __cplusplus
}
#endif
#define WINPR_ASSERT_AT(cond, file, fkt, line) \
do \
{ \
WINPR_PRAGMA_DIAG_PUSH \
WINPR_PRAGMA_DIAG_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE \
WINPR_PRAGMA_DIAG_TAUTOLOGICAL_VALUE_RANGE_COMPARE \
WINPR_PRAGMA_DIAG_IGNORED_UNKNOWN_PRAGMAS \
WINPR_DO_COVERITY_PRAGMA(coverity compliance block \(deviate "CONSTANT_EXPRESSION_RESULT" \
"WINPR_ASSERT" \) \
\(deviate "NO_EFFECT" \
"WINPR_ASSERT" \)) \
\
winpr_internal_assert((cond), (file), (fkt), (line)); \
\
WINPR_DO_COVERITY_PRAGMA(coverity compliance end_block "CONSTANT_EXPRESSION_RESULT" \
"NO_EFFECT") \
WINPR_PRAGMA_DIAG_POP \
} while (0)
#define WINPR_ASSERT(cond) WINPR_ASSERT_AT((cond), __FILE__, __func__, __LINE__)
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(__cplusplus) && (__cplusplus >= 201703L) // C++ 17
#define WINPR_STATIC_ASSERT(cond) static_assert(cond)
#elif defined(__cplusplus) && (__cplusplus >= 201103L) // C++ 11
#define WINPR_STATIC_ASSERT(cond) static_assert(cond, #cond)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L) // C23
#define WINPR_STATIC_ASSERT(cond) static_assert(cond)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) // C11
#define WINPR_STATIC_ASSERT(cond) _Static_assert(cond, #cond)
#else
WINPR_PRAGMA_WARNING("static-assert macro not supported on this platform")
#define WINPR_STATIC_ASSERT(cond) assert(cond)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,9 +1,9 @@
/**
* WinPR: Windows Portable Runtime
* Runtime ASSERT macros
* Compatibility header for runtime ASSERT macros
*
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
* Copyright 2021 Thincast Technologies GmbH
* Copyright 2024 Armin Novak <armin.novak@thincast.com>
* Copyright 2024 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,75 +29,6 @@
#include <winpr/wlog.h>
#include <winpr/debug.h>
#if defined(WITH_VERBOSE_WINPR_ASSERT) && (WITH_VERBOSE_WINPR_ASSERT != 0)
#define winpr_internal_assert(cond, file, fkt, line) \
do \
{ \
if (!(cond)) \
winpr_int_assert(#cond, (file), (fkt), (line)); \
} while (0)
#ifdef __cplusplus
extern "C"
{
#include <winpr/assert-api.h>
#include <winpr/cast.h>
#endif
static INLINE WINPR_NORETURN(void winpr_int_assert(const char* condstr, const char* file,
const char* fkt, size_t line))
{
wLog* _log_cached_ptr = WLog_Get("com.freerdp.winpr.assert");
WLog_Print(_log_cached_ptr, WLOG_FATAL, "%s [%s:%s:%" PRIuz "]", condstr, file, fkt, line);
winpr_log_backtrace_ex(_log_cached_ptr, WLOG_FATAL, 20);
abort();
}
#ifdef __cplusplus
}
#endif
#else
#define winpr_internal_assert(cond, file, fkt, line) assert(cond)
#endif
#define WINPR_ASSERT_AT(cond, file, fkt, line) \
do \
{ \
WINPR_PRAGMA_DIAG_PUSH \
WINPR_PRAGMA_DIAG_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE \
WINPR_PRAGMA_DIAG_TAUTOLOGICAL_VALUE_RANGE_COMPARE \
WINPR_PRAGMA_DIAG_IGNORED_UNKNOWN_PRAGMAS \
WINPR_DO_COVERITY_PRAGMA(coverity compliance block \(deviate "CONSTANT_EXPRESSION_RESULT" \
"WINPR_ASSERT" \) \
\(deviate "NO_EFFECT" \
"WINPR_ASSERT" \)) \
\
winpr_internal_assert((cond), (file), (fkt), (line)); \
\
WINPR_DO_COVERITY_PRAGMA(coverity compliance end_block "CONSTANT_EXPRESSION_RESULT" \
"NO_EFFECT") \
WINPR_PRAGMA_DIAG_POP \
} while (0)
#define WINPR_ASSERT(cond) WINPR_ASSERT_AT((cond), __FILE__, __func__, __LINE__)
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(__cplusplus) && (__cplusplus >= 201703L) // C++ 17
#define WINPR_STATIC_ASSERT(cond) static_assert(cond)
#elif defined(__cplusplus) && (__cplusplus >= 201103L) // C++ 11
#define WINPR_STATIC_ASSERT(cond) static_assert(cond, #cond)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L) // C23
#define WINPR_STATIC_ASSERT(cond) static_assert(cond)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) // C11
#define WINPR_STATIC_ASSERT(cond) _Static_assert(cond, #cond)
#else
WINPR_PRAGMA_WARNING("static-assert macro not supported on this platform")
#define WINPR_STATIC_ASSERT(cond) assert(cond)
#endif
#ifdef __cplusplus
}
#endif
#endif /* WINPR_ERROR_H */

122
winpr/include/winpr/cast.h Normal file
View File

@ -0,0 +1,122 @@
/**
* WinPR: Windows Portable Runtime
* Cast macros
*
* Copyright 2024 Armin Novak <anovak@thincast.com>
* Copyright 2024 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdint.h>
#include <winpr/assert-api.h>
/**
* @brief C++ safe cast macro
* @since version 3.10.1
*/
#ifdef __cplusplus
#define WINPR_CXX_COMPAT_CAST(t, val) static_cast<t>(val)
#else
#define WINPR_CXX_COMPAT_CAST(t, val) (t)(val)
#endif
#if defined(__GNUC__) || defined(__clang__)
/**
* @brief A macro to do dirty casts. Do not use without a good justification!
* @param ptr The pointer to cast
* @param dstType The data type to cast to
* @return The casted pointer
* @since version 3.9.0
*/
#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) \
__extension__({ \
union \
{ \
srcType src; \
dstType dst; \
} cnv; \
WINPR_STATIC_ASSERT(sizeof(srcType) == sizeof(dstType)); \
cnv.src = ptr; \
cnv.dst; \
})
/**
* @brief A macro to do dirty casts. Do not use without a good justification!
* @param ptr The pointer to cast
* @param dstType The data type to cast to
* @return The casted pointer
* @since version 3.9.0
*/
#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) \
__extension__({ \
union \
{ \
__typeof(ptr) src; \
dstType dst; \
} cnv; \
cnv.src = ptr; \
cnv.dst; \
})
/**
* @brief A macro to do function pointer casts. Do not use without a good justification!
* @param ptr The pointer to cast
* @param dstType The data type to cast to
* @return The casted pointer
* @since version 3.9.0
*/
#define WINPR_FUNC_PTR_CAST(ptr, dstType) \
__extension__({ \
union \
{ \
__typeof(ptr) src; \
dstType dst; \
} cnv; \
WINPR_STATIC_ASSERT(sizeof(dstType) == sizeof(__typeof(ptr))); \
cnv.src = ptr; \
cnv.dst; \
})
#else
#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) (dstType) ptr
#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) (dstType) ptr
#define WINPR_FUNC_PTR_CAST(ptr, dstType) (dstType)(uintptr_t) ptr
#endif
#if defined(__GNUC__) || defined(__clang__)
/**
* @brief A macro to do checked integer casts.
* will check if the value does change by casting to and from the target type and comparing the
* values. will also check if the sign of a value changes during conversion.
*
* @param type the type to cast to
* @param var the integer of unknown type to cast
* @return The casted integer
* @since version 3.10.1
*/
#define WINPR_ASSERTING_INT_CAST(type, var) \
__extension__({ \
WINPR_ASSERT((var) == \
WINPR_CXX_COMPAT_CAST(__typeof(var), WINPR_CXX_COMPAT_CAST(type, (var)))); \
WINPR_ASSERT((((var) > 0) && (WINPR_CXX_COMPAT_CAST(type, (var)) > 0)) || \
(((var) <= 0) && WINPR_CXX_COMPAT_CAST(type, (var)) <= 0)); \
WINPR_CXX_COMPAT_CAST(type, (var)); \
})
#else
#define WINPR_ASSERTING_INT_CAST(type, var) WINPR_CXX_COMPAT_CAST(type, var)
#endif

View File

@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/cast.h>
#include <winpr/platform.h>
#include <winpr/winpr.h>
@ -108,13 +109,7 @@ static INLINE UINT64 _byteswap_uint64(UINT64 _val)
static INLINE UINT16 _byteswap_ushort(UINT16 _val)
{
#ifdef __cplusplus
#define winpr_byteswap_cast(t, val) static_cast<t>(val)
#else
#define winpr_byteswap_cast(t, val) (t)(val)
#endif
return winpr_byteswap_cast(UINT16, ((_val) >> 8U) | ((_val) << 8U));
#undef winpr_byteswap_cast
return WINPR_CXX_COMPAT_CAST(UINT16, ((_val) >> 8U) | ((_val) << 8U));
}
#endif /* (__GNUC__ > 4) || ... */

View File

@ -26,12 +26,9 @@
#include <winpr/wtypes.h>
#include <winpr/platform.h>
#include <winpr/assert.h>
#include <winpr/cast.h>
#ifdef __cplusplus
#define WINPR_ENDIAN_CAST(t, val) static_cast<t>(val)
#else
#define WINPR_ENDIAN_CAST(t, val) (t)(val)
#endif
#define WINPR_ENDIAN_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
#ifdef __cplusplus
extern "C"

View File

@ -20,8 +20,7 @@
#ifndef WINPR_ERROR_H
#define WINPR_ERROR_H
#include <winpr/platform.h>
#include <winpr/winpr.h>
#include <winpr/cast.h>
#include <winpr/wtypes.h>
#ifdef _WIN32
@ -147,11 +146,8 @@
WINPR_PRAGMA_DIAG_PUSH
WINPR_PRAGMA_DIAG_IGNORED_RESERVED_ID_MACRO
#ifdef __cplusplus
#define ERROR_CAST(t, val) static_cast<t>(val)
#else
#define ERROR_CAST(t, val) (t)(val)
#endif
#define ERROR_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
static INLINE HRESULT HRESULT_FROM_WIN32(unsigned long x)
{
HRESULT hx = ERROR_CAST(HRESULT, x);

View File

@ -23,12 +23,9 @@
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
#include <winpr/windows.h>
#include <winpr/cast.h>
#ifdef __cplusplus
#define STATUS_CAST(t, val) static_cast<t>(val)
#else
#define STATUS_CAST(t, val) (t)(val)
#endif
#define STATUS_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
#ifndef _WIN32

View File

@ -484,4 +484,115 @@ WINPR_PRAGMA_DIAG_IGNORED_RESERVED_ID_MACRO
WINPR_PRAGMA_DIAG_POP
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)
#define WINPR_DEPRECATED(obj) [[deprecated]] obj
#define WINPR_DEPRECATED_VAR(text, obj) [[deprecated(text)]] obj
#define WINPR_NORETURN(obj) [[noreturn]] obj
#elif defined(WIN32) && !defined(__CYGWIN__)
#define WINPR_DEPRECATED(obj) __declspec(deprecated) obj
#define WINPR_DEPRECATED_VAR(text, obj) __declspec(deprecated(text)) obj
#define WINPR_NORETURN(obj) __declspec(noreturn) obj
#elif defined(__GNUC__)
#define WINPR_DEPRECATED(obj) obj __attribute__((deprecated))
#define WINPR_DEPRECATED_VAR(text, obj) obj __attribute__((deprecated(text)))
#define WINPR_NORETURN(obj) __attribute__((__noreturn__)) obj
#else
#define WINPR_DEPRECATED(obj) obj
#define WINPR_DEPRECATED_VAR(text, obj) obj
#define WINPR_NORETURN(obj) obj
#endif
#ifdef _WIN32
#define INLINE __inline
#else
#define INLINE inline
#endif
#ifdef WINPR_DLL
#if defined _WIN32 || defined __CYGWIN__
#ifdef WINPR_EXPORTS
#ifdef __GNUC__
#define WINPR_API __attribute__((dllexport))
#else
#define WINPR_API __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#define WINPR_API __attribute__((dllimport))
#else
#define WINPR_API __declspec(dllimport)
#endif
#endif
#else
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define WINPR_API __attribute__((visibility("default")))
#else
#define WINPR_API
#endif
#endif
#else /* WINPR_DLL */
#define WINPR_API
#endif
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ <= 10)
#define WINPR_ATTR_MALLOC(deallocator, ptrindex) \
__attribute__((malloc, warn_unused_result)) /** @since version 3.3.0 */
#elif defined(__GNUC__)
#define WINPR_ATTR_MALLOC(deallocator, ptrindex) \
__attribute__((malloc(deallocator, ptrindex), warn_unused_result)) /** @since version 3.3.0 */
#else
#define WINPR_ATTR_MALLOC(deallocator, ptrindex) __declspec(restrict) /** @since version 3.3.0 */
#endif
#if defined(__GNUC__) || defined(__clang__)
#define WINPR_ATTR_FORMAT_ARG(pos, args) __attribute__((__format__(__printf__, pos, args)))
#define WINPR_FORMAT_ARG /**/
#else
#define WINPR_ATTR_FORMAT_ARG(pos, args)
#define WINPR_FORMAT_ARG _Printf_format_string_
#endif
#if defined(EXPORT_ALL_SYMBOLS)
#define WINPR_LOCAL WINPR_API
#else
#if defined _WIN32 || defined __CYGWIN__
#define WINPR_LOCAL
#else
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define WINPR_LOCAL __attribute__((visibility("hidden")))
#else
#define WINPR_LOCAL
#endif
#endif
#endif
// WARNING: *do not* use thread-local storage for new code because it is not portable
// It is only used for VirtualChannelInit, and all FreeRDP channels use VirtualChannelInitEx
// The old virtual channel API is only realistically used on Windows where TLS is available
#if defined _WIN32 || defined __CYGWIN__
#ifdef __GNUC__
#define WINPR_TLS __thread
#else
#define WINPR_TLS __declspec(thread)
#endif
#elif !defined(__IOS__)
#define WINPR_TLS __thread
#else
// thread-local storage is not supported on iOS
// don't warn because it isn't actually used on iOS
#define WINPR_TLS
#endif
#if defined(__GNUC__) || defined(__clang__)
#define WINPR_ALIGN64 __attribute__((aligned(8))) /** @since version 3.4.0 */
#else
#ifdef _WIN32
#define WINPR_ALIGN64 __declspec(align(8)) /** @since version 3.4.0 */
#else
#define WINPR_ALIGN64 /** @since version 3.4.0 */
#endif
#endif
#define WINPR_UNUSED(x) (void)(x)
#endif /* WINPR_PLATFORM_H */

View File

@ -28,6 +28,8 @@
#include <winpr/endian.h>
#include <winpr/synch.h>
#include <winpr/assert.h>
#include <winpr/cast.h>
#include <winpr/wlog.h>
#ifdef __cplusplus
extern "C"
@ -56,11 +58,7 @@ extern "C"
WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size);
WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size);
#ifdef __cplusplus
#define WINPR_STREAM_CAST(t, val) static_cast<t>(val)
#else
#define WINPR_STREAM_CAST(t, val) (t)(val)
#endif
#define WINPR_STREAM_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
#define Stream_CheckAndLogRequiredCapacityOfSize(tag, s, nmemb, size) \
Stream_CheckAndLogRequiredCapacityEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
@ -1252,7 +1250,7 @@ extern "C"
*
* @since version 3.9.0
*/
#define Stream_GetBufferAs(_s, _b) _b = Stream_BufferAs(_s, typeof(_b))
#define Stream_GetBufferAs(_s, _b) _b = Stream_BufferAs(_s, __typeof(_b))
#define Stream_PointerAs(s, type) WINPR_STREAM_CAST(type*, Stream_Pointer(s))
@ -1274,7 +1272,7 @@ extern "C"
*
* @since version 3.9.0
*/
#define Stream_GetPointerAs(_s, _p) _p = Stream_PointerAs(_s, typeof(_p))
#define Stream_GetPointerAs(_s, _p) _p = Stream_PointerAs(_s, __typeof(_p))
#if defined(WITH_WINPR_DEPRECATED)
WINPR_API WINPR_DEPRECATED_VAR("Use Stream_SetPosition instead",

View File

@ -20,114 +20,11 @@
#define WINPR_H
#include <winpr/platform.h>
#include <winpr/cast.h>
#ifdef WINPR_DLL
#if defined _WIN32 || defined __CYGWIN__
#ifdef WINPR_EXPORTS
#ifdef __GNUC__
#define WINPR_API __attribute__((dllexport))
#else
#define WINPR_API __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#define WINPR_API __attribute__((dllimport))
#else
#define WINPR_API __declspec(dllimport)
#endif
#endif
#else
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define WINPR_API __attribute__((visibility("default")))
#else
#define WINPR_API
#endif
#endif
#else /* WINPR_DLL */
#define WINPR_API
#endif
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ <= 10)
#define WINPR_ATTR_MALLOC(deallocator, ptrindex) \
__attribute__((malloc, warn_unused_result)) /** @since version 3.3.0 */
#elif defined(__GNUC__)
#define WINPR_ATTR_MALLOC(deallocator, ptrindex) \
__attribute__((malloc(deallocator, ptrindex), warn_unused_result)) /** @since version 3.3.0 */
#else
#define WINPR_ATTR_MALLOC(deallocator, ptrindex) __declspec(restrict) /** @since version 3.3.0 */
#endif
#if defined(__GNUC__) || defined(__clang__)
#define WINPR_ATTR_FORMAT_ARG(pos, args) __attribute__((__format__(__printf__, pos, args)))
#define WINPR_FORMAT_ARG /**/
#else
#define WINPR_ATTR_FORMAT_ARG(pos, args)
#define WINPR_FORMAT_ARG _Printf_format_string_
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)
#define WINPR_DEPRECATED(obj) [[deprecated]] obj
#define WINPR_DEPRECATED_VAR(text, obj) [[deprecated(text)]] obj
#define WINPR_NORETURN(obj) [[noreturn]] obj
#elif defined(WIN32) && !defined(__CYGWIN__)
#define WINPR_DEPRECATED(obj) __declspec(deprecated) obj
#define WINPR_DEPRECATED_VAR(text, obj) __declspec(deprecated(text)) obj
#define WINPR_NORETURN(obj) __declspec(noreturn) obj
#elif defined(__GNUC__)
#define WINPR_DEPRECATED(obj) obj __attribute__((deprecated))
#define WINPR_DEPRECATED_VAR(text, obj) obj __attribute__((deprecated(text)))
#define WINPR_NORETURN(obj) __attribute__((__noreturn__)) obj
#else
#define WINPR_DEPRECATED(obj) obj
#define WINPR_DEPRECATED_VAR(text, obj) obj
#define WINPR_NORETURN(obj) obj
#endif
#if defined(EXPORT_ALL_SYMBOLS)
#define WINPR_LOCAL WINPR_API
#else
#if defined _WIN32 || defined __CYGWIN__
#define WINPR_LOCAL
#else
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define WINPR_LOCAL __attribute__((visibility("hidden")))
#else
#define WINPR_LOCAL
#endif
#endif
#endif
// WARNING: *do not* use thread-local storage for new code because it is not portable
// It is only used for VirtualChannelInit, and all FreeRDP channels use VirtualChannelInitEx
// The old virtual channel API is only realistically used on Windows where TLS is available
#if defined _WIN32 || defined __CYGWIN__
#ifdef __GNUC__
#define WINPR_TLS __thread
#else
#define WINPR_TLS __declspec(thread)
#endif
#elif !defined(__IOS__)
#define WINPR_TLS __thread
#else
// thread-local storage is not supported on iOS
// don't warn because it isn't actually used on iOS
#define WINPR_TLS
#endif
#ifdef _WIN32
#define INLINE __inline
#else
#define INLINE inline
#endif
#if defined(__GNUC__) || defined(__clang__)
#define WINPR_ALIGN64 __attribute__((aligned(8))) /** @since version 3.4.0 */
#else
#ifdef _WIN32
#define WINPR_ALIGN64 __declspec(align(8)) /** @since version 3.4.0 */
#else
#define WINPR_ALIGN64 /** @since version 3.4.0 */
#endif
#ifdef __cplusplus
extern "C"
{
#endif
WINPR_API void winpr_get_version(int* major, int* minor, int* revision);
@ -135,67 +32,8 @@ WINPR_API const char* winpr_get_version_string(void);
WINPR_API const char* winpr_get_build_revision(void);
WINPR_API const char* winpr_get_build_config(void);
#define WINPR_UNUSED(x) (void)(x)
#if defined(__GNUC__) || defined(__clang__)
/**
* @brief A macro to do dirty casts. Do not use without a good justification!
* @param ptr The pointer to cast
* @param dstType The data type to cast to
* @return The casted pointer
* @since version 3.9.0
*/
#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) \
__extension__({ \
union \
{ \
srcType src; \
dstType dst; \
} cnv; \
WINPR_STATIC_ASSERT(sizeof(srcType) == sizeof(dstType)); \
cnv.src = ptr; \
cnv.dst; \
})
/**
* @brief A macro to do dirty casts. Do not use without a good justification!
* @param ptr The pointer to cast
* @param dstType The data type to cast to
* @return The casted pointer
* @since version 3.9.0
*/
#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) \
__extension__({ \
union \
{ \
typeof(ptr) src; \
dstType dst; \
} cnv; \
cnv.src = ptr; \
cnv.dst; \
})
/**
* @brief A macro to do function pointer casts. Do not use without a good justification!
* @param ptr The pointer to cast
* @param dstType The data type to cast to
* @return The casted pointer
* @since version 3.9.0
*/
#define WINPR_FUNC_PTR_CAST(ptr, dstType) \
__extension__({ \
union \
{ \
typeof(ptr) src; \
dstType dst; \
} cnv; \
cnv.src = ptr; \
cnv.dst; \
})
#else
#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) (dstType) ptr
#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) (dstType) ptr
#define WINPR_FUNC_PTR_CAST(ptr, dstType) (dstType)(uintptr_t) ptr
#ifdef __cplusplus
}
#endif
#endif /* WINPR_H */

View File

@ -15,7 +15,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set(CRT_FILES alignment.c conversion.c buffer.c memory.c unicode.c string.c)
set(CRT_FILES
alignment.c
conversion.c
buffer.c
memory.c
unicode.c
string.c
assert.c
)
if(WITH_UNICODE_BUILTIN)
list(APPEND CRT_FILES unicode_builtin.c)

View File

@ -0,0 +1,31 @@
/**
* WinPR: Windows Portable Runtime
* Runtime ASSERT macros
*
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
* Copyright 2021 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <winpr/assert.h>
#include <winpr/wlog.h>
#include <winpr/debug.h>
void winpr_int_assert(const char* condstr, const char* file, const char* fkt, size_t line)
{
wLog* _log_cached_ptr = WLog_Get("com.freerdp.winpr.assert");
WLog_Print(_log_cached_ptr, WLOG_FATAL, "%s [%s:%s:%" PRIuz "]", condstr, file, fkt, line);
winpr_log_backtrace_ex(_log_cached_ptr, WLOG_FATAL, 20);
abort();
}