[Lldb-commits] [lldb] r228802 - Fix CMIUtilString::SplitConsiderQuotes (MI)

Ilia K ki.stfu at gmail.com
Tue Feb 10 20:52:55 PST 2015


Author: ki.stfu
Date: Tue Feb 10 22:52:54 2015
New Revision: 228802

URL: http://llvm.org/viewvc/llvm-project?rev=228802&view=rev
Log:
Fix CMIUtilString::SplitConsiderQuotes (MI)

Summary:
This method doesn't work properly. Here is an example:
```
CMIUtilString test("\"hello\" \"\\\" world \\\" !\"");
CMIUtilString::VecString_t res;
test.SplitConsiderQuotes(" ", res);
```

Before this patch the result was as following:
```
(lldb) print res
(CMIUtilString::VecString_t) $1 = size=4 {
  [0] = (std::__1::string = "\"hello\"")
  [1] = (std::__1::string = "\"\\\"")
  [2] = (std::__1::string = "world")
  [3] = (std::__1::string = "\\\" !\"")
}
```

This patch fixes that error and now it looks like following:
```
(lldb) print res
(CMIUtilString::VecString_t) $1 = size=2 {
  [0] = (std::__1::string = "\"hello\"")
  [1] = (std::__1::string = "\"\\\" world \\\" !\"")
}
```

Reviewers: abidh, emaste, clayborg

Reviewed By: clayborg

Subscribers: lldb-commits, emaste, clayborg, abidh

Differential Revision: http://reviews.llvm.org/D7532

Modified:
    lldb/trunk/tools/lldb-mi/MIUtilString.cpp
    lldb/trunk/tools/lldb-mi/MIUtilString.h

