testStrMatch() portability

This commit is contained in:
Michael Davidsaver
2021-08-30 21:14:17 -07:00
parent 2f122da5c2
commit 3382b35975
3 changed files with 37 additions and 5 deletions
+3 -1
View File
@@ -79,7 +79,8 @@ public:
}
//! Override current pass/fail result if input matches a regular expression
//! @since 0.1.1
//! @since UNRELEASED Expression syntax is POSIX extended.
//! @since 0.1.1 Added
testCase& setPassMatch(const std::string& expr, const std::string& inp);
//! Append to message
@@ -288,6 +289,7 @@ testCase testThrowsMatch(const std::string& expr, FN fn)
//! Macro which asserts that STR matches the regular expression EXPR
//! Evaluates to a pvxs::testCase
//! @since UNRELEASED Expression syntax is POSIX extended.
//! @since 0.1.1
#define testStrMatch(EXPR, STR) ::pvxs::detail::_testStrMatch(#EXPR, EXPR, #STR, STR)
+31 -3
View File
@@ -4,7 +4,18 @@
* in file LICENSE that is included with this distribution.
*/
#include <regex>
#include "pvxs/version.h"
#if !defined(GCC_VERSION) || GCC_VERSION>VERSION_INT(4,9,0,0)
# include <regex>
#else
// GCC 4.8 provides the regex header and symbols, but with a no-op implementation
// so fill in the gap with POSIX regex
# include <sys/types.h>
# include <regex.h>
# define USE_POSIX_REGEX
#endif
#include <epicsUnitTest.h>
@@ -96,15 +107,33 @@ testCase::~testCase()
testCase& testCase::setPassMatch(const std::string& expr, const std::string& inp)
{
#ifdef USE_POSIX_REGEX
regex_t ex{};
if(auto err = regcomp(&ex, expr.c_str(), REG_EXTENDED|REG_NOSUB)) {
auto len = regerror(err, &ex, nullptr, 0u);
std::vector<char> msg(len+1);
(void)regerror(err, &ex, msg.data(), len);
msg[len] = '\0'; // paranoia
setPass(false);
(*this)<<" expression error: "<<msg.data()<<" :";
} else {
setPass(regexec(&ex, inp.c_str(), 0, nullptr, 0)!=REG_NOMATCH);
regfree(&ex);
}
#else
std::regex ex;
try {
ex.assign(expr);
ex.assign(expr, std::regex_constants::extended);
setPass(std::regex_match(inp, ex));
}catch(std::regex_error& e) {
setPass(false);
(*this)<<" expression error: "<<e.what()<<" :";
}
#endif
return *this;
}
@@ -174,7 +203,6 @@ testCase _testStrTest(unsigned op, const char *sLHS, const char* rlhs, const cha
testCase _testStrMatch(const char *spat, const std::string& pat, const char *sstr, const std::string& str)
{
std::regex expr;
testCase ret;
ret.setPassMatch(pat, str);
ret<<spat<<" (\""<<pat<<"\") match "<<str<<" (\""<<escape(str)<<"\")";
+3 -1
View File
@@ -200,13 +200,15 @@ void testTestEq()
testStrNotEq("hello", std::string("world"));
testStrNotEq(std::string("hello"), "world");
testStrNotEq(std::string("hello"), std::string("world"));
testStrMatch("[Hh]ello [Ww]orld", "hello world");
}
} // namespace
MAIN(testutil)
{
testPlan(24);
testPlan(25);
testTrue(version_abi_check())<<" 0x"<<std::hex<<PVXS_VERSION<<" ~= 0x"<<std::hex<<PVXS_ABI_VERSION;
testServerGUID();
testFill();