2014-05-16 18:51:01 +08:00
|
|
|
//===-- MIUtilString.cpp ----------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// Third party headers
|
2015-02-27 02:14:30 +08:00
|
|
|
#include <inttypes.h> // for PRIx8
|
|
|
|
#include <limits.h> // for ULONG_MAX
|
|
|
|
#include <memory> // std::unique_ptr
|
|
|
|
#include <sstream> // std::stringstream
|
|
|
|
#include <stdarg.h> // va_list, va_start, var_end
|
|
|
|
#include <string.h> // for strncmp
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
// In-house headers:
|
|
|
|
#include "MIUtilString.h"
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMIUtilString constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::CMIUtilString()
|
2014-11-18 02:06:21 +08:00
|
|
|
: std::string()
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMIUtilString constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vpData - Pointer to UTF8 text data.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2015-07-03 21:45:34 +08:00
|
|
|
CMIUtilString::CMIUtilString(const char *vpData)
|
2014-11-18 02:06:21 +08:00
|
|
|
: std::string(vpData)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMIUtilString constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vpData - Pointer to UTF8 text data.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2015-07-03 21:45:34 +08:00
|
|
|
CMIUtilString::CMIUtilString(const char *const *vpData)
|
2014-11-18 02:06:21 +08:00
|
|
|
: std::string((const char *)vpData)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-09-18 00:22:30 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: CMIUtilString constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vpData - Pointer to UTF8 text data.
|
|
|
|
// nLen - Length of string.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
|
|
|
//--
|
|
|
|
CMIUtilString::CMIUtilString(const char *vpData, size_t nLen)
|
|
|
|
: std::string(vpData, nLen)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-06-25 00:35:50 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
2015-06-18 13:27:05 +08:00
|
|
|
// Details: CMIUtilString assignment operator.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: vpRhs - Pointer to UTF8 text data.
|
|
|
|
// Return: CMIUtilString & - *this string.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2015-07-03 21:45:34 +08:00
|
|
|
CMIUtilString &CMIUtilString::operator=(const char *vpRhs)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
if (*this == vpRhs)
|
|
|
|
return *this;
|
2014-06-25 00:35:50 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
if (vpRhs != nullptr)
|
|
|
|
{
|
|
|
|
assign(vpRhs);
|
|
|
|
}
|
2014-06-25 00:35:50 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return *this;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2015-06-18 13:27:05 +08:00
|
|
|
// Details: CMIUtilString assignment operator.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: vrRhs - The other string to copy from.
|
|
|
|
// Return: CMIUtilString & - *this string.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString &CMIUtilString::operator=(const std::string &vrRhs)
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
if (*this == vrRhs)
|
|
|
|
return *this;
|
2014-06-25 00:35:50 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
assign(vrRhs);
|
|
|
|
|
|
|
|
return *this;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
2014-05-16 18:51:01 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMIUtilString destructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::~CMIUtilString()
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Perform a snprintf format style on a string data. A new string object is
|
|
|
|
// created and returned.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: vrFormat - (R) Format string data instruction.
|
|
|
|
// vArgs - (R) Var list args of any type.
|
|
|
|
// Return: CMIUtilString - Number of splits found in the string data.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
|
|
|
CMIUtilString::FormatPriv(const CMIUtilString &vrFormat, va_list vArgs)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString strResult;
|
|
|
|
MIint nFinal = 0;
|
|
|
|
MIint n = vrFormat.size();
|
|
|
|
|
|
|
|
// IOR: mysterious crash in this function on some windows builds not able to duplicate
|
|
|
|
// but found article which may be related. Crash occurs in vsnprintf() or va_copy()
|
|
|
|
// Duplicate vArgs va_list argument pointer to ensure that it can be safely used in
|
|
|
|
// a new frame
|
|
|
|
// http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
|
|
|
|
va_list argsDup;
|
|
|
|
va_copy(argsDup, vArgs);
|
|
|
|
|
|
|
|
// Create a copy va_list to reset when we spin
|
|
|
|
va_list argsCpy;
|
|
|
|
va_copy(argsCpy, argsDup);
|
|
|
|
|
|
|
|
if (n == 0)
|
|
|
|
return strResult;
|
|
|
|
|
|
|
|
n = n << 4; // Reserve 16 times as much the length of the vrFormat
|
|
|
|
|
|
|
|
std::unique_ptr<char[]> pFormatted;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
pFormatted.reset(new char[n + 1]); // +1 for safety margin
|
|
|
|
::strncpy(&pFormatted[0], vrFormat.c_str(), n);
|
|
|
|
|
|
|
|
// We need to restore the variable argument list pointer to the start again
|
|
|
|
// before running vsnprintf() more then once
|
|
|
|
va_copy(argsDup, argsCpy);
|
|
|
|
|
|
|
|
nFinal = ::vsnprintf(&pFormatted[0], n, vrFormat.c_str(), argsDup);
|
|
|
|
if ((nFinal < 0) || (nFinal >= n))
|
|
|
|
n += abs(nFinal - n + 1);
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end(argsCpy);
|
|
|
|
va_end(argsDup);
|
|
|
|
|
|
|
|
strResult = pFormatted.get();
|
|
|
|
|
|
|
|
return strResult;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Perform a snprintf format style on a string data. A new string object is
|
|
|
|
// created and returned.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: vFormat - (R) Format string data instruction.
|
|
|
|
// ... - (R) Var list args of any type.
|
|
|
|
// Return: CMIUtilString - Number of splits found in the string data.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
|
|
|
CMIUtilString::Format(const CMIUtilString vFormating, ...)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
va_list args;
|
|
|
|
va_start(args, vFormating);
|
|
|
|
CMIUtilString strResult = CMIUtilString::FormatPriv(vFormating, args);
|
|
|
|
va_end(args);
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return strResult;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Perform a snprintf format style on a string data. A new string object is
|
|
|
|
// created and returned.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: vrFormat - (R) Format string data instruction.
|
|
|
|
// vArgs - (R) Var list args of any type.
|
|
|
|
// Return: CMIUtilString - Number of splits found in the string data.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
|
|
|
CMIUtilString::FormatValist(const CMIUtilString &vrFormating, va_list vArgs)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return CMIUtilString::FormatPriv(vrFormating, vArgs);
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Splits string into array of strings using delimiter. If multiple delimiter
|
|
|
|
// are found in sequence then they are not added to the list of splits.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vData - (R) String data to be split up.
|
|
|
|
// vDelimiter - (R) Delimiter char or text.
|
|
|
|
// vwVecSplits - (W) Container of splits found in string data.
|
2015-07-03 23:40:44 +08:00
|
|
|
// Return: size_t - Number of splits found in the string data.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString::Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
vwVecSplits.clear();
|
|
|
|
|
|
|
|
if (this->empty() || vDelimiter.empty())
|
|
|
|
return 0;
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
|
|
|
size_t nOffset(0);
|
2015-02-11 12:52:54 +08:00
|
|
|
do
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
2015-02-11 12:52:54 +08:00
|
|
|
// Find first occurrence which doesn't match to the delimiter
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nSectionPos(FindFirstNot(vDelimiter, nOffset));
|
|
|
|
if (nSectionPos == std::string::npos)
|
2015-02-11 12:52:54 +08:00
|
|
|
break;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2015-02-11 12:52:54 +08:00
|
|
|
// Find next occurrence of the delimiter after section
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nNextDelimiterPos(FindFirst(vDelimiter, nSectionPos));
|
|
|
|
if (nNextDelimiterPos == std::string::npos)
|
2015-02-11 12:52:54 +08:00
|
|
|
nNextDelimiterPos = nLen;
|
|
|
|
|
|
|
|
// Extract string between delimiters
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nSectionLen(nNextDelimiterPos - nSectionPos);
|
2015-02-11 12:52:54 +08:00
|
|
|
const std::string strSection(substr(nSectionPos, nSectionLen));
|
2014-11-18 02:06:21 +08:00
|
|
|
vwVecSplits.push_back(strSection.c_str());
|
|
|
|
|
2015-02-11 12:52:54 +08:00
|
|
|
// Next
|
|
|
|
nOffset = nNextDelimiterPos + 1;
|
|
|
|
}
|
|
|
|
while (nOffset < nLen);
|
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return vwVecSplits.size();
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2014-06-25 00:35:50 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Splits string into array of strings using delimiter. However the string is
|
|
|
|
// also considered for text surrounded by quotes. Text with quotes including the
|
|
|
|
// delimiter is treated as a whole. If multiple delimiter are found in sequence
|
2015-06-18 13:27:05 +08:00
|
|
|
// then they are not added to the list of splits. Quotes that are embedded in
|
2014-11-18 02:06:21 +08:00
|
|
|
// the string as string formatted quotes are ignored (proceeded by a '\\') i.e.
|
|
|
|
// "\"MI GDB local C++.cpp\":88".
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vData - (R) String data to be split up.
|
|
|
|
// vDelimiter - (R) Delimiter char or text.
|
|
|
|
// vwVecSplits - (W) Container of splits found in string data.
|
2015-07-03 23:40:44 +08:00
|
|
|
// Return: size_t - Number of splits found in the string data.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString::SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const
|
2014-06-25 00:35:50 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
vwVecSplits.clear();
|
|
|
|
|
|
|
|
if (this->empty() || vDelimiter.empty())
|
|
|
|
return 0;
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
|
|
|
size_t nOffset(0);
|
2015-02-11 12:52:54 +08:00
|
|
|
do
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
2015-02-11 12:52:54 +08:00
|
|
|
// Find first occurrence which doesn't match to the delimiter
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nSectionPos(FindFirstNot(vDelimiter, nOffset));
|
|
|
|
if (nSectionPos == std::string::npos)
|
2015-02-11 12:52:54 +08:00
|
|
|
break;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2015-02-11 12:52:54 +08:00
|
|
|
// Find next occurrence of the delimiter after (quoted) section
|
|
|
|
const bool bSkipQuotedText(true);
|
|
|
|
bool bUnmatchedQuote(false);
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nNextDelimiterPos(FindFirst(vDelimiter, bSkipQuotedText, bUnmatchedQuote, nSectionPos));
|
2015-02-11 12:52:54 +08:00
|
|
|
if (bUnmatchedQuote)
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
2015-02-11 12:52:54 +08:00
|
|
|
vwVecSplits.clear();
|
|
|
|
return 0;
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
2015-07-03 23:40:44 +08:00
|
|
|
if (nNextDelimiterPos == std::string::npos)
|
2015-02-11 12:52:54 +08:00
|
|
|
nNextDelimiterPos = nLen;
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2015-02-11 12:52:54 +08:00
|
|
|
// Extract string between delimiters
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nSectionLen(nNextDelimiterPos - nSectionPos);
|
2015-02-11 12:52:54 +08:00
|
|
|
const std::string strSection(substr(nSectionPos, nSectionLen));
|
2014-11-18 02:06:21 +08:00
|
|
|
vwVecSplits.push_back(strSection.c_str());
|
|
|
|
|
2015-02-11 12:52:54 +08:00
|
|
|
// Next
|
|
|
|
nOffset = nNextDelimiterPos + 1;
|
|
|
|
}
|
|
|
|
while (nOffset < nLen);
|
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return vwVecSplits.size();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
2015-02-20 21:07:41 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Split string into lines using \n and return an array of strings.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vwVecSplits - (W) Container of splits found in string data.
|
2015-07-03 23:40:44 +08:00
|
|
|
// Return: size_t - Number of splits found in the string data.
|
2015-02-20 21:07:41 +08:00
|
|
|
// Throws: None.
|
|
|
|
//--
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t
|
2015-02-20 21:07:41 +08:00
|
|
|
CMIUtilString::SplitLines(VecString_t &vwVecSplits) const
|
|
|
|
{
|
|
|
|
return Split("\n", vwVecSplits);
|
|
|
|
}
|
|
|
|
|
2014-05-16 18:51:01 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Remove '\n' from the end of string if found. It does not alter
|
|
|
|
// *this string.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - New version of the string.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::StripCREndOfLine() const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPos = rfind('\n');
|
|
|
|
if (nPos == std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
return *this;
|
|
|
|
|
|
|
|
const CMIUtilString strNew(substr(0, nPos).c_str());
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return strNew;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Remove all '\n' from the string and replace with a space. It does not alter
|
|
|
|
// *this string.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - New version of the string.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::StripCRAll() const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return FindAndReplace("\n", " ");
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Find and replace all matches of a sub string with another string. It does not
|
|
|
|
// alter *this string.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vFind - (R) The string to look for.
|
|
|
|
// vReplaceWith - (R) The string to replace the vFind match.
|
|
|
|
// Return: CMIUtilString - New version of the string.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
|
|
|
CMIUtilString::FindAndReplace(const CMIUtilString &vFind, const CMIUtilString &vReplaceWith) const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
if (vFind.empty() || this->empty())
|
|
|
|
return *this;
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nPos = find(vFind);
|
|
|
|
if (nPos == std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
return *this;
|
|
|
|
|
|
|
|
CMIUtilString strNew(*this);
|
2015-07-03 23:40:44 +08:00
|
|
|
while (nPos != std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
|
|
|
strNew.replace(nPos, vFind.length(), vReplaceWith);
|
|
|
|
nPos += vReplaceWith.length();
|
|
|
|
nPos = strNew.find(vFind, nPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
return strNew;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Check if *this string is a decimal number.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: bool - True = yes number, false not a number.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::IsNumber() const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
if (empty())
|
|
|
|
return false;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
if ((at(0) == '-') && (length() == 1))
|
|
|
|
return false;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPos = find_first_not_of("-.0123456789");
|
|
|
|
if (nPos != std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
return false;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return true;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 02:42:25 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Check if *this string is a hexadecimal number.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: bool - True = yes number, false not a number.
|
|
|
|
// Throws: None.
|
|
|
|
//--
|
|
|
|
bool
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::IsHexadecimalNumber() const
|
2015-02-14 02:42:25 +08:00
|
|
|
{
|
|
|
|
// Compare '0x..' prefix
|
|
|
|
if ((strncmp(c_str(), "0x", 2) != 0) && (strncmp(c_str(), "0X", 2) != 0))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Skip '0x..' prefix
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPos = find_first_not_of("01234567890ABCDEFabcedf", 2);
|
|
|
|
if (nPos != std::string::npos)
|
2015-02-14 02:42:25 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-05-16 18:51:01 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Extract the number from the string. The number can be either a hexadecimal or
|
|
|
|
// natural number. It cannot contain other non-numeric characters.
|
|
|
|
// Type: Method.
|
2015-06-18 13:27:05 +08:00
|
|
|
// Args: vwrNumber - (W) Number extracted from the string.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Return: bool - True = yes number, false not a number.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMIUtilString::ExtractNumber(MIint64 &vwrNumber) const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
vwrNumber = 0;
|
|
|
|
|
|
|
|
if (!IsNumber())
|
|
|
|
{
|
|
|
|
if (ExtractNumberFromHexadecimal(vwrNumber))
|
|
|
|
return true;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return false;
|
|
|
|
}
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
std::stringstream ss(const_cast<CMIUtilString &>(*this));
|
|
|
|
ss >> vwrNumber;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return true;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Extract the number from the hexadecimal string..
|
|
|
|
// Type: Method.
|
2015-06-18 13:27:05 +08:00
|
|
|
// Args: vwrNumber - (W) Number extracted from the string.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Return: bool - True = yes number, false not a number.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMIUtilString::ExtractNumberFromHexadecimal(MIint64 &vwrNumber) const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
vwrNumber = 0;
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPos = find_first_not_of("xX01234567890ABCDEFabcedf");
|
|
|
|
if (nPos != std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
return false;
|
|
|
|
|
2015-02-14 02:42:25 +08:00
|
|
|
errno = 0;
|
|
|
|
const MIuint64 nNum = ::strtoull(this->c_str(), nullptr, 16);
|
|
|
|
if (errno == ERANGE)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
vwrNumber = static_cast<MIint64>(nNum);
|
2014-11-18 02:06:21 +08:00
|
|
|
|
|
|
|
return true;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Determine if the text is all valid alpha numeric characters. Letters can be
|
|
|
|
// either upper or lower case.
|
|
|
|
// Type: Static method.
|
2015-07-03 15:28:11 +08:00
|
|
|
// Args: vpText - (R) The text data to examine.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Return: bool - True = yes all alpha, false = one or more chars is non alpha.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
2015-07-03 21:45:34 +08:00
|
|
|
CMIUtilString::IsAllValidAlphaAndNumeric(const char *vpText)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t len = ::strlen(vpText);
|
2014-11-18 02:06:21 +08:00
|
|
|
if (len == 0)
|
|
|
|
return false;
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
for (size_t i = 0; i < len; i++, vpText++)
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
2015-07-03 21:45:34 +08:00
|
|
|
const char c = *vpText;
|
2014-11-18 02:06:21 +08:00
|
|
|
if (::isalnum((int)c) == 0)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Check if two strings share equal contents.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: vrLhs - (R) String A.
|
|
|
|
// vrRhs - (R) String B.
|
|
|
|
// Return: bool - True = yes equal, false - different.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
|
|
|
CMIUtilString::Compare(const CMIUtilString &vrLhs, const CMIUtilString &vrRhs)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
// Check the sizes match
|
|
|
|
if (vrLhs.size() != vrRhs.size())
|
|
|
|
return false;
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return (::strncmp(vrLhs.c_str(), vrRhs.c_str(), vrLhs.size()) == 0);
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Remove from either end of *this string the following: " \t\n\v\f\r".
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - Trimmed string.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::Trim() const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString strNew(*this);
|
2015-07-03 21:45:34 +08:00
|
|
|
const char *pWhiteSpace = " \t\n\v\f\r";
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPos = find_last_not_of(pWhiteSpace);
|
|
|
|
if (nPos != std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
|
|
|
strNew = substr(0, nPos + 1).c_str();
|
|
|
|
}
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPos2 = strNew.find_first_not_of(pWhiteSpace);
|
|
|
|
if (nPos2 != std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
{
|
|
|
|
strNew = strNew.substr(nPos2).c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
return strNew;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2014-05-16 18:51:01 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Remove from either end of *this string the specified character.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - Trimmed string.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
2015-07-03 21:45:34 +08:00
|
|
|
CMIUtilString::Trim(const char vChar) const
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString strNew(*this);
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen = strNew.length();
|
2014-11-18 02:06:21 +08:00
|
|
|
if (nLen > 1)
|
|
|
|
{
|
|
|
|
if ((strNew[0] == vChar) && (strNew[nLen - 1] == vChar))
|
|
|
|
strNew = strNew.substr(1, nLen - 2).c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
return strNew;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2014-05-16 18:51:01 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Do a printf equivalent for printing a number in binary i.e. "b%llB".
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Static method.
|
|
|
|
// Args: vnDecimal - (R) The number to represent in binary.
|
|
|
|
// Return: CMIUtilString - Binary number in text.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
|
|
|
CMIUtilString::FormatBinary(const MIuint64 vnDecimal)
|
2014-05-16 18:51:01 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString strBinaryNumber;
|
|
|
|
|
|
|
|
const MIuint nConstBits = 64;
|
|
|
|
MIuint nRem[nConstBits + 1];
|
|
|
|
MIint i = 0;
|
|
|
|
MIuint nLen = 0;
|
|
|
|
MIuint64 nNum = vnDecimal;
|
|
|
|
while ((nNum > 0) && (nLen < nConstBits))
|
|
|
|
{
|
|
|
|
nRem[i++] = nNum % 2;
|
|
|
|
nNum = nNum >> 1;
|
|
|
|
nLen++;
|
|
|
|
}
|
2015-07-03 21:45:34 +08:00
|
|
|
char pN[nConstBits + 1];
|
2014-11-18 02:06:21 +08:00
|
|
|
MIuint j = 0;
|
|
|
|
for (i = nLen; i > 0; --i, j++)
|
|
|
|
{
|
|
|
|
pN[j] = '0' + nRem[i - 1];
|
|
|
|
}
|
|
|
|
pN[j] = 0; // String NUL termination
|
|
|
|
|
|
|
|
strBinaryNumber = CMIUtilString::Format("0b%s", &pN[0]);
|
|
|
|
|
|
|
|
return strBinaryNumber;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2014-08-09 00:47:42 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Remove from a string doubled up characters so only one set left. Characters
|
|
|
|
// are only removed if the previous character is already a same character.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vChar - (R) The character to search for and remove adjacent duplicates.
|
|
|
|
// Return: CMIUtilString - New version of the string.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
2015-07-03 21:45:34 +08:00
|
|
|
CMIUtilString::RemoveRepeatedCharacters(const char vChar)
|
2014-08-09 00:47:42 +08:00
|
|
|
{
|
2014-11-18 02:06:21 +08:00
|
|
|
return RemoveRepeatedCharacters(0, vChar);
|
2014-08-09 00:47:42 +08:00
|
|
|
}
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2014-08-09 00:47:42 +08:00
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Recursively remove from a string doubled up characters so only one set left.
|
|
|
|
// Characters are only removed if the previous character is already a same
|
|
|
|
// character.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: vChar - (R) The character to search for and remove adjacent duplicates.
|
2015-07-03 23:40:44 +08:00
|
|
|
// vnPos - Character position in the string.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Return: CMIUtilString - New version of the string.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
CMIUtilString
|
2015-07-03 23:40:44 +08:00
|
|
|
CMIUtilString::RemoveRepeatedCharacters(size_t vnPos, const char vChar)
|
2014-08-09 00:47:42 +08:00
|
|
|
{
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cQuote = '"';
|
2014-08-09 00:47:42 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
// Look for first quote of two
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPos = find(cQuote, vnPos);
|
|
|
|
if (nPos == std::string::npos)
|
2014-11-18 02:06:21 +08:00
|
|
|
return *this;
|
2014-08-09 00:47:42 +08:00
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nPosNext = nPos + 1;
|
|
|
|
if (nPosNext > length())
|
2014-11-18 02:06:21 +08:00
|
|
|
return *this;
|
2014-08-09 00:47:42 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
if (at(nPosNext) == cQuote)
|
|
|
|
{
|
|
|
|
*this = substr(0, nPos) + substr(nPosNext, length());
|
|
|
|
RemoveRepeatedCharacters(nPosNext, vChar);
|
|
|
|
}
|
2014-08-09 00:47:42 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return *this;
|
2014-08-09 00:47:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: Is the text in *this string surrounded by quotes.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: bool - True = Yes string is quoted, false = no quoted.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2014-11-18 02:06:21 +08:00
|
|
|
bool
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::IsQuoted() const
|
2014-08-09 00:47:42 +08:00
|
|
|
{
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cQuote = '"';
|
2014-11-18 02:06:21 +08:00
|
|
|
|
|
|
|
if (at(0) != cQuote)
|
|
|
|
return false;
|
2014-08-09 00:47:42 +08:00
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen = length();
|
2014-11-18 02:06:21 +08:00
|
|
|
if ((nLen > 0) && (at(nLen - 1) != cQuote))
|
|
|
|
return false;
|
2014-08-09 00:47:42 +08:00
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
return true;
|
2014-08-09 00:47:42 +08:00
|
|
|
}
|
2015-02-11 12:52:54 +08:00
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2015-06-18 13:27:05 +08:00
|
|
|
// Details: Find first occurrence in *this string which matches the pattern.
|
2015-02-11 12:52:54 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: vrPattern - (R) The pattern to search for.
|
2015-07-03 23:40:44 +08:00
|
|
|
// vnPos - The starting position at which to start searching. (Dflt = 0)
|
|
|
|
// Return: size_t - The position of the first substring that match.
|
2015-02-11 12:52:54 +08:00
|
|
|
// Throws: None.
|
|
|
|
//--
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t
|
|
|
|
CMIUtilString::FindFirst(const CMIUtilString &vrPattern, size_t vnPos /* = 0 */) const
|
2015-02-11 12:52:54 +08:00
|
|
|
{
|
|
|
|
return find(vrPattern, vnPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2015-06-18 13:27:05 +08:00
|
|
|
// Details: Find first occurrence in *this string which matches the pattern and isn't surrounded by quotes.
|
2015-02-11 12:52:54 +08:00
|
|
|
// 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.
|
2015-07-03 23:40:44 +08:00
|
|
|
// vnPos - Position of the first character in the string to be considered in the search. (Dflt = 0)
|
|
|
|
// Return: size_t - The position of the first substring that matches and isn't quoted.
|
2015-02-11 12:52:54 +08:00
|
|
|
// Throws: None.
|
|
|
|
//--
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t
|
2015-02-11 12:52:54 +08:00
|
|
|
CMIUtilString::FindFirst(const CMIUtilString &vrPattern, const bool vbSkipQuotedText, bool &vrwbNotFoundClosedQuote,
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t vnPos /* = 0 */) const
|
2015-02-11 12:52:54 +08:00
|
|
|
{
|
|
|
|
vrwbNotFoundClosedQuote = false;
|
|
|
|
|
|
|
|
if (!vbSkipQuotedText)
|
|
|
|
return FindFirst(vrPattern, vnPos);
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
2015-02-11 12:52:54 +08:00
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nPos = vnPos;
|
2015-02-11 12:52:54 +08:00
|
|
|
do
|
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nQuotePos(FindFirstQuote(nPos));
|
|
|
|
const size_t nPatternPos(FindFirst(vrPattern, nPos));
|
|
|
|
if (nQuotePos == std::string::npos)
|
2015-02-11 12:52:54 +08:00
|
|
|
return nPatternPos;
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nQuoteClosedPos = FindFirstQuote(nQuotePos + 1);
|
|
|
|
if (nQuoteClosedPos == std::string::npos)
|
2015-02-11 12:52:54 +08:00
|
|
|
{
|
|
|
|
vrwbNotFoundClosedQuote = true;
|
2015-07-03 23:40:44 +08:00
|
|
|
return std::string::npos;
|
2015-02-11 12:52:54 +08:00
|
|
|
}
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
if ((nPatternPos == std::string::npos) || (nPatternPos < nQuotePos))
|
2015-02-11 12:52:54 +08:00
|
|
|
return nPatternPos;
|
|
|
|
|
|
|
|
nPos = nQuoteClosedPos + 1;
|
|
|
|
}
|
|
|
|
while (nPos < nLen);
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
return std::string::npos;
|
2015-02-11 12:52:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2015-06-18 13:27:05 +08:00
|
|
|
// Details: Find first occurrence in *this string which doesn't match the pattern.
|
2015-02-11 12:52:54 +08:00
|
|
|
// Type: Method.
|
|
|
|
// Args: vrPattern - (R) The pattern to search for.
|
2015-07-03 23:40:44 +08:00
|
|
|
// vnPos - Position of the first character in the string to be considered in the search. (Dflt = 0)
|
|
|
|
// Return: size_t - The position of the first character that doesn't match.
|
2015-02-11 12:52:54 +08:00
|
|
|
// Throws: None.
|
|
|
|
//--
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t
|
|
|
|
CMIUtilString::FindFirstNot(const CMIUtilString &vrPattern, size_t vnPos /* = 0 */) const
|
2015-02-11 12:52:54 +08:00
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
|
|
|
const size_t nPatternLen(vrPattern.length());
|
2015-02-11 12:52:54 +08:00
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nPatternPos(vnPos);
|
2015-02-11 12:52:54 +08:00
|
|
|
do
|
|
|
|
{
|
|
|
|
const bool bMatchPattern(compare(nPatternPos, nPatternLen, vrPattern) == 0);
|
|
|
|
if (!bMatchPattern)
|
|
|
|
return nPatternPos;
|
|
|
|
nPatternPos += nPatternLen;
|
|
|
|
}
|
|
|
|
while (nPatternPos < nLen);
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
return std::string::npos;
|
2015-02-11 12:52:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
2015-06-18 13:27:05 +08:00
|
|
|
// Details: Find first occurrence of not escaped quotation mark in *this string.
|
2015-02-11 12:52:54 +08:00
|
|
|
// Type: Method.
|
2015-07-03 23:40:44 +08:00
|
|
|
// Args: vnPos - Position of the first character in the string to be considered in the search.
|
|
|
|
// Return: size_t - The position of the quotation mark.
|
2015-02-11 12:52:54 +08:00
|
|
|
// Throws: None.
|
|
|
|
//--
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t
|
|
|
|
CMIUtilString::FindFirstQuote(size_t vnPos) const
|
2015-02-11 12:52:54 +08:00
|
|
|
{
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cBckSlash('\\');
|
|
|
|
const char cQuote('"');
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
2015-02-11 12:52:54 +08:00
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nPos = vnPos;
|
2015-02-11 12:52:54 +08:00
|
|
|
do
|
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nBckSlashPos(find(cBckSlash, nPos));
|
|
|
|
const size_t nQuotePos(find(cQuote, nPos));
|
|
|
|
if ((nBckSlashPos == std::string::npos) || (nQuotePos == std::string::npos))
|
2015-02-11 12:52:54 +08:00
|
|
|
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);
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
return std::string::npos;
|
2015-02-11 12:52:54 +08:00
|
|
|
}
|
2015-02-27 02:14:30 +08:00
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Get escaped string from *this string.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - The escaped version of the initial string.
|
|
|
|
// Throws: None.
|
|
|
|
//--
|
|
|
|
CMIUtilString
|
2015-07-03 23:40:44 +08:00
|
|
|
CMIUtilString::Escape(bool vbEscapeQuotes /* = false */) const
|
2015-02-27 02:14:30 +08:00
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
2015-02-27 02:14:30 +08:00
|
|
|
CMIUtilString strNew;
|
|
|
|
strNew.reserve(nLen);
|
2015-07-03 23:40:44 +08:00
|
|
|
for (size_t nIndex(0); nIndex < nLen; ++nIndex)
|
2015-02-27 02:14:30 +08:00
|
|
|
{
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cUnescapedChar((*this)[nIndex]);
|
2015-05-08 19:21:13 +08:00
|
|
|
if (cUnescapedChar == '"' && vbEscapeQuotes)
|
|
|
|
strNew.append("\\\"");
|
|
|
|
else
|
|
|
|
strNew.append(ConvertToPrintableASCII((char)cUnescapedChar));
|
2015-02-27 02:14:30 +08:00
|
|
|
}
|
|
|
|
return strNew;
|
|
|
|
}
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Get string with backslashes in front of double quote '"' and backslash '\\'
|
|
|
|
// characters.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - The wrapped version of the initial string.
|
|
|
|
// Throws: None.
|
|
|
|
//--
|
|
|
|
CMIUtilString
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::AddSlashes() const
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
{
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cBckSlash('\\');
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
CMIUtilString strNew;
|
|
|
|
strNew.reserve(nLen);
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nOffset(0);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
while (nOffset < nLen)
|
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nUnescapedCharPos(find_first_of("\"\\", nOffset));
|
|
|
|
const bool bUnescapedCharNotFound(nUnescapedCharPos == std::string::npos);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
if (bUnescapedCharNotFound)
|
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nAppendAll(std::string::npos);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
strNew.append(*this, nOffset, nAppendAll);
|
|
|
|
break;
|
|
|
|
}
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nAppendLen(nUnescapedCharPos - nOffset);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
strNew.append(*this, nOffset, nAppendLen);
|
|
|
|
strNew.push_back(cBckSlash);
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cUnescapedChar((*this)[nUnescapedCharPos]);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
strNew.push_back(cUnescapedChar);
|
|
|
|
nOffset = nUnescapedCharPos + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return strNew;
|
|
|
|
}
|
|
|
|
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
|
|
// Details: Remove backslashes added by CMIUtilString::AddSlashes.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMIUtilString - The initial version of wrapped string.
|
|
|
|
// Throws: None.
|
|
|
|
//--
|
|
|
|
CMIUtilString
|
2015-08-04 18:24:20 +08:00
|
|
|
CMIUtilString::StripSlashes() const
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
{
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cBckSlash('\\');
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nLen(length());
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
CMIUtilString strNew;
|
|
|
|
strNew.reserve(nLen);
|
|
|
|
|
2015-07-03 23:40:44 +08:00
|
|
|
size_t nOffset(0);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
while (nOffset < nLen)
|
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nBckSlashPos(find(cBckSlash, nOffset));
|
|
|
|
const bool bBckSlashNotFound(nBckSlashPos == std::string::npos);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
if (bBckSlashNotFound)
|
|
|
|
{
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nAppendAll(std::string::npos);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
strNew.append(*this, nOffset, nAppendAll);
|
|
|
|
break;
|
|
|
|
}
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nAppendLen(nBckSlashPos - nOffset);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
strNew.append(*this, nOffset, nAppendLen);
|
|
|
|
const bool bBckSlashIsLast(nBckSlashPos == nLen);
|
|
|
|
if (bBckSlashIsLast)
|
|
|
|
{
|
|
|
|
strNew.push_back(cBckSlash);
|
|
|
|
break;
|
|
|
|
}
|
2015-07-03 21:45:34 +08:00
|
|
|
const char cEscapedChar((*this)[nBckSlashPos + 1]);
|
2015-07-03 23:40:44 +08:00
|
|
|
const size_t nEscapedCharPos(std::string("\"\\").find(cEscapedChar));
|
|
|
|
const bool bEscapedCharNotFound(nEscapedCharPos == std::string::npos);
|
Fix handling of double quotes (MI)
Summary:
* Clean CMICmdArgValString::Validate: now it's based on CMIUtilString::SplitConsiderQuotes method:
A bit of introduction:
# Command line is wrapped into CMICmdArgContext.
# CMICmdArgSet is a set of arguments to be parsed. This class contains CMICmdArgContext as a private member.
# MI command is class which is inhereted from CMICmdBase. It contains CMICmdArgSet as a private member.
When command is executed CMICmdBase::ParseArgs() is called. This method adds args for parsing using CMICmdArgSet::Add(). Then CMICmdBase::ParseValidateCmdOptions() is called, which calls CMICmdArgSet::Validate(). Then it gets a number of arguments (using SplitConsiderQuotes().array_length) and for each arguments registered in ParseArgs() tries to validate it using CMICmdArgValBase::Validate(). Every user commands parses this string again (first time it was made in SplitConsiderQuotes) and in case of CMICmdArgValString it was made incorrectly. It searches the first and last quotes (but it should be first and next after first). Besides, it was splitted into 4 cases.
I'm just using SplitConsiderQuotes directly, and I don't split them by hand again.
Actually, I think we should do so in every CMICmdArgVal_XXX::Validate() method.
* Enable MiInterpreterExecTestCase.test_lldbmi_target_create test
* Fix MiExecTestCase.test_lldbmi_exec_arguments_set test
All tests pass on OS X.
Reviewers: abidh, emaste, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, emaste, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7860
llvm-svn: 230654
2015-02-27 02:21:22 +08:00
|
|
|
if (bEscapedCharNotFound)
|
|
|
|
strNew.push_back(cBckSlash);
|
|
|
|
strNew.push_back(cEscapedChar);
|
|
|
|
nOffset = nBckSlashPos + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return strNew;
|
|
|
|
}
|
2015-05-08 19:21:13 +08:00
|
|
|
|
|
|
|
CMIUtilString
|
2015-07-28 13:43:47 +08:00
|
|
|
CMIUtilString::ConvertToPrintableASCII(const char vChar, bool bEscapeQuotes)
|
2015-05-08 19:21:13 +08:00
|
|
|
{
|
|
|
|
switch (vChar)
|
|
|
|
{
|
|
|
|
case '\a':
|
|
|
|
return "\\a";
|
|
|
|
case '\b':
|
|
|
|
return "\\b";
|
|
|
|
case '\t':
|
|
|
|
return "\\t";
|
|
|
|
case '\n':
|
|
|
|
return "\\n";
|
|
|
|
case '\v':
|
|
|
|
return "\\v";
|
|
|
|
case '\f':
|
|
|
|
return "\\f";
|
|
|
|
case '\r':
|
|
|
|
return "\\r";
|
|
|
|
case '\033':
|
|
|
|
return "\\e";
|
|
|
|
case '\\':
|
|
|
|
return "\\\\";
|
2015-07-28 13:43:47 +08:00
|
|
|
case '"':
|
|
|
|
if (bEscapeQuotes)
|
|
|
|
return "\\\"";
|
|
|
|
// fall thru
|
2015-05-08 19:21:13 +08:00
|
|
|
default:
|
|
|
|
if (::isprint(vChar))
|
|
|
|
return Format("%c", vChar);
|
|
|
|
else
|
|
|
|
return Format("\\x%02" PRIx8, vChar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CMIUtilString
|
2015-07-28 13:43:47 +08:00
|
|
|
CMIUtilString::ConvertCharValueToPrintableASCII(char vChar, bool bEscapeQuotes)
|
2015-05-08 19:21:13 +08:00
|
|
|
{
|
2015-07-28 13:43:47 +08:00
|
|
|
switch (vChar)
|
|
|
|
{
|
|
|
|
case '\a':
|
|
|
|
return "\\a";
|
|
|
|
case '\b':
|
|
|
|
return "\\b";
|
|
|
|
case '\t':
|
|
|
|
return "\\t";
|
|
|
|
case '\n':
|
|
|
|
return "\\n";
|
|
|
|
case '\v':
|
|
|
|
return "\\v";
|
|
|
|
case '\f':
|
|
|
|
return "\\f";
|
|
|
|
case '\r':
|
|
|
|
return "\\r";
|
|
|
|
case '\033':
|
|
|
|
return "\\e";
|
|
|
|
case '\\':
|
|
|
|
return "\\\\";
|
|
|
|
case '"':
|
|
|
|
if (bEscapeQuotes)
|
|
|
|
return "\\\"";
|
|
|
|
// fall thru
|
|
|
|
default:
|
|
|
|
if (::isprint(vChar))
|
|
|
|
return Format("%c", vChar);
|
|
|
|
else
|
|
|
|
return CMIUtilString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CMIUtilString
|
|
|
|
CMIUtilString::ConvertToPrintableASCII(const char16_t vChar16, bool bEscapeQuotes)
|
|
|
|
{
|
|
|
|
if (vChar16 == (char16_t)(char)vChar16)
|
|
|
|
{
|
2015-05-08 19:21:13 +08:00
|
|
|
// Convert char16_t to char (if possible)
|
2015-07-28 13:43:47 +08:00
|
|
|
CMIUtilString str = ConvertCharValueToPrintableASCII((char)vChar16, bEscapeQuotes);
|
|
|
|
if (str.length() > 0)
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
return Format("\\u%02" PRIx8 "%02" PRIx8,
|
2015-05-08 19:21:13 +08:00
|
|
|
(vChar16 >> 8) & 0xff, vChar16 & 0xff);
|
|
|
|
}
|
|
|
|
|
|
|
|
CMIUtilString
|
2015-07-28 13:43:47 +08:00
|
|
|
CMIUtilString::ConvertToPrintableASCII(const char32_t vChar32, bool bEscapeQuotes)
|
2015-05-08 19:21:13 +08:00
|
|
|
{
|
2015-07-28 13:43:47 +08:00
|
|
|
if (vChar32 == (char32_t)(char)vChar32)
|
|
|
|
{
|
2015-05-08 19:21:13 +08:00
|
|
|
// Convert char32_t to char (if possible)
|
2015-07-28 13:43:47 +08:00
|
|
|
CMIUtilString str = ConvertCharValueToPrintableASCII((char)vChar32, bEscapeQuotes);
|
|
|
|
if (str.length() > 0)
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
return Format("\\U%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
|
2015-05-08 19:21:13 +08:00
|
|
|
(vChar32 >> 24) & 0xff, (vChar32 >> 16) & 0xff,
|
|
|
|
(vChar32 >> 8) & 0xff, vChar32 & 0xff);
|
|
|
|
}
|