mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
Fix C++11 std::regex incompatibility
boost::regex supports escape sequences starting with a backslash in format strings of regex_replace, but std::regex does not. Therefore format strings involving literal backslashes have to be written differently for both flavours. The special MSVC handling in regex.h is removed, since it is not needed anymore, and using grep syntax would definitely be wrong.
This commit is contained in:
parent
12faf2b161
commit
e8211fb931
@ -670,11 +670,19 @@ static docstring escape_special_chars(docstring const & expr)
|
||||
|
||||
// $& is an ECMAScript format expression that expands to all
|
||||
// of the current match
|
||||
// The '$' must be prefixed with the escape character '\' for
|
||||
// boost to treat it as a literal.
|
||||
// Thus, to prefix a matched expression with '\', we use:
|
||||
#if defined(LYX_USE_CXX11) && defined(LYX_USE_STD_REGEX)
|
||||
// To prefix a matched expression with a single literal backslash, we
|
||||
// need to escape it for the C++ compiler and use:
|
||||
// FIXME: UNICODE
|
||||
return from_utf8(lyx::regex_replace(to_utf8(expr), reg, string("\\$&")));
|
||||
#else
|
||||
// A backslash in the format string starts an escape sequence in boost.
|
||||
// Thus, to prefix a matched expression with a single literal backslash,
|
||||
// we need to give two backslashes to the regex engine, and escape both
|
||||
// for the C++ compiler and use:
|
||||
// FIXME: UNICODE
|
||||
return from_utf8(lyx::regex_replace(to_utf8(expr), reg, string("\\\\$&")));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,10 +20,17 @@ string const escape_special_chars(string const & expr)
|
||||
|
||||
// $& is a ECMAScript format expression that expands to all
|
||||
// of the current match
|
||||
// The '$' must be prefixed with the escape character '\' for
|
||||
// boost to treat it as a literal.
|
||||
// Thus, to prefix a matched expression with '\', we use:
|
||||
#if defined(LYX_USE_CXX11) && defined(LYX_USE_STD_REGEX)
|
||||
// To prefix a matched expression with a single literal backslash, we
|
||||
// need to escape it for the C++ compiler and use:
|
||||
return lyx::regex_replace(expr, reg, "\\$&");
|
||||
#else
|
||||
// A backslash in the format string starts an escape sequence in boost.
|
||||
// Thus, to prefix a matched expression with a single literal backslash,
|
||||
// we need to give two backslashes to the regex engine, and escape both
|
||||
// for the C++ compiler and use:
|
||||
return lyx::regex_replace(expr, reg, "\\\\$&");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,74 +14,20 @@
|
||||
|
||||
#if defined(LYX_USE_CXX11) && defined(LYX_USE_STD_REGEX)
|
||||
# include <regex>
|
||||
# ifdef _MSC_VER
|
||||
namespace lyx {
|
||||
// inheriting 'private' to see which functions are used and if there are
|
||||
// other ECMAScript defaults
|
||||
// FIXME: Is this really needed?
|
||||
// If yes, then the MSVC regex implementation is not standard-conforming.
|
||||
class regex : private std::regex
|
||||
{
|
||||
public:
|
||||
regex() {}
|
||||
regex(const regex& rhs) : std::regex(rhs) {}
|
||||
template<class T>
|
||||
regex(T t) : std::regex(t, std::regex_constants::grep) {}
|
||||
template<class T>
|
||||
void assign(T t) { std::regex::assign(t, std::regex_constants::grep); }
|
||||
template<class T, class V>
|
||||
void assign(T t, V v) { std::regex::assign(t, v); }
|
||||
const std::regex& toStd() const { return *this; }
|
||||
};
|
||||
template<class T>
|
||||
bool regex_match(T t, const regex& r) { return std::regex_match(t, r.toStd()); }
|
||||
template<class T>
|
||||
bool regex_match(T t, std::smatch& m, const regex& r) { return std::regex_match(t, m, r.toStd()); }
|
||||
template<class T, class V>
|
||||
bool regex_match(T t, V v, std::smatch& m, const regex& r) { return std::regex_match(t, v, m, r.toStd()); }
|
||||
template<class T, class V>
|
||||
std::string regex_replace(T t, const regex& r, V v) { return std::regex_replace(t, r.toStd(), v); }
|
||||
template<class T, class V, class U, class H>
|
||||
T regex_replace(T t, V v, U u, const regex& r, H h) { return std::regex_replace(t, v, u, r.toStd(), h); }
|
||||
template<class T>
|
||||
bool regex_search(T t, const regex& r) { return std::regex_search(t, r.toStd()); }
|
||||
template<class T>
|
||||
bool regex_search(T t, std::smatch& m, const regex& r) { return std::regex_search(t, m, r.toStd()); }
|
||||
template<class T, class V>
|
||||
bool regex_search(T t, V v, std::smatch& m, const regex& r) { return std::regex_search(t, v, m, r.toStd()); }
|
||||
|
||||
struct sregex_iterator : std::sregex_iterator
|
||||
{
|
||||
sregex_iterator() {}
|
||||
template<class T, class V>
|
||||
sregex_iterator(T t, V v, const regex& r) : std::sregex_iterator(t, v, r.toStd()) {}
|
||||
};
|
||||
}
|
||||
# else
|
||||
// <regex> in gcc is unusable in versions less than 4.9.0
|
||||
// see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631
|
||||
# define LR_NS std
|
||||
namespace lyx {
|
||||
using LR_NS::regex;
|
||||
using LR_NS::regex_match;
|
||||
using LR_NS::regex_replace;
|
||||
using LR_NS::regex_search;
|
||||
using LR_NS::sregex_iterator;
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
# include <boost/regex.hpp>
|
||||
# define LR_NS boost
|
||||
#endif
|
||||
|
||||
namespace lyx {
|
||||
using LR_NS::regex;
|
||||
using LR_NS::regex_match;
|
||||
using LR_NS::regex_replace;
|
||||
using LR_NS::regex_search;
|
||||
using LR_NS::sregex_iterator;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace lyx {
|
||||
using LR_NS::smatch;
|
||||
using LR_NS::basic_regex;
|
||||
using LR_NS::regex_error;
|
||||
|
Loading…
Reference in New Issue
Block a user