From 617c95d6b7e6099e829070a347425d5c0269d961 Mon Sep 17 00:00:00 2001 From: "Dan S. Camper" Date: Wed, 12 Jun 2024 08:45:52 -0500 Subject: [PATCH] Further rationalization of error reporting; better function comments --- rtl/eclrtl/eclregex.cpp | 131 ++++++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 44 deletions(-) diff --git a/rtl/eclrtl/eclregex.cpp b/rtl/eclrtl/eclregex.cpp index 0fd1f54f4a0..012b44bf3b7 100644 --- a/rtl/eclrtl/eclregex.cpp +++ b/rtl/eclrtl/eclregex.cpp @@ -60,15 +60,16 @@ static void pcre2Free(void * block, void * /*userData*/) rtlFree(block); } -/// @brief Convert a PCRE2 error code to a string and throw an exception -/// @param errCode PCRE2 error code -/// @param msgPrefix Prefix for error message; can be an empty string; -/// include a trailing space if a non-empty message is passed -/// @param regex Regex pattern that was in play when error occurred; pass -/// an empty string if no regex was used -/// @param errOffset OPTIONAL; offset in regex pattern where error occurred; -/// ignored if regex is empty -static void failWithPCRE2Error(int errCode, const std::string & msgPrefix, const std::string & regex, int errOffset = -1) +/** + * @brief Handles failure reporting with a regex and throws an exception with the given error code and message. + * + * @param errCode The error code indicating the type of error that occurred. + * @param msgPrefix The prefix to be added to the error message; can be an empty string; include a trailing space if a non-empty regex is passed. + * @param regex The regular expression pattern; may be an empty string. + * @param regexLength The length (in code points) of the regular expression pattern. + * @param errOffset The offset into regex at which the error occurred. + */ +static void failWithPCRE2Error(int errCode, const std::string & msgPrefix, const std::string & regex, int errOffset) { const int errBuffSize = 120; char errBuff[errBuffSize]; @@ -99,15 +100,27 @@ static void failWithPCRE2Error(int errCode, const std::string & msgPrefix, const rtlFail(0, msg.c_str()); } -/// @brief Convert a PCRE2 error code to a string and throw an exception -/// @param errCode PCRE2 error code -/// @param msgPrefix Prefix for error message; can be an empty string; -/// include a trailing space if a non-empty regex is passed -/// @param regex Unicode regex pattern that was in play when error occurred -/// @param regexLength The length of regex, in code points -/// @param errOffset Offset in regex pattern where error occurred; -/// ignored if regex is null or empty -static void failWithUPCRE2Error(int errCode, const std::string & msgPrefix, const UChar * regex, int regexLength, int errOffset) +/** + * @brief Handles the failure of a regular expression operation and throws an exception with the given error code and message. + * + * @param errCode The error code associated with the failure. + * @param msg The error message describing the failure. + */ +static void failWithPCRE2Error(int errCode, const std::string & msg) +{ + failWithPCRE2Error(errCode, msg, "", -1); +} + +/** + * @brief Handles failure reporting with Unicode regex and throws an exception with the given error code and message. + * + * @param errCode The error code indicating the type of error that occurred. + * @param msgPrefix The prefix to be added to the error message; can be an empty string; include a trailing space if a non-empty message is passed. + * @param regex The regular expression pattern in UChar format. + * @param regexLength The length (in code points) of the regular expression pattern. + * @param errOffset The offset into regex at which the error occurred. + */ +static void failWithPCRE2Error(int errCode, const std::string & msgPrefix, const UChar * regex, int regexLength, int errOffset) { std::string regexPattern; if (regex && regex[0]) @@ -121,29 +134,20 @@ static void failWithUPCRE2Error(int errCode, const std::string & msgPrefix, cons failWithPCRE2Error(errCode, msgPrefix, regexPattern, errOffset); } -/// @brief Convert a PCRE2 error code to a string and throw an exception -/// @param errCode PCRE2 error code -/// @param msg Error message; can be an empty string -/// @param regex OPTIONAL; Unicode regex pattern that was in play when error occurred -/// @param regexLength OPTIONAL; the length of regex, in code points -/// @param errOffset OPTIONAL; offset in regex pattern where error occurred; -/// ignored if regex is null or empty -static void failWithUPCRE2Error(int errCode, const std::string & msg) -{ - failWithUPCRE2Error(errCode, msg, nullptr, 0, -1); -} - -//--------------------------------------------------------------------------- -// Compiled regex pattern cache used for all data types //--------------------------------------------------------------------------- +/** + * @brief Parent class of all compiled regular expression pattern classes; used for caching. + */ class CompiledRegexPattern { - public: - CompiledRegexPattern() = default; - virtual ~CompiledRegexPattern() = default; +public: + CompiledRegexPattern() = default; + virtual ~CompiledRegexPattern() = default; }; +//--------------------------------------------------------------------------- + static CLRUCache compiledStrRegExprCache(500); // Cache size of 500 static CriticalSection compiledStrRegExprLock; @@ -192,7 +196,7 @@ class CStrRegExprFindInstance : implements IStrRegExprFindInstance if (numMatches < 0 && numMatches != PCRE2_ERROR_NOMATCH) { // Treat everything else as an error - failWithPCRE2Error(numMatches, "Error in regex search: ", ""); + failWithPCRE2Error(numMatches, "Error in regex search: "); } } @@ -302,7 +306,7 @@ class CCompiledStrRegExpr : public CompiledRegexPattern, implements ICompiledStr { // PCRE2_ERROR_NOMEMORY is a normal result when we're just asking for the size of the output pcre2_match_data_free_8(matchData); - failWithPCRE2Error(replaceResult, "Error in regex replace: ", ""); + failWithPCRE2Error(replaceResult, "Error in regex replace: "); } if (pcreLen > 0) @@ -318,7 +322,7 @@ class CCompiledStrRegExpr : public CompiledRegexPattern, implements ICompiledStr if (replaceResult < 0) { pcre2_match_data_free_8(matchData); - failWithPCRE2Error(replaceResult, "Error in regex replace: ", ""); + failWithPCRE2Error(replaceResult, "Error in regex replace: "); } } @@ -362,7 +366,7 @@ class CCompiledStrRegExpr : public CompiledRegexPattern, implements ICompiledStr { // Treat everything else as an error pcre2_match_data_free_8(matchData); - failWithPCRE2Error(numMatches, "Error in regex getMatchSet: ", ""); + failWithPCRE2Error(numMatches, "Error in regex getMatchSet: "); } } else if (numMatches > 0) @@ -406,6 +410,19 @@ class CCompiledStrRegExpr : public CompiledRegexPattern, implements ICompiledStr // STRING implementation //--------------------------------------------------------------------------- +/** + * @brief Fetches or creates a compiled string regular expression object. + * + * This function fetches a compiled string regular expression object from the cache if it exists, + * or creates a new one if it doesn't. The regular expression object is created based on the provided + * regex pattern, length, and case sensitivity flag. The created object is then cached for future use. + * + * @param _regexLength The length of the regex pattern. + * @param _regex The regex pattern. + * @param _isCaseSensitive Flag indicating whether the regex pattern is case sensitive or not. + * @return A pointer to a copy of the fetched or created CCompiledStrRegExpr object. The returned object + * * must eventually be deleted. + */ CCompiledStrRegExpr* fetchOrCreateCompiledStrRegExpr(int _regexLength, const char * _regex, bool _isCaseSensitive) { CCompiledStrRegExpr * compiledObjPtr = nullptr; @@ -462,6 +479,19 @@ ECLRTL_API void rtlDestroyStrRegExprFindInstance(IStrRegExprFindInstance * findI // UTF8 implementation //--------------------------------------------------------------------------- +/** + * @brief Fetches or creates a compiled UTF-8 regular expression object. + * + * This function fetches a compiled UTF-8 regular expression object from the cache if it exists, + * or creates a new one if it doesn't. The regular expression object is created based on the provided + * regex pattern, length, and case sensitivity flag. The created object is then cached for future use. + * + * @param _regexLength The length of the regex pattern, in code points. + * @param _regex The regex pattern. + * @param _isCaseSensitive Flag indicating whether the regex pattern is case sensitive or not. + * @return A pointer to a copy of the fetched or created CCompiledStrRegExpr object. The returned object + * * must eventually be deleted. + */ CCompiledStrRegExpr* fetchOrCreateCompiledU8StrRegExpr(int _regexLength, const char * _regex, bool _isCaseSensitive) { CCompiledStrRegExpr * compiledObjPtr = nullptr; @@ -542,7 +572,7 @@ class CUStrRegExprFindInstance : implements IUStrRegExprFindInstance if (numMatches < 0 && numMatches != PCRE2_ERROR_NOMATCH) { // Treat everything else as an error - failWithUPCRE2Error(numMatches, "Error in regex search: "); + failWithPCRE2Error(numMatches, "Error in regex search: "); } } @@ -612,7 +642,7 @@ class CCompiledUStrRegExpr : public CompiledRegexPattern, implements ICompiledUS if (newCompiledRegex == nullptr) { - failWithUPCRE2Error(errNum, "Error in regex pattern: ", _regex, _regexLength, errOffset); + failWithPCRE2Error(errNum, "Error in regex pattern: ", _regex, _regexLength, errOffset); } compiledRegex = std::shared_ptr(newCompiledRegex, pcre2_code_free_16); @@ -640,7 +670,7 @@ class CCompiledUStrRegExpr : public CompiledRegexPattern, implements ICompiledUS { // PCRE2_ERROR_NOMEMORY is a normal result when we're just asking for the size of the output pcre2_match_data_free_16(matchData); - failWithUPCRE2Error(replaceResult, "Error in regex replace: "); + failWithPCRE2Error(replaceResult, "Error in regex replace: "); } if (pcreLen > 0) @@ -656,7 +686,7 @@ class CCompiledUStrRegExpr : public CompiledRegexPattern, implements ICompiledUS if (replaceResult < 0) { pcre2_match_data_free_16(matchData); - failWithUPCRE2Error(replaceResult, "Error in regex replace: "); + failWithPCRE2Error(replaceResult, "Error in regex replace: "); } } @@ -699,7 +729,7 @@ class CCompiledUStrRegExpr : public CompiledRegexPattern, implements ICompiledUS { // Treat everything else as an error pcre2_match_data_free_16(matchData); - failWithUPCRE2Error(numMatches, "Error in regex getMatchSet: "); + failWithPCRE2Error(numMatches, "Error in regex getMatchSet: "); } } else if (numMatches > 0) @@ -742,6 +772,19 @@ class CCompiledUStrRegExpr : public CompiledRegexPattern, implements ICompiledUS // UNICODE implementation //--------------------------------------------------------------------------- +/** + * @brief Fetches or creates a compiled Unicode regular expression object. + * + * This function fetches a compiled Unicode regular expression object from the cache if it exists, + * or creates a new one if it doesn't. The regular expression object is created based on the provided + * regex pattern, length, and case sensitivity flag. The created object is then cached for future use. + * + * @param _regexLength The length of the regex pattern, in code points. + * @param _regex The regex pattern. + * @param _isCaseSensitive Flag indicating whether the regex pattern is case sensitive or not. + * @return A pointer to a copy of the fetched or created CCompiledUStrRegExpr object. The returned object + * * must eventually be deleted. + */ CCompiledUStrRegExpr* fetchOrCreateCompiledUStrRegExpr(int _regexLength, const UChar * _regex, bool _isCaseSensitive) { CCompiledUStrRegExpr * compiledObjPtr = nullptr;