diff --git a/src/native/shared/cpp-util.hh b/src/native/shared/cpp-util.hh index 3951b81f474..6e77d98f5f7 100644 --- a/src/native/shared/cpp-util.hh +++ b/src/native/shared/cpp-util.hh @@ -7,9 +7,12 @@ #include #include #include +#include #include +#include #include #include +#include #include #include @@ -30,6 +33,50 @@ namespace xamarin::android::detail { va_end (ap); return ret == -1 ? "Out of memory" : message; } + + [[gnu::always_inline]] + static inline std::string get_function_name (const char *signature) + { + using std::operator""sv; + + std::string_view sig { signature }; + if (sig.length () == 0) { + return ""; + } + + auto splitSignature = sig | std::views::split ("::"sv) | std::ranges::to> (); + + std::string ret; + if (splitSignature.size () > 1) { + ret.append (splitSignature [splitSignature.size () - 2]); + ret.append ("::"sv); + } + std::string_view func_name { splitSignature[splitSignature.size () - 1] }; + std::string_view::size_type args_pos = func_name.find ('('); + std::string_view::size_type name_start_pos = func_name.find (' '); + + if (name_start_pos == std::string_view::npos) { + name_start_pos = 0; + } else { + name_start_pos++; // point to after the space which separates return type from name + if (name_start_pos >= func_name.length ()) [[unlikely]] { + name_start_pos = 0; + } + } + + if (args_pos == std::string_view::npos) { + ret.append (func_name.substr (name_start_pos)); + } else { + // If there's a snafu with positions, start from 0 + if (name_start_pos >= args_pos || name_start_pos > func_name.length ()) [[unlikely]] { + name_start_pos = 0; + } + + ret.append (func_name.substr (name_start_pos, args_pos - name_start_pos)); + } + + return ret; + } } template F> @@ -63,7 +110,13 @@ abort_if_invalid_pointer_argument (T *ptr, const char *ptr_name, std::source_loc { abort_unless ( ptr != nullptr, - [&ptr_name] { return xamarin::android::detail::_format_message ("Parameter '%s' must be a valid pointer", ptr_name); }, + [&ptr_name, &sloc] { + return xamarin::android::detail::_format_message ( + "%s: parameter '%s' must be a valid pointer", + xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (), + ptr_name + ); + }, sloc ); } @@ -74,7 +127,13 @@ abort_if_negative_integer_argument (int arg, const char *arg_name, std::source_l { abort_unless ( arg > 0, - [&arg_name] { return xamarin::android::detail::_format_message ("Parameter '%s' must be a valid pointer", arg_name); }, + [&arg_name, &sloc] { + return xamarin::android::detail::_format_message ( + "%s: parameter '%s' must be a valid pointer", + xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (), + arg_name + ); + }, sloc ); }