[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