testStrMatch() portability
This commit is contained in:
+3
-1
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user