mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-25 01:28:50 -05:00
Merge topic 'modernize_string_view_cmOutputConverter'
ec892a572bcmOutputConverter: Make shell escaping methods cm::string_view based8573e20c43cmOutputConverter: Let GetFortranFormat accept a cm::string_view4911762358cmOutputConverter: Return bool instead of int in utility functionsa929255deccmOutputConverter: Let cmOutputConverterIsShellOperator accept cm::string_view1b30b28c04cmOutputConverter: Let cmOutputConverterIsShellOperator accept cm::string_view6675f785becmOutputConverter: Let EscapeForCMake accept a cm::string_view09977c1816cmSystemTool: Let TrimWhitespace accept a cm::string_view2f19e53705cmSystemTool: Let HelpFileName accept a cm::string_view ... Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3615
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <set>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "cmState.h"
|
||||
@@ -38,10 +37,10 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
|
||||
return this->ConvertToOutputFormat(remote, format);
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
|
||||
std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source,
|
||||
OutputFormat output) const
|
||||
{
|
||||
std::string result = source;
|
||||
std::string result(source);
|
||||
// Convert it to an output path.
|
||||
if (output == SHELL || output == WATCOMQUOTE) {
|
||||
result = this->ConvertDirectorySeparatorsForShell(source);
|
||||
@@ -53,9 +52,9 @@ std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
|
||||
const std::string& source) const
|
||||
cm::string_view source) const
|
||||
{
|
||||
std::string result = source;
|
||||
std::string result(source);
|
||||
// For the MSYS shell convert drive letters to posix paths, so
|
||||
// that c:/some/path becomes /c/some/path. This is needed to
|
||||
// avoid problems with the shell path translation.
|
||||
@@ -71,21 +70,21 @@ std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool cmOutputConverterIsShellOperator(const std::string& str)
|
||||
static bool cmOutputConverterIsShellOperator(cm::string_view str)
|
||||
{
|
||||
static std::set<std::string> const shellOperators{
|
||||
static std::set<cm::string_view> const shellOperators{
|
||||
"<", ">", "<<", ">>", "|", "||", "&&", "&>", "1>", "2>", "2>&1", "1>&2"
|
||||
};
|
||||
return (shellOperators.count(str) != 0);
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::EscapeForShell(const std::string& str,
|
||||
std::string cmOutputConverter::EscapeForShell(cm::string_view str,
|
||||
bool makeVars, bool forEcho,
|
||||
bool useWatcomQuote) const
|
||||
{
|
||||
// Do not escape shell operators.
|
||||
if (cmOutputConverterIsShellOperator(str)) {
|
||||
return str;
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
// Compute the flags for the target shell environment.
|
||||
@@ -117,46 +116,44 @@ std::string cmOutputConverter::EscapeForShell(const std::string& str,
|
||||
flags |= Shell_Flag_IsUnix;
|
||||
}
|
||||
|
||||
return Shell__GetArgument(str.c_str(), flags);
|
||||
return Shell__GetArgument(str, flags);
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::EscapeForCMake(const std::string& str)
|
||||
std::string cmOutputConverter::EscapeForCMake(cm::string_view str)
|
||||
{
|
||||
// Always double-quote the argument to take care of most escapes.
|
||||
std::string result = "\"";
|
||||
for (const char* c = str.c_str(); *c; ++c) {
|
||||
if (*c == '"') {
|
||||
for (const char c : str) {
|
||||
if (c == '"') {
|
||||
// Escape the double quote to avoid ending the argument.
|
||||
result += "\\\"";
|
||||
} else if (*c == '$') {
|
||||
} else if (c == '$') {
|
||||
// Escape the dollar to avoid expanding variables.
|
||||
result += "\\$";
|
||||
} else if (*c == '\\') {
|
||||
} else if (c == '\\') {
|
||||
// Escape the backslash to avoid other escapes.
|
||||
result += "\\\\";
|
||||
} else {
|
||||
// Other characters will be parsed correctly.
|
||||
result += *c;
|
||||
result += c;
|
||||
}
|
||||
}
|
||||
result += "\"";
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
|
||||
std::string cmOutputConverter::EscapeWindowsShellArgument(cm::string_view arg,
|
||||
int shell_flags)
|
||||
{
|
||||
return Shell__GetArgument(arg, shell_flags);
|
||||
}
|
||||
|
||||
cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
|
||||
const char* value)
|
||||
cm::string_view value)
|
||||
{
|
||||
FortranFormat format = FortranFormatNone;
|
||||
if (value && *value) {
|
||||
std::vector<std::string> fmt;
|
||||
cmSystemTools::ExpandListArgument(value, fmt);
|
||||
for (std::string const& fi : fmt) {
|
||||
if (!value.empty()) {
|
||||
for (std::string const& fi : cmSystemTools::ExpandedListArgument(value)) {
|
||||
if (fi == "FIXED") {
|
||||
format = FortranFormatFixed;
|
||||
}
|
||||
@@ -168,6 +165,15 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
|
||||
return format;
|
||||
}
|
||||
|
||||
cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
|
||||
const char* value)
|
||||
{
|
||||
if (!value) {
|
||||
return FortranFormatNone;
|
||||
}
|
||||
return GetFortranFormat(cm::string_view(value));
|
||||
}
|
||||
|
||||
void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
|
||||
{
|
||||
this->LinkScriptShell = linkScriptShell;
|
||||
@@ -213,12 +219,12 @@ use the caret character itself (^), use two in a row (^^).
|
||||
*/
|
||||
|
||||
/* Some helpers to identify character classes */
|
||||
static int Shell__CharIsWhitespace(char c)
|
||||
static bool Shell__CharIsWhitespace(char c)
|
||||
{
|
||||
return ((c == ' ') || (c == '\t'));
|
||||
}
|
||||
|
||||
static int Shell__CharNeedsQuotesOnUnix(char c)
|
||||
static bool Shell__CharNeedsQuotesOnUnix(char c)
|
||||
{
|
||||
return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
|
||||
(c == '&') || (c == '$') || (c == '(') || (c == ')') || (c == '~') ||
|
||||
@@ -226,51 +232,52 @@ static int Shell__CharNeedsQuotesOnUnix(char c)
|
||||
(c == '\\'));
|
||||
}
|
||||
|
||||
static int Shell__CharNeedsQuotesOnWindows(char c)
|
||||
static bool Shell__CharNeedsQuotesOnWindows(char c)
|
||||
{
|
||||
return ((c == '\'') || (c == '#') || (c == '&') || (c == '<') ||
|
||||
(c == '>') || (c == '|') || (c == '^'));
|
||||
}
|
||||
|
||||
static int Shell__CharIsMakeVariableName(char c)
|
||||
static bool Shell__CharIsMakeVariableName(char c)
|
||||
{
|
||||
return c && (c == '_' || isalpha((static_cast<int>(c))));
|
||||
}
|
||||
|
||||
int cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
|
||||
bool cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
|
||||
{
|
||||
/* On Windows the built-in command shell echo never needs quotes. */
|
||||
if (!(flags & Shell_Flag_IsUnix) && (flags & Shell_Flag_EchoWindows)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* On all platforms quotes are needed to preserve whitespace. */
|
||||
if (Shell__CharIsWhitespace(c)) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (flags & Shell_Flag_IsUnix) {
|
||||
/* On UNIX several special characters need quotes to preserve them. */
|
||||
if (Shell__CharNeedsQuotesOnUnix(c)) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
/* On Windows several special characters need quotes to preserve them. */
|
||||
if (Shell__CharNeedsQuotesOnWindows(c)) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
|
||||
cm::string_view::iterator cmOutputConverter::Shell__SkipMakeVariables(
|
||||
cm::string_view::iterator c, cm::string_view::iterator end)
|
||||
{
|
||||
while (*c == '$' && *(c + 1) == '(') {
|
||||
const char* skip = c + 2;
|
||||
while (Shell__CharIsMakeVariableName(*skip)) {
|
||||
while ((c != end && (c + 1) != end) && (*c == '$' && *(c + 1) == '(')) {
|
||||
cm::string_view::iterator skip = c + 2;
|
||||
while ((skip != end) && Shell__CharIsMakeVariableName(*skip)) {
|
||||
++skip;
|
||||
}
|
||||
if (*skip == ')') {
|
||||
if ((skip != end) && *skip == ')') {
|
||||
c = skip + 1;
|
||||
} else {
|
||||
break;
|
||||
@@ -302,63 +309,60 @@ flag later when we understand applications of this better.
|
||||
*/
|
||||
#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
|
||||
|
||||
int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int flags)
|
||||
bool cmOutputConverter::Shell__ArgumentNeedsQuotes(cm::string_view in,
|
||||
int flags)
|
||||
{
|
||||
/* The empty string needs quotes. */
|
||||
if (!*in) {
|
||||
return 1;
|
||||
if (in.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Scan the string for characters that require quoting. */
|
||||
{
|
||||
const char* c;
|
||||
for (c = in; *c; ++c) {
|
||||
/* Look for $(MAKEVAR) syntax if requested. */
|
||||
if (flags & Shell_Flag_AllowMakeVariables) {
|
||||
for (cm::string_view::iterator cit = in.begin(), cend = in.end();
|
||||
cit != cend; ++cit) {
|
||||
/* Look for $(MAKEVAR) syntax if requested. */
|
||||
if (flags & Shell_Flag_AllowMakeVariables) {
|
||||
#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
|
||||
const char* skip = Shell__SkipMakeVariables(c);
|
||||
if (skip != c) {
|
||||
/* We need to quote make variable references to preserve the
|
||||
string with contents substituted in its place. */
|
||||
return 1;
|
||||
}
|
||||
cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend);
|
||||
if (skip != cit) {
|
||||
/* We need to quote make variable references to preserve the
|
||||
string with contents substituted in its place. */
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
/* Skip over the make variable references if any are present. */
|
||||
c = Shell__SkipMakeVariables(c);
|
||||
/* Skip over the make variable references if any are present. */
|
||||
cit = Shell__SkipMakeVariables(cit, cend);
|
||||
|
||||
/* Stop if we have reached the end of the string. */
|
||||
if (!*c) {
|
||||
break;
|
||||
}
|
||||
/* Stop if we have reached the end of the string. */
|
||||
if (cit == cend) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether this character needs quotes. */
|
||||
if (Shell__CharNeedsQuotes(*c, flags)) {
|
||||
return 1;
|
||||
}
|
||||
/* Check whether this character needs quotes. */
|
||||
if (Shell__CharNeedsQuotes(*cit, flags)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* On Windows some single character arguments need quotes. */
|
||||
if (flags & Shell_Flag_IsUnix && *in && !*(in + 1)) {
|
||||
char c = *in;
|
||||
if (flags & Shell_Flag_IsUnix && in.size() == 1) {
|
||||
char c = in[0];
|
||||
if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
std::string cmOutputConverter::Shell__GetArgument(cm::string_view in,
|
||||
int flags)
|
||||
{
|
||||
/* Output will be at least as long as input string. */
|
||||
std::string out;
|
||||
out.reserve(strlen(in));
|
||||
|
||||
/* String iterator. */
|
||||
const char* c;
|
||||
out.reserve(in.size());
|
||||
|
||||
/* Keep track of how many backslashes have been encountered in a row. */
|
||||
int windows_backslashes = 0;
|
||||
@@ -378,14 +382,15 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
}
|
||||
|
||||
/* Scan the string for characters that require escaping or quoting. */
|
||||
for (c = in; *c; ++c) {
|
||||
for (cm::string_view::iterator cit = in.begin(), cend = in.end();
|
||||
cit != cend; ++cit) {
|
||||
/* Look for $(MAKEVAR) syntax if requested. */
|
||||
if (flags & Shell_Flag_AllowMakeVariables) {
|
||||
const char* skip = Shell__SkipMakeVariables(c);
|
||||
if (skip != c) {
|
||||
cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend);
|
||||
if (skip != cit) {
|
||||
/* Copy to the end of the make variable references. */
|
||||
while (c != skip) {
|
||||
out += *c++;
|
||||
while (cit != skip) {
|
||||
out += *cit++;
|
||||
}
|
||||
|
||||
/* The make variable reference eliminates any escaping needed
|
||||
@@ -393,7 +398,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
windows_backslashes = 0;
|
||||
|
||||
/* Stop if we have reached the end of the string. */
|
||||
if (!*c) {
|
||||
if (cit == cend) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -403,7 +408,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
if (flags & Shell_Flag_IsUnix) {
|
||||
/* On Unix a few special characters need escaping even inside a
|
||||
quoted argument. */
|
||||
if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
|
||||
if (*cit == '\\' || *cit == '"' || *cit == '`' || *cit == '$') {
|
||||
/* This character needs a backslash to escape it. */
|
||||
out += '\\';
|
||||
}
|
||||
@@ -411,10 +416,10 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
/* On Windows the built-in command shell echo never needs escaping. */
|
||||
} else {
|
||||
/* On Windows only backslashes and double-quotes need escaping. */
|
||||
if (*c == '\\') {
|
||||
if (*cit == '\\') {
|
||||
/* Found a backslash. It may need to be escaped later. */
|
||||
++windows_backslashes;
|
||||
} else if (*c == '"') {
|
||||
} else if (*cit == '"') {
|
||||
/* Found a double-quote. Escape all immediately preceding
|
||||
backslashes. */
|
||||
while (windows_backslashes > 0) {
|
||||
@@ -432,7 +437,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
}
|
||||
|
||||
/* Check whether this character needs escaping for a make tool. */
|
||||
if (*c == '$') {
|
||||
if (*cit == '$') {
|
||||
if (flags & Shell_Flag_Make) {
|
||||
/* In Makefiles a dollar is written $$. The make tool will
|
||||
replace it with just $ before passing it to the shell. */
|
||||
@@ -449,7 +454,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
/* Otherwise a dollar is written just $. */
|
||||
out += '$';
|
||||
}
|
||||
} else if (*c == '#') {
|
||||
} else if (*cit == '#') {
|
||||
if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
|
||||
/* In Watcom WMake makefiles a pound is written $#. The make
|
||||
tool will replace it with just # before passing it to the
|
||||
@@ -459,7 +464,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
/* Otherwise a pound is written just #. */
|
||||
out += '#';
|
||||
}
|
||||
} else if (*c == '%') {
|
||||
} else if (*cit == '%') {
|
||||
if ((flags & Shell_Flag_VSIDE) ||
|
||||
((flags & Shell_Flag_Make) &&
|
||||
((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
|
||||
@@ -469,7 +474,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
/* Otherwise a percent is written just %. */
|
||||
out += '%';
|
||||
}
|
||||
} else if (*c == ';') {
|
||||
} else if (*cit == ';') {
|
||||
if (flags & Shell_Flag_VSIDE) {
|
||||
/* In a VS IDE a semicolon is written ";". If this is written
|
||||
in an un-quoted argument it starts a quoted segment,
|
||||
@@ -483,7 +488,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
|
||||
}
|
||||
} else {
|
||||
/* Store this character. */
|
||||
out += *c;
|
||||
out += *cit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-12
@@ -5,9 +5,10 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "cmStateSnapshot.h"
|
||||
#include "cm_string_view.hxx"
|
||||
|
||||
#include <string>
|
||||
|
||||
class cmState;
|
||||
|
||||
@@ -22,10 +23,9 @@ public:
|
||||
WATCOMQUOTE,
|
||||
RESPONSE
|
||||
};
|
||||
std::string ConvertToOutputFormat(const std::string& source,
|
||||
std::string ConvertToOutputFormat(cm::string_view source,
|
||||
OutputFormat output) const;
|
||||
std::string ConvertDirectorySeparatorsForShell(
|
||||
const std::string& source) const;
|
||||
std::string ConvertDirectorySeparatorsForShell(cm::string_view source) const;
|
||||
|
||||
//! for existing files convert to output path and short path if spaces
|
||||
std::string ConvertToOutputForExisting(const std::string& remote,
|
||||
@@ -72,15 +72,15 @@ public:
|
||||
Shell_Flag_IsUnix = (1 << 8)
|
||||
};
|
||||
|
||||
std::string EscapeForShell(const std::string& str, bool makeVars = false,
|
||||
std::string EscapeForShell(cm::string_view str, bool makeVars = false,
|
||||
bool forEcho = false,
|
||||
bool useWatcomQuote = false) const;
|
||||
|
||||
static std::string EscapeForCMake(const std::string& str);
|
||||
static std::string EscapeForCMake(cm::string_view str);
|
||||
|
||||
/** Compute an escaped version of the given argument for use in a
|
||||
windows shell. */
|
||||
static std::string EscapeWindowsShellArgument(const char* arg,
|
||||
static std::string EscapeWindowsShellArgument(cm::string_view arg,
|
||||
int shell_flags);
|
||||
|
||||
enum FortranFormat
|
||||
@@ -89,15 +89,17 @@ public:
|
||||
FortranFormatFixed,
|
||||
FortranFormatFree
|
||||
};
|
||||
static FortranFormat GetFortranFormat(cm::string_view value);
|
||||
static FortranFormat GetFortranFormat(const char* value);
|
||||
|
||||
private:
|
||||
cmState* GetState() const;
|
||||
|
||||
static int Shell__CharNeedsQuotes(char c, int flags);
|
||||
static const char* Shell__SkipMakeVariables(const char* c);
|
||||
static int Shell__ArgumentNeedsQuotes(const char* in, int flags);
|
||||
static std::string Shell__GetArgument(const char* in, int flags);
|
||||
static bool Shell__CharNeedsQuotes(char c, int flags);
|
||||
static cm::string_view::iterator Shell__SkipMakeVariables(
|
||||
cm::string_view::iterator begin, cm::string_view::iterator end);
|
||||
static bool Shell__ArgumentNeedsQuotes(cm::string_view in, int flags);
|
||||
static std::string Shell__GetArgument(cm::string_view in, int flags);
|
||||
|
||||
private:
|
||||
cmStateSnapshot StateSnapshot;
|
||||
|
||||
+29
-24
@@ -176,36 +176,37 @@ void cmSystemTools::ExpandRegistryValues(std::string& source,
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string cmSystemTools::EscapeQuotes(const std::string& str)
|
||||
std::string cmSystemTools::EscapeQuotes(cm::string_view str)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(str.size());
|
||||
for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
|
||||
if (*ch == '"') {
|
||||
for (const char ch : str) {
|
||||
if (ch == '"') {
|
||||
result += '\\';
|
||||
}
|
||||
result += *ch;
|
||||
result += ch;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string cmSystemTools::HelpFileName(std::string name)
|
||||
std::string cmSystemTools::HelpFileName(cm::string_view str)
|
||||
{
|
||||
std::string name(str);
|
||||
cmSystemTools::ReplaceString(name, "<", "");
|
||||
cmSystemTools::ReplaceString(name, ">", "");
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string cmSystemTools::TrimWhitespace(const std::string& s)
|
||||
std::string cmSystemTools::TrimWhitespace(cm::string_view str)
|
||||
{
|
||||
std::string::const_iterator start = s.begin();
|
||||
while (start != s.end() && cm_isspace(*start)) {
|
||||
auto start = str.begin();
|
||||
while (start != str.end() && cm_isspace(*start)) {
|
||||
++start;
|
||||
}
|
||||
if (start == s.end()) {
|
||||
return "";
|
||||
if (start == str.end()) {
|
||||
return std::string();
|
||||
}
|
||||
std::string::const_iterator stop = s.end() - 1;
|
||||
auto stop = str.end() - 1;
|
||||
while (cm_isspace(*stop)) {
|
||||
--stop;
|
||||
}
|
||||
@@ -1121,7 +1122,7 @@ void cmSystemTools::GlobDirs(const std::string& path,
|
||||
}
|
||||
}
|
||||
|
||||
void cmSystemTools::ExpandListArgument(const std::string& arg,
|
||||
void cmSystemTools::ExpandListArgument(cm::string_view arg,
|
||||
std::vector<std::string>& argsOut,
|
||||
bool emptyArgs)
|
||||
{
|
||||
@@ -1129,25 +1130,29 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
|
||||
if (!emptyArgs && arg.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if there are no ; in the name then just copy the current string
|
||||
if (arg.find(';') == std::string::npos) {
|
||||
argsOut.push_back(arg);
|
||||
if (arg.find(';') == cm::string_view::npos) {
|
||||
argsOut.emplace_back(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string newArg;
|
||||
const char* last = arg.c_str();
|
||||
// Break the string at non-escaped semicolons not nested in [].
|
||||
int squareNesting = 0;
|
||||
for (const char* c = last; *c; ++c) {
|
||||
cm::string_view::iterator last = arg.begin();
|
||||
cm::string_view::iterator const cend = arg.end();
|
||||
for (cm::string_view::iterator c = last; c != cend; ++c) {
|
||||
switch (*c) {
|
||||
case '\\': {
|
||||
// We only want to allow escaping of semicolons. Other
|
||||
// escapes should not be processed here.
|
||||
const char* next = c + 1;
|
||||
if (*next == ';') {
|
||||
newArg.append(last, c - last);
|
||||
cm::string_view::iterator cnext = c + 1;
|
||||
if ((cnext != cend) && *cnext == ';') {
|
||||
newArg.append(last, c);
|
||||
// Skip over the escape character
|
||||
last = c = next;
|
||||
last = cnext;
|
||||
c = cnext;
|
||||
}
|
||||
} break;
|
||||
case '[': {
|
||||
@@ -1160,7 +1165,7 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
|
||||
// Break the string here if we are not nested inside square
|
||||
// brackets.
|
||||
if (squareNesting == 0) {
|
||||
newArg.append(last, c - last);
|
||||
newArg.append(last, c);
|
||||
// Skip over the semicolon
|
||||
last = c + 1;
|
||||
if (!newArg.empty() || emptyArgs) {
|
||||
@@ -1175,15 +1180,15 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
|
||||
} break;
|
||||
}
|
||||
}
|
||||
newArg.append(last);
|
||||
newArg.append(last, cend);
|
||||
if (!newArg.empty() || emptyArgs) {
|
||||
// Add the last argument if the string is not empty.
|
||||
argsOut.push_back(newArg);
|
||||
argsOut.push_back(std::move(newArg));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> cmSystemTools::ExpandedListArgument(
|
||||
const std::string& arg, bool emptyArgs)
|
||||
cm::string_view arg, bool emptyArgs)
|
||||
{
|
||||
std::vector<std::string> argsOut;
|
||||
ExpandListArgument(arg, argsOut, emptyArgs);
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
* Expand the ; separated string @a arg into multiple arguments.
|
||||
* All found arguments are appended to @a argsOut.
|
||||
*/
|
||||
static void ExpandListArgument(const std::string& arg,
|
||||
static void ExpandListArgument(cm::string_view arg,
|
||||
std::vector<std::string>& argsOut,
|
||||
bool emptyArgs = false);
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
* Same as ExpandListArgument but a new vector is created containing
|
||||
* the expanded arguments from the string @a arg.
|
||||
*/
|
||||
static std::vector<std::string> ExpandedListArgument(const std::string& arg,
|
||||
static std::vector<std::string> ExpandedListArgument(cm::string_view arg,
|
||||
bool emptyArgs = false);
|
||||
|
||||
/**
|
||||
@@ -78,15 +78,15 @@ public:
|
||||
KeyWOW64 view = KeyWOW64_Default);
|
||||
|
||||
//! Escape quotes in a string.
|
||||
static std::string EscapeQuotes(const std::string& str);
|
||||
static std::string EscapeQuotes(cm::string_view str);
|
||||
|
||||
/** Map help document name to file name. */
|
||||
static std::string HelpFileName(std::string);
|
||||
static std::string HelpFileName(cm::string_view);
|
||||
|
||||
/**
|
||||
* Returns a string that has whitespace removed from the start and the end.
|
||||
*/
|
||||
static std::string TrimWhitespace(const std::string& s);
|
||||
static std::string TrimWhitespace(cm::string_view str);
|
||||
|
||||
using MessageCallback = std::function<void(const std::string&, const char*)>;
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user