OSDN Git Service

replace std::regex with QRegExp
authorIvailo Monev <xakepa10@gmail.com>
Fri, 10 Jun 2022 23:20:32 +0000 (02:20 +0300)
committerIvailo Monev <xakepa10@gmail.com>
Fri, 10 Jun 2022 23:32:24 +0000 (02:32 +0300)
here comes the solution to std::regex randomly throwing exceptions
(3 different kind of exceptions but almost always not the same as
the last time it does for the same pattern)

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/3rdparty/javascriptcore/runtime/RegExp.cpp
src/3rdparty/javascriptcore/runtime/RegExp.h

index c80b95d..95af10e 100644 (file)
@@ -85,39 +85,19 @@ PassRefPtr<RegExp> RegExp::create(const UString& pattern, const UString& flags)
 
 void RegExp::compile()
 {
-    m_constructionError = std::string();
-    m_regExp = std::regex();
+    m_constructionError.clear();
     m_numSubpatterns = 0;
 
-    int regexOptions = std::regex_constants::ECMAScript;
+    Qt::CaseSensitivity regexOptions = Qt::CaseSensitive;
     if (ignoreCase())
-        regexOptions |= std::regex_constants::icase;
-#if 0
-    if (multiline())
-#if __cplusplus >= 201703L
-        regexOptions |= std::regex_constants::multiline;
-#endif
-#endif
+        regexOptions = Qt::CaseInsensitive;
 
-    m_regexPattern = std::string(m_pattern.ascii());
-#ifndef QT_NO_EXCEPTIONS
-    try {
-        m_regExp = std::regex(m_regexPattern.c_str(), regexOptions);
-        std::sregex_iterator matchbegin = std::sregex_iterator(m_regexPattern.begin(), m_regexPattern.end(), m_regExp);
-        std::sregex_iterator matchend = std::sregex_iterator();
-        m_numSubpatterns = std::distance(matchbegin, matchend);
-    } catch (const std::regex_error &err) {
-        m_constructionError = err.what();
-    } catch (...) {
-        m_constructionError = "Exception caught during regex compilation";
+    m_regExp = QRegExp(QString(m_pattern), regexOptions);
+    if (!m_regExp.isValid()) {
+        m_constructionError = m_regExp.errorString().toLatin1();
+        return;
     }
-#else
-    // no exceptions, no way to find out if error occured
-    m_regExp = std::regex(m_regexPattern.c_str(), regexOptions);
-    std::sregex_iterator matchbegin = std::sregex_iterator(m_regexPattern.begin(), m_regexPattern.end(), m_regExp);
-    std::sregex_iterator matchend = std::sregex_iterator();
-    m_numSubpatterns = std::distance(matchbegin, matchend);
-#endif
+    m_numSubpatterns = m_regExp.captureCount();
 }
 
 int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
@@ -145,19 +125,13 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
             offsetVector = ovector->data();
         }
 
-        const std::string sstring = std::string(s.ascii());
-#ifndef QT_NO_EXCEPTIONS
-        bool didmatch = false;
-        try {
-            didmatch = std::regex_match(sstring.data() + startOffset, m_regExp);
-        } catch (const std::regex_error &err) {
-            m_constructionError = err.what();
-        } catch (...) {
-            m_constructionError = "Exception caught during regex matching";
+        const QString qstring(s);
+#if 0
+        if (multiline()) {
+            // TODO: split lines and match
         }
-#else
-        const bool didmatch = std::regex_match(sstring.data() + startOffset, m_regExp);
 #endif
+        const bool didmatch = m_regExp.exactMatch(qstring.data() + startOffset);
 
         if (!didmatch) {
 #ifndef QT_NO_DEBUG
@@ -168,13 +142,10 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
             return -1;
         }
 
-        std::sregex_iterator matchbegin = std::sregex_iterator(m_regexPattern.begin(), m_regexPattern.end(), m_regExp);
-        std::sregex_iterator matchend = std::sregex_iterator();
         size_t nummatches = 0;
-        for (std::sregex_iterator iter = matchbegin; iter != matchend; iter++) {
-            const std::smatch itermatch = *iter;
-            offsetVector[nummatches] = itermatch.position();
-            offsetVector[nummatches + 1] = itermatch.length();
+        for (int i = 0; i < m_regExp.matchedLength(); i++) {
+            offsetVector[nummatches] = m_regExp.pos(i);
+            offsetVector[nummatches + 1] = m_regExp.cap(0).length();
             offsetVector[nummatches + 2] = 0;
             nummatches++;
         }
index 26a8591..a94dc01 100644 (file)
@@ -26,7 +26,7 @@
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 
-#include <regex>
+#include <QRegExp>
 
 namespace JSC {
 
@@ -42,8 +42,8 @@ namespace JSC {
 
         const UString& pattern() const { return m_pattern; }
 
-        bool isValid() const { return m_constructionError.empty(); }
-        const char* errorMessage() const { return m_constructionError.c_str(); }
+        bool isValid() const { return m_constructionError.isEmpty(); }
+        const char* errorMessage() const { return m_constructionError.constData(); }
 
         int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
         unsigned numSubpatterns() const { return m_numSubpatterns; }
@@ -58,11 +58,9 @@ namespace JSC {
 
         UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this.
         int m_flagBits;
-        std::string m_constructionError;
         unsigned m_numSubpatterns;
-
-        std::string m_regexPattern;
-        std::regex m_regExp;
+        QRegExp m_regExp;
+        QByteArray m_constructionError;
     };
 
 } // namespace JSC