]> git.lyx.org Git - features.git/commitdiff
Fix C++11 std::regex incompatibility
authorGeorg Baum <baum@lyx.org>
Tue, 24 Nov 2015 19:31:14 +0000 (20:31 +0100)
committerGeorg Baum <baum@lyx.org>
Tue, 24 Nov 2015 19:31:14 +0000 (20:31 +0100)
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.

src/frontends/qt4/GuiCitation.cpp
src/frontends/tests/biblio.cpp
src/support/regex.h

index dc41fbdc871828da61c9eacc865e490ddb2cdc0d..8856ebc8668473a79e65e6587beda75254ab8e64 100644 (file)
@@ -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
 }
 
 
index 5a7a376d3e40a33086b9eb07cee86a7cb456eff2..4ba1d40a341fe2754000b12cdbf6122c4da5e2df 100644 (file)
@@ -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
 }
 
 
index 94140a53eaebb1a1af53d8b171f5c9b5c4ac515a..fd6f1e5ceac19f6c9e5cf5f955c9462c5477a648 100644 (file)
 
 #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;