xref: /freebsd-src/contrib/llvm-project/openmp/runtime/src/kmp_safe_c_api.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric 
20b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric //
40b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric //
80b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric 
100b57cec5SDimitry Andric #ifndef KMP_SAFE_C_API_H
110b57cec5SDimitry Andric #define KMP_SAFE_C_API_H
120b57cec5SDimitry Andric 
13fe6060f1SDimitry Andric #include <type_traits>
140b57cec5SDimitry Andric #include "kmp_platform.h"
150b57cec5SDimitry Andric #include <string.h>
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric // Replacement for banned C API
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric // Not every unsafe call listed here is handled now, but keeping everything
200b57cec5SDimitry Andric // in one place should be handy for future maintenance.
210b57cec5SDimitry Andric #if KMP_OS_WINDOWS && KMP_MSVC_COMPAT
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #define RSIZE_MAX_STR (4UL << 10) // 4KB
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric // _malloca was suggested, but it is not a drop-in replacement for _alloca
260b57cec5SDimitry Andric #define KMP_ALLOCA _alloca
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric #define KMP_MEMCPY_S memcpy_s
290b57cec5SDimitry Andric #define KMP_SNPRINTF sprintf_s
300b57cec5SDimitry Andric #define KMP_SSCANF sscanf_s
310b57cec5SDimitry Andric #define KMP_STRCPY_S strcpy_s
320b57cec5SDimitry Andric #define KMP_STRNCPY_S strncpy_s
331ac55f4cSDimitry Andric #define KMP_STRNCAT_S strncat_s
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric // Use this only when buffer size is unknown
360b57cec5SDimitry Andric #define KMP_MEMCPY(dst, src, cnt) memcpy_s(dst, cnt, src, cnt)
370b57cec5SDimitry Andric 
38fe6060f1SDimitry Andric template <typename T, bool B = std::is_array<T>::value>
39fe6060f1SDimitry Andric struct kmp_get_rmax_t {};
40fe6060f1SDimitry Andric template <typename T> struct kmp_get_rmax_t<T, false> {
41fe6060f1SDimitry Andric   static const size_t value = RSIZE_MAX_STR;
42fe6060f1SDimitry Andric };
43fe6060f1SDimitry Andric template <typename T> struct kmp_get_rmax_t<T, true> {
44fe6060f1SDimitry Andric   static const size_t value = sizeof(T);
45fe6060f1SDimitry Andric };
46fe6060f1SDimitry Andric #define KMP_STRLEN(str) strnlen_s(str, kmp_get_rmax_t<decltype(str)>::value)
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric // Use this only when buffer size is unknown
490b57cec5SDimitry Andric #define KMP_STRNCPY(dst, src, cnt) strncpy_s(dst, cnt, src, cnt)
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric // _TRUNCATE insures buffer size > max string to print.
520b57cec5SDimitry Andric #define KMP_VSNPRINTF(dst, cnt, fmt, arg)                                      \
530b57cec5SDimitry Andric   vsnprintf_s(dst, cnt, _TRUNCATE, fmt, arg)
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric #else // KMP_OS_WINDOWS
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric // For now, these macros use the existing API.
580b57cec5SDimitry Andric 
59*5f757f3fSDimitry Andric #if KMP_OS_NETBSD
60*5f757f3fSDimitry Andric #define KMP_ALLOCA __builtin_alloca
61*5f757f3fSDimitry Andric #else
620b57cec5SDimitry Andric #define KMP_ALLOCA alloca
63*5f757f3fSDimitry Andric #endif
640b57cec5SDimitry Andric #define KMP_MEMCPY_S(dst, bsz, src, cnt) memcpy(dst, src, cnt)
650b57cec5SDimitry Andric #define KMP_SNPRINTF snprintf
660b57cec5SDimitry Andric #define KMP_SSCANF sscanf
670b57cec5SDimitry Andric #define KMP_STRCPY_S(dst, bsz, src) strcpy(dst, src)
680b57cec5SDimitry Andric #define KMP_STRNCPY_S(dst, bsz, src, cnt) strncpy(dst, src, cnt)
691ac55f4cSDimitry Andric #define KMP_STRNCAT_S(dst, bsz, src, cnt) strncat(dst, src, cnt)
700b57cec5SDimitry Andric #define KMP_VSNPRINTF vsnprintf
710b57cec5SDimitry Andric #define KMP_STRNCPY strncpy
720b57cec5SDimitry Andric #define KMP_STRLEN strlen
730b57cec5SDimitry Andric #define KMP_MEMCPY memcpy
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric #endif // KMP_OS_WINDOWS
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric // Offer truncated version of strncpy
780b57cec5SDimitry Andric static inline void __kmp_strncpy_truncate(char *buffer, size_t buf_size,
790b57cec5SDimitry Andric                                           char const *src, size_t src_size) {
800b57cec5SDimitry Andric   if (src_size >= buf_size) {
810b57cec5SDimitry Andric     src_size = buf_size - 1;
820b57cec5SDimitry Andric   }
83e8d8bef9SDimitry Andric   KMP_STRNCPY_S(buffer, buf_size, src, src_size);
84e8d8bef9SDimitry Andric   buffer[src_size] = '\0';
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric #endif // KMP_SAFE_C_API_H
88