refactor: replace old linux regex.h with regex from STL.

main
Christoph Hasse 4 years ago
parent 969ffcc439
commit d82980b563

@ -27,35 +27,9 @@
// included header files
// + standard includes
#include <vector>
#include <regex>
using exv_grep_keys_t = std::vector<std::regex>;
#if defined(EXV_HAVE_REGEX_H)
# include <regex.h>
/*!
@brief exv_grep_keys_t is a vector of keys to match to strings
*/
typedef std::vector<regex_t> exv_grep_keys_t ;
# else
/*!
@brief exv_grep_key_t is a simple string and the ignore flag
*/
struct Exiv2_grep_key_t {
/*!
@brief Exiv2_grep_key_t constructor
*/
Exiv2_grep_key_t(std::string pattern,bool bIgnoreCase)
:pattern_(pattern),bIgnoreCase_(bIgnoreCase) {}
//! simple string to match
std::string pattern_;
//! should we ignore cast in the match?
bool bIgnoreCase_;
};
/*!
@brief exv_grep_keys_t is a vector of keys to match to strings
*/
typedef std::vector<Exiv2_grep_key_t> exv_grep_keys_t ;
#endif
/*!
@brief Make an integer version number for comparison from a major, minor and

@ -483,24 +483,14 @@ namespace Action {
bool Print::grepTag(const std::string& key)
{
bool result=Params::instance().greps_.empty();
for (auto&& g : Params::instance().greps_) {
if (result)
bool result = Params::instance().greps_.empty();
for (auto const& g : Params::instance().greps_) {
result = std::regex_search(key, g);
if (result) {
break;
#if defined(EXV_HAVE_REGEX_H)
result = regexec(&g, key.c_str(), 0, nullptr, 0) == 0;
#else
std::string Pattern(g.pattern_);
std::string Key(key);
if (g.bIgnoreCase_) {
// https://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/
std::transform(Pattern.begin(), Pattern.end(),Pattern.begin(), ::tolower);
std::transform(Key.begin() , Key.end() ,Key.begin() , ::tolower);
}
result = Key.find(Pattern) != std::string::npos;
#endif
}
}
return result ;
return result;
}
bool Print::keyTag(const std::string& key)

@ -37,9 +37,7 @@
#include <cassert>
#include <cctype>
#if defined(EXV_HAVE_REGEX_H)
#include <regex.h>
#endif
#include <regex>
#if defined(_MSC_VER)
#include <Windows.h>
@ -204,14 +202,6 @@ Params& Params::instance()
return *instance_;
}
Params::~Params() {
#if defined(EXV_HAVE_REGEX_H)
for (auto&& grep : instance().greps_) {
regfree(&grep);
}
#endif
}
void Params::cleanup()
{
delete instance_;
@ -448,48 +438,27 @@ int Params::setLogLevel(const std::string& optArg)
return rc;
} // Params::setLogLevel
// http://stackoverflow.com/questions/874134/find-if-string-ends-with-another-string-in-c
static inline bool ends_with(std::string const & value, std::string const & ending,std::string& stub)
int Params::evalGrep(const std::string& optArg)
{
if (ending.size() > value.size()) return false;
bool bResult = std::equal(ending.rbegin(), ending.rend(), value.rbegin());
stub = bResult ? value.substr(0,value.length() - ending.length()) : value;
return bResult ;
}
// check that string ends in "/i"
bool bIgnoreCase = optArg.size() > 2 && optArg.back() == 'i' && optArg[optArg.size() - 2] == '/';
auto pattern = bIgnoreCase ? optArg.substr(0, optArg.size() - 2) : optArg;
int Params::evalGrep( const std::string& optArg)
{
int result=0;
std::string pattern;
std::string ignoreCase("/i");
bool bIgnoreCase = ends_with(optArg,ignoreCase,pattern);
#if defined(EXV_HAVE_REGEX_H)
// try to compile a reg-exp from the input argument and store it in the vector
const size_t i = greps_.size();
greps_.resize(i + 1);
regex_t *pRegex = &greps_[i];
int errcode = regcomp( pRegex, pattern.c_str(), bIgnoreCase ? REG_NOSUB|REG_ICASE : REG_NOSUB);
// there was an error compiling the regexp
if( errcode ) {
size_t length = regerror(errcode, pRegex, nullptr, 0);
auto buffer = new char[length];
regerror (errcode, pRegex, buffer, length);
std::cerr << progname()
<< ": " << _("Option") << " -g: "
<< _("Invalid regexp") << " \"" << optArg << "\": " << buffer << "\n";
// free the memory and drop the regexp
delete[] buffer;
regfree( pRegex);
greps_.resize(i);
result=1;
try {
// use grep syntax, optimize for faster matching, treat all sub expressions as unnamed
auto flags = std::regex::grep | std::regex::optimize | std::regex::nosubs;
flags = bIgnoreCase ? flags | std::regex::icase : flags;
// try and emplace regex into vector
// might throw if invalid pattern
greps_.emplace_back(pattern, flags);
} catch (std::regex_error const& e) {
// there was an error compiling the regexp
std::cerr << progname() << ": " << _("Option") << " -g: " << _("Invalid regexp") << " \"" << optArg << "\n";
return 1;
}
#else
greps_.push_back(Exiv2_grep_key_t(pattern,bIgnoreCase));
#endif
return result;
} // Params::evalGrep
return 0;
} // Params::evalGrep
int Params::evalKey( const std::string& optArg)
{

@ -40,6 +40,7 @@
#include <vector>
#include <set>
#include <iostream>
#include <regex>
#ifdef EXV_HAVE_UNISTD_H
#include <unistd.h>
@ -297,9 +298,6 @@ private:
yodAdjust_[yodDay] = emptyYodAdjust_[yodDay];
}
//! Destructor, frees any allocated regexes in greps_
~Params() override;
//! @name Helpers
//@{
int setLogLevel(const std::string& optarg);

@ -42,6 +42,7 @@
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <regex>
// #1147
#ifndef WIN32
@ -115,21 +116,11 @@ namespace Exiv2 {
static bool shouldOutput(const exv_grep_keys_t& greps,const char* key,const std::string& value)
{
bool bPrint = greps.empty();
for (auto g = greps.begin(); !bPrint && g != greps.end(); ++g) {
std::string Key(key);
#if defined(EXV_HAVE_REGEX_H)
bPrint = (0 == regexec(&(*g), key, 0, nullptr, 0) || 0 == regexec(&(*g), value.c_str(), 0, nullptr, 0));
#else
std::string Pattern(g->pattern_);
std::string Value(value);
if ( g->bIgnoreCase_ ) {
// https://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/
std::transform(Pattern.begin(), Pattern.end(),Pattern.begin(), ::tolower);
std::transform(Key.begin() , Key.end() ,Key.begin() , ::tolower);
std::transform(Value.begin() , Value.end() ,Value.begin() , ::tolower);
}
bPrint = Key.find(Pattern) != std::string::npos || Value.find(Pattern) != std::string::npos;
#endif
for (auto const& g : greps) {
bPrint = std::regex_search(key, g) || std::regex_search(value, g);
if (bPrint) {
break;
}
}
return bPrint;
}
@ -323,8 +314,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
int have_iconv =0;
int have_memory =0;
int have_lstat =0;
int have_regex =0;
int have_regex_h =0;
int have_stdbool =0;
int have_stdint =0;
int have_stdlib =0;
@ -378,14 +367,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
have_lstat=1;
#endif
#ifdef EXV_HAVE_REGEX
have_regex=1;
#endif
#ifdef EXV_HAVE_REGEX_H
have_regex_h=1;
#endif
#ifdef EXV_HAVE_STDBOOL_H
have_stdbool=1;
#endif
@ -517,8 +498,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
output(os,keys,"have_iconv" ,have_iconv );
output(os,keys,"have_memory" ,have_memory );
output(os,keys,"have_lstat" ,have_lstat );
output(os,keys,"have_regex" ,have_regex );
output(os,keys,"have_regex_h" ,have_regex_h );
output(os,keys,"have_stdbool" ,have_stdbool );
output(os,keys,"have_stdint" ,have_stdint );
output(os,keys,"have_stdlib" ,have_stdlib );

Loading…
Cancel
Save