From 260a5334ee963f66745d0cb98316ee831737b22d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 16 Dec 2021 13:39:09 +0000 Subject: libstdc++: Improve std::regex_error::what() strings This replaces the vague "regex_error" for std::regex_error::what() with a string that corresponds to the error_type enum passed to the constructor. This allows us to remove many of the strings passed to __throw_regex_error, because the default string is at least as good. When a string argument to __throw_regex_error is kept it should add some context-specific detail absent from the default string. Also remove full stops (periods) from the end of those strings, to make it easier to include them in logs and other output. I've left them starting with an upper-case letter, which is consistent with strerror output for (at least) Glibc, Solaris and BSD. I'm ambivalent whether that's the right choice. This also adds the missing noreturn attribute to __throw_regex_error. libstdc++-v3/ChangeLog: * include/bits/regex_compiler.tcc: Adjust all calls to __throw_regex_error. * include/bits/regex_error.h (__throw_regex_error): Add noreturn attribute. * include/bits/regex_scanner.tcc: Likewise. * src/c++11/regex.cc (desc): New helper function. (regex_error::regex_error(error_type)): Use desc to get a string corresponding to the error code. --- libstdc++-v3/src/c++11/regex.cc | 47 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'libstdc++-v3/src/c++11') diff --git a/libstdc++-v3/src/c++11/regex.cc b/libstdc++-v3/src/c++11/regex.cc index 0a4a5524b22..d5e1cc7612a 100644 --- a/libstdc++-v3/src/c++11/regex.cc +++ b/libstdc++-v3/src/c++11/regex.cc @@ -35,8 +35,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __attribute__((unused))) { _GLIBCXX_THROW_OR_ABORT(regex_error(__ecode)); } +namespace +{ + const char* + desc(regex_constants::error_type e) + { + using namespace regex_constants; + switch (e) + { + case error_collate: + return "Invalid collating element in regular expression"; + case error_ctype: + return "Invalid character class in regular expression"; + case error_escape: + return "Invalid escape in regular expression"; + case error_backref: + return "Invalid back reference in regular expression"; + case error_brack: + return "Mismatched '[' and ']' in regular expression"; + case error_paren: + return "Mismatched '(' and ')' in regular expression"; + case error_brace: + return "Mismatched '{' and '}' in regular expression"; + case error_badbrace: + return "Invalid range in '{}' in regular expression"; + case error_range: + return "Invalid character range in regular expression"; + case error_space: + return "Insufficient memory to compile regular expression"; + case error_badrepeat: + return "Invalid '?', '*', or '+' in regular expression"; + case error_complexity: + return "Complexity of regex match exceeded implementation limits"; + case error_stack: + return "Insufficient memory to determine regex match"; + case _S_null: + return "Unexpected null character in regular expression"; + case _S_grammar: + return "Conflicting regex grammar options"; + default: + return "regex error"; + }; + + } +} + regex_error::regex_error(regex_constants::error_type __ecode) - : std::runtime_error("regex_error"), _M_code(__ecode) + : std::runtime_error(desc(__ecode)), _M_code(__ecode) { } regex_error::~regex_error() throw() { } -- cgit v1.2.3