forked from OSchip/llvm-project
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 llvm-svn: 228802
This commit is contained in:
parent
81b5c668ac
commit
98bdc6418f
|
@ -224,40 +224,30 @@ CMIUtilString::Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits)
|
|||
if (this->empty() || vDelimiter.empty())
|
||||
return 0;
|
||||
|
||||
MIint nPos = find(vDelimiter);
|
||||
if (nPos == (MIint)std::string::npos)
|
||||
const MIuint nLen(length());
|
||||
MIuint nOffset(0);
|
||||
do
|
||||
{
|
||||
vwVecSplits.push_back(*this);
|
||||
return 1;
|
||||
}
|
||||
const MIint strLen(length());
|
||||
if (nPos == strLen)
|
||||
{
|
||||
vwVecSplits.push_back(*this);
|
||||
return 1;
|
||||
}
|
||||
// Find first occurrence which doesn't match to the delimiter
|
||||
const MIuint nSectionPos(FindFirstNot(vDelimiter, nOffset));
|
||||
if (nSectionPos == (MIuint)std::string::npos)
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
const std::string strSection(substr(nPos, strLen - nPos));
|
||||
if ((strSection.length() != 0) && (strSection != vDelimiter))
|
||||
// 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());
|
||||
|
||||
// Next
|
||||
nOffset = nNextDelimiterPos + 1;
|
||||
}
|
||||
while (nOffset < nLen);
|
||||
|
||||
return vwVecSplits.size();
|
||||
}
|
||||
|
||||
|
@ -283,81 +273,37 @@ CMIUtilString::SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t
|
|||
if (this->empty() || vDelimiter.empty())
|
||||
return 0;
|
||||
|
||||
MIint nPos = find(vDelimiter);
|
||||
if (nPos == (MIint)std::string::npos)
|
||||
const MIuint nLen(length());
|
||||
MIuint nOffset(0);
|
||||
do
|
||||
{
|
||||
vwVecSplits.push_back(*this);
|
||||
return 1;
|
||||
}
|
||||
const MIint strLen(length());
|
||||
if (nPos == strLen)
|
||||
{
|
||||
vwVecSplits.push_back(*this);
|
||||
return 1;
|
||||
}
|
||||
// Find first occurrence which doesn't match to the delimiter
|
||||
const MIuint nSectionPos(FindFirstNot(vDelimiter, nOffset));
|
||||
if (nSectionPos == (MIuint)std::string::npos)
|
||||
break;
|
||||
|
||||
// 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)
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue