7
7
#include < cstdio>
8
8
#include < concepts>
9
9
#include < memory>
10
+ #include < ranges>
10
11
#include < source_location>
12
+ #include < string>
11
13
#include < string_view>
12
14
#include < type_traits>
15
+ #include < vector>
13
16
14
17
#include < semaphore.h>
15
18
#include < android/log.h>
@@ -30,6 +33,50 @@ namespace xamarin::android::detail {
30
33
va_end (ap);
31
34
return ret == -1 ? " Out of memory" : message;
32
35
}
36
+
37
+ [[gnu::always_inline]]
38
+ static inline std::string get_function_name (const char *signature)
39
+ {
40
+ using std::operator " " sv;
41
+
42
+ std::string_view sig { signature };
43
+ if (sig.length () == 0 ) {
44
+ return " <unknown function>" ;
45
+ }
46
+
47
+ auto splitSignature = sig | std::views::split (" ::" sv) | std::ranges::to<std::vector<std::string>> ();
48
+
49
+ std::string ret;
50
+ if (splitSignature.size () > 1 ) {
51
+ ret.append (splitSignature [splitSignature.size () - 2 ]);
52
+ ret.append (" ::" sv);
53
+ }
54
+ std::string_view func_name { splitSignature[splitSignature.size () - 1 ] };
55
+ std::string_view::size_type args_pos = func_name.find (' (' );
56
+ std::string_view::size_type name_start_pos = func_name.find (' ' );
57
+
58
+ if (name_start_pos == std::string_view::npos) {
59
+ name_start_pos = 0 ;
60
+ } else {
61
+ name_start_pos++; // point to after the space which separates return type from name
62
+ if (name_start_pos >= func_name.length ()) [[unlikely]] {
63
+ name_start_pos = 0 ;
64
+ }
65
+ }
66
+
67
+ if (args_pos == std::string_view::npos) {
68
+ ret.append (func_name.substr (name_start_pos));
69
+ } else {
70
+ // If there's a snafu with positions, start from 0
71
+ if (name_start_pos >= args_pos || name_start_pos > func_name.length ()) [[unlikely]] {
72
+ name_start_pos = 0 ;
73
+ }
74
+
75
+ ret.append (func_name.substr (name_start_pos, args_pos - name_start_pos));
76
+ }
77
+
78
+ return ret;
79
+ }
33
80
}
34
81
35
82
template <std::invocable<> F>
@@ -63,7 +110,13 @@ abort_if_invalid_pointer_argument (T *ptr, const char *ptr_name, std::source_loc
63
110
{
64
111
abort_unless (
65
112
ptr != nullptr ,
66
- [&ptr_name] { return xamarin::android::detail::_format_message (" Parameter '%s' must be a valid pointer" , ptr_name); },
113
+ [&ptr_name, &sloc] {
114
+ return xamarin::android::detail::_format_message (
115
+ " %s: parameter '%s' must be a valid pointer" ,
116
+ xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (),
117
+ ptr_name
118
+ );
119
+ },
67
120
sloc
68
121
);
69
122
}
@@ -74,7 +127,13 @@ abort_if_negative_integer_argument (int arg, const char *arg_name, std::source_l
74
127
{
75
128
abort_unless (
76
129
arg > 0 ,
77
- [&arg_name] { return xamarin::android::detail::_format_message (" Parameter '%s' must be a valid pointer" , arg_name); },
130
+ [&arg_name, &sloc] {
131
+ return xamarin::android::detail::_format_message (
132
+ " %s: parameter '%s' must be a valid pointer" ,
133
+ xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (),
134
+ arg_name
135
+ );
136
+ },
78
137
sloc
79
138
);
80
139
}
0 commit comments