Modified: lldb/trunk/tools/lldb-mi/MIUtilString.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.cpp?rev=228802&r1=228801&r2=228802&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIUtilString.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIUtilString.cpp Tue Feb 10 22:52:54 2015
@@ -224,39 +224,29 @@ CMIUtilString::Split(const CMIUtilString
     if (this->empty() || vDelimiter.empty())
         return 0;
 
-    MIint nPos = find(vDelimiter);
-    if (nPos == (MIint)std::string::npos)
-    {
-        vwVecSplits.push_back(*this);
-        return 1;
-    }
-    const MIint strLen(length());
-    if (nPos == strLen)
-    {
-        vwVecSplits.push_back(*this);
-        return 1;
-    }
+    const MIuint nLen(length());
+    MIuint nOffset(0);
+    do
+    {
+        // Find first occurrence which doesn't match to the delimiter
+        const MIuint nSectionPos(FindFirstNot(vDelimiter, nOffset));
+        if (nSectionPos == (MIuint)std::string::npos)
+            break;
+
+        // Find next occurrence of the delimiter after section
+        MIuint nNextDelimiterPos(FindFirst(vDelimiter, nSectionPos));
+        if (nNextDelimiterPos == (MIuint)std::string::npos)
+            nNextDelimiterPos = nLen;
+
+        // Extract string between delimiters
+        const MIuint nSectionLen(nNextDelimiterPos - nSectionPos);
+        const std::string strSection(substr(nSectionPos, nSectionLen));
+        vwVecSplits.push_back(strSection.c_str());
 
-    MIuint nAdd1(1);
-    if ((nPos > 0) && (substr(0, nPos) != vDelimiter))
-    {
-        nPos = 0;
-        nAdd1 = 0;
-    }
-    MIint nPos2 = find(vDelimiter, nPos + 1);
-    while (nPos2 != (MIint)std::string::npos)
-    {
-        const MIuint len(nPos2 - nPos - nAdd1);
-        const std::string strSection(substr(nPos + nAdd1, len));
-        if (strSection != vDelimiter)
-            vwVecSplits.push_back(strSection.c_str());
-        nPos += len + 1;
-        nPos2 = find(vDelimiter, nPos + 1);
-        nAdd1 = 0;
+        // Next
+        nOffset = nNextDelimiterPos + 1;
     }
-    const std::string strSection(substr(nPos, strLen - nPos));
-    if ((strSection.length() != 0) && (strSection != vDelimiter))
-        vwVecSplits.push_back(strSection.c_str());
+    while (nOffset < nLen);
 
     return vwVecSplits.size();
 }
@@ -283,81 +273,37 @@ CMIUtilString::SplitConsiderQuotes(const
     if (this->empty() || vDelimiter.empty())
         return 0;
 
-    MIint nPos = find(vDelimiter);
-    if (nPos == (MIint)std::string::npos)
-    {
-        vwVecSplits.push_back(*this);
-        return 1;
-    }
-    const MIint strLen(length());
-    if (nPos == strLen)
-    {
-        vwVecSplits.push_back(*this);
-        return 1;
-    }
-
-    // Look for more quotes
-    bool bHaveQuotes = false;
-    const MIchar cBckSlash = '\\';
-    const MIchar cQuote = '"';
-    MIint nPosQ = find(cQuote);
-    MIint nPosQ2 = (MIint)std::string::npos;
-    if (nPosQ != (MIint)std::string::npos)
-    {
-        nPosQ2 = nPosQ + 1;
-        while (nPosQ2 < strLen)
+    const MIuint nLen(length());
+    MIuint nOffset(0);
+    do
+    {
+        // Find first occurrence which doesn't match to the delimiter
+        const MIuint nSectionPos(FindFirstNot(vDelimiter, nOffset));
+        if (nSectionPos == (MIuint)std::string::npos)
+            break;
+
+        // Find next occurrence of the delimiter after (quoted) section
+        const bool bSkipQuotedText(true);
+        bool bUnmatchedQuote(false);
+        MIuint nNextDelimiterPos(FindFirst(vDelimiter, bSkipQuotedText, bUnmatchedQuote, nSectionPos));
+        if (bUnmatchedQuote)
         {
-            nPosQ2 = find(cQuote, nPosQ2);
-            if ((nPosQ2 == (MIint)std::string::npos) || (at(nPosQ2 - 1) != cBckSlash))
-                break;
-            nPosQ2++;
+            vwVecSplits.clear();
+            return 0;
         }
-        bHaveQuotes = (nPosQ2 != (MIint)std::string::npos);
-    }
+        if (nNextDelimiterPos == (MIuint)std::string::npos)
+            nNextDelimiterPos = nLen;
 
-    MIuint nAdd1(1);
-    if ((nPos > 0) && (substr(0, nPos) != vDelimiter))
-    {
-        nPos = 0;
-        nAdd1 = 0;
-    }
-    MIint nPos2 = find(vDelimiter, nPos + 1);
-    while (nPos2 != (MIint)std::string::npos)
-    {
-        if (!bHaveQuotes || (bHaveQuotes && ((nPos2 > nPosQ2) || (nPos2 < nPosQ))))
-        {
-            // Extract text or quoted text
-            const MIuint len(nPos2 - nPos - nAdd1);
-            const std::string strSection(substr(nPos + nAdd1, len));
-            if (strSection != vDelimiter)
-                vwVecSplits.push_back(strSection.c_str());
-            nPos += len + 1;
-            nPos2 = find(vDelimiter, nPos + 1);
-            nAdd1 = 0;
-
-            if (bHaveQuotes && (nPos2 > nPosQ2))
-            {
-                // Reset, look for more quotes
-                bHaveQuotes = false;
-                nPosQ = find(cQuote, nPos);
-                nPosQ2 = (MIint)std::string::npos;
-                if (nPosQ != (MIint)std::string::npos)
-                {
-                    nPosQ2 = find(cQuote, nPosQ + 1);
-                    bHaveQuotes = (nPosQ2 != (MIint)std::string::npos);
-                }
-            }
-        }
-        else
-        {
-            // Skip passed text in quotes
-            nPos2 = find(vDelimiter, nPosQ2 + 1);
-        }
-    }
-    const std::string strSection(substr(nPos, strLen - nPos));
-    if ((strSection.length() != 0) && (strSection != vDelimiter))
+        // Extract string between delimiters
+        const MIuint nSectionLen(nNextDelimiterPos - nSectionPos);
+        const std::string strSection(substr(nSectionPos, nSectionLen));
         vwVecSplits.push_back(strSection.c_str());
 
+        // Next
+        nOffset = nNextDelimiterPos + 1;
+    }
+    while (nOffset < nLen);
+
     return vwVecSplits.size();
 }
 
@@ -696,3 +642,123 @@ CMIUtilString::IsQuoted(void) const
 
     return true;
 }
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurence in *this string which maches the pattern.
+// Type:    Method.
+// Args:    vrPattern   - (R) The pattern to search for.
+//          vnPos       - (R) The starting position at which to start searching. (Dflt = 0)
+// Return:  MIuint - The position of the first substring that match.
+// Throws:  None.
+//--
+MIuint
+CMIUtilString::FindFirst(const CMIUtilString &vrPattern, const MIuint vnPos /* = 0 */) const
+{
+    return find(vrPattern, vnPos);
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurence in *this string which maches the pattern and isn't surrounded by quotes.
+// Type:    Method.
+// Args:    vrPattern                 - (R) The pattern to search for.
+//          vbSkipQuotedText          - (R) True = don't look at quoted text, false = otherwise.
+//          vrwbNotFoundClosedQuote   - (W) True = parsing error: unmatched quote, false = otherwise.
+//          vnPos                     - (R) Position of the first character in the string to be considered in the search. (Dflt = 0)
+// Return:  MIuint - The position of the first substring that matches and isn't quoted.
+// Throws:  None.
+//--
+MIuint
+CMIUtilString::FindFirst(const CMIUtilString &vrPattern, const bool vbSkipQuotedText, bool &vrwbNotFoundClosedQuote,
+                         const MIuint vnPos /* = 0 */) const
+{
+    vrwbNotFoundClosedQuote = false;
+
+    if (!vbSkipQuotedText)
+        return FindFirst(vrPattern, vnPos);
+
+    const MIuint nLen(length());
+
+    MIuint nPos = vnPos;
+    do
+    {
+        const MIuint nQuotePos(FindFirstQuote(nPos));
+        const MIuint nPatternPos(FindFirst(vrPattern, nPos));
+        if (nQuotePos == (MIuint)std::string::npos)
+            return nPatternPos;
+
+        const MIuint nQuoteClosedPos = FindFirstQuote(nQuotePos + 1);
+        if (nQuoteClosedPos == (MIuint)std::string::npos)
+        {
+            vrwbNotFoundClosedQuote = true;
+            return (MIuint)std::string::npos;
+        }
+
+        if ((nPatternPos == (MIuint)std::string::npos) || (nPatternPos < nQuotePos))
+            return nPatternPos;
+
+        nPos = nQuoteClosedPos + 1;
+    }
+    while (nPos < nLen);
+
+    return (MIuint)std::string::npos;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurence in *this string which doesn't mach to the pattern.
+// Type:    Method.
+// Args:    vrPattern   - (R) The pattern to search for.
+//          vnPos       - (R) Position of the first character in the string to be considered in the search. (Dflt = 0)
+// Return:  MIuint - The position of the first character that doesn't match.
+// Throws:  None.
+//--
+MIuint
+CMIUtilString::FindFirstNot(const CMIUtilString &vrPattern, const MIuint vnPos /* = 0 */) const
+{
+    const MIuint nLen(length());
+    const MIuint nPatternLen(vrPattern.length());
+
+    MIuint nPatternPos(vnPos);
+    do
+    {
+        const bool bMatchPattern(compare(nPatternPos, nPatternLen, vrPattern) == 0);
+        if (!bMatchPattern)
+            return nPatternPos;
+        nPatternPos += nPatternLen;
+    }
+    while (nPatternPos < nLen);
+
+    return (MIuint)std::string::npos;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurence of not escaped quotation mark in *this string.
+// Type:    Method.
+// Args:    vnPos   - (R) Position of the first character in the string to be considered in the search.
+// Return:  MIuint - The position of the quotation mark.
+// Throws:  None.
+//--
+MIuint
+CMIUtilString::FindFirstQuote(const MIuint vnPos) const
+{
+    const MIchar cBckSlash('\\');
+    const MIchar cQuote('"');
+    const MIuint nLen(length());
+
+    MIuint nPos = vnPos;
+    do
+    {
+        const MIuint nBckSlashPos(find(cBckSlash, nPos));
+        const MIuint nQuotePos(find(cQuote, nPos));
+        if ((nBckSlashPos == (MIuint)std::string::npos) || (nQuotePos == (MIuint)std::string::npos))
+            return nQuotePos;
+
+        if (nQuotePos < nBckSlashPos)
+            return nQuotePos;
+
+        // Skip 2 characters: First is '\', second is that which is escaped by '\'
+        nPos = nBckSlashPos + 2;
+    }
+    while (nPos < nLen);
+
+    return (MIuint)std::string::npos;
+}

Modified: lldb/trunk/tools/lldb-mi/MIUtilString.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.h?rev=228802&r1=228801&r2=228802&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIUtilString.h (original)
+++ lldb/trunk/tools/lldb-mi/MIUtilString.h Tue Feb 10 22:52:54 2015
@@ -66,6 +66,10 @@ class CMIUtilString : public std::string
     CMIUtilString StripCRAll(void) const;
     CMIUtilString Trim(void) const;
     CMIUtilString Trim(const MIchar vChar) const;
+    MIuint FindFirst(const CMIUtilString &vrPattern, const MIuint vnPos = 0) const;
+    MIuint FindFirst(const CMIUtilString &vrPattern, const bool vbSkipQuotedText, bool &vrwbNotFoundClosedQuote,
+                     const MIuint vnPos = 0) const;
+    MIuint FindFirstNot(const CMIUtilString &vrPattern, const MIuint vnPos = 0) const;
     //
     CMIUtilString &operator=(const MIchar *vpRhs);
     CMIUtilString &operator=(const std::string &vrRhs);
@@ -82,4 +86,5 @@ class CMIUtilString : public std::string
   private:
     bool ExtractNumberFromHexadecimal(MIint64 &vwrNumber) const;
     CMIUtilString RemoveRepeatedCharacters(const MIint vnPos, const MIchar vChar);
+    MIuint FindFirstQuote(const MIuint vnPos) const;
 };





More information about the lldb-commits mailing list