xref: /reactos/sdk/lib/ucrt/math/matherr.cpp (revision fe11f7a2)
1 //
2 // matherr.cpp
3 //
4 //      Copyright (c) 2024 Timo Kreuzer
5 //
6 // User math error support.
7 //
8 // SPDX-License-Identifier: MIT
9 //
10 
11 #include <math.h>
12 #include <corecrt_startup.h>
13 #include <corecrt_internal.h>
14 
15 static __crt_state_management::dual_state_global<_UserMathErrorFunctionPointer> __acrt_global_user_matherr;
16 
17 //
18 // Declared in corecrt_internal.h
19 // Called from initialize_pointers()
20 //
21 extern "C"
22 void __cdecl __acrt_initialize_user_matherr(void* encoded_null)
23 {
24     __acrt_global_user_matherr.initialize(
25         reinterpret_cast<_UserMathErrorFunctionPointer>(encoded_null));
26 }
27 
28 //
29 // Declared in corecrt_internal.h
30 //
31 extern "C"
32 bool __cdecl __acrt_has_user_matherr(void)
33 {
34     _UserMathErrorFunctionPointer user_matherr =
35         __crt_fast_decode_pointer(__acrt_global_user_matherr.value());
36     return user_matherr != nullptr;
37 }
38 
39 //
40 // Declared in corecrt_internal.h
41 //
42 extern "C"
43 int  __cdecl __acrt_invoke_user_matherr(struct _exception* _Exp)
44 {
45     _UserMathErrorFunctionPointer user_matherr =
46         __crt_fast_decode_pointer(__acrt_global_user_matherr.value());
47     if (user_matherr != nullptr)
48     {
49         return user_matherr(_Exp);
50     }
51 
52     return 0;
53 }
54 
55 //
56 // Declared in corecrt_startup.h
57 //
58 extern "C"
59 void
60 __cdecl
61 __setusermatherr(
62     _UserMathErrorFunctionPointer _UserMathErrorFunction)
63 {
64     _UserMathErrorFunctionPointer encodedPtr =
65         __crt_fast_encode_pointer(_UserMathErrorFunction);
66 
67     __acrt_global_user_matherr.value() = encodedPtr;
68 }
69 
70 //
71 // Used by libm
72 //
73 extern "C"
74 int
75 __cdecl
76 _invoke_matherr(
77     int type,
78     char* name,
79     double arg1,
80     double arg2,
81     double retval)
82 {
83     struct _exception excpt;
84     excpt.type = type;
85     excpt.name = name;
86     excpt.arg1 = arg1;
87     excpt.arg2 = arg2;
88     excpt.retval = retval;
89     return __acrt_invoke_user_matherr(&excpt);
90 }
91