|
|
@@ -15,6 +15,7 @@
|
|
|
#include "cmake.h"
|
|
|
|
|
|
#include <assert.h>
|
|
|
+#include <sstream>
|
|
|
|
|
|
#include <ctype.h> /* isalpha */
|
|
|
#include <string.h> /* strlen */
|
|
|
@@ -328,19 +329,9 @@ std::string cmOutputConverter::EscapeForShell(const std::string& str,
|
|
|
flags |= Shell_Flag_NMake;
|
|
|
}
|
|
|
|
|
|
- // Compute the buffer size needed.
|
|
|
- int size = (this->GetState()->UseWindowsShell()
|
|
|
- ? Shell_GetArgumentSizeForWindows(str.c_str(), flags)
|
|
|
- : Shell_GetArgumentSizeForUnix(str.c_str(), flags));
|
|
|
-
|
|
|
- // Compute the shell argument itself.
|
|
|
- std::vector<char> arg(size);
|
|
|
- if (this->GetState()->UseWindowsShell()) {
|
|
|
- Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
|
|
|
- } else {
|
|
|
- Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
|
|
|
- }
|
|
|
- return std::string(&arg[0]);
|
|
|
+ return this->GetState()->UseWindowsShell()
|
|
|
+ ? Shell_GetArgumentForWindows(str.c_str(), flags)
|
|
|
+ : Shell_GetArgumentForUnix(str.c_str(), flags);
|
|
|
}
|
|
|
|
|
|
std::string cmOutputConverter::EscapeForCMake(const std::string& str)
|
|
|
@@ -369,18 +360,7 @@ std::string cmOutputConverter::EscapeForCMake(const std::string& str)
|
|
|
std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
|
|
|
int shell_flags)
|
|
|
{
|
|
|
- char local_buffer[1024];
|
|
|
- char* buffer = local_buffer;
|
|
|
- int size = Shell_GetArgumentSizeForWindows(arg, shell_flags);
|
|
|
- if (size > 1024) {
|
|
|
- buffer = new char[size];
|
|
|
- }
|
|
|
- Shell_GetArgumentForWindows(arg, buffer, shell_flags);
|
|
|
- std::string result(buffer);
|
|
|
- if (buffer != local_buffer) {
|
|
|
- delete[] buffer;
|
|
|
- }
|
|
|
- return result;
|
|
|
+ return Shell_GetArgumentForWindows(arg, shell_flags);
|
|
|
}
|
|
|
|
|
|
cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
|
|
|
@@ -586,12 +566,10 @@ int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int cmOutputConverter::Shell__GetArgumentSize(const char* in, int isUnix,
|
|
|
- int flags)
|
|
|
+std::string cmOutputConverter::Shell__GetArgument(const char* in, int isUnix,
|
|
|
+ int flags)
|
|
|
{
|
|
|
- /* Start with the length of the original argument, plus one for
|
|
|
- either a terminating null or a separating space. */
|
|
|
- int size = (int)strlen(in) + 1;
|
|
|
+ std::ostringstream out;
|
|
|
|
|
|
/* String iterator. */
|
|
|
const char* c;
|
|
|
@@ -599,116 +577,17 @@ int cmOutputConverter::Shell__GetArgumentSize(const char* in, int isUnix,
|
|
|
/* Keep track of how many backslashes have been encountered in a row. */
|
|
|
int windows_backslashes = 0;
|
|
|
|
|
|
- /* Scan the string for characters that require escaping or quoting. */
|
|
|
- for (c = in; *c; ++c) {
|
|
|
- /* Look for $(MAKEVAR) syntax if requested. */
|
|
|
- if (flags & Shell_Flag_AllowMakeVariables) {
|
|
|
- /* Skip over the make variable references if any are present. */
|
|
|
- c = Shell__SkipMakeVariables(c);
|
|
|
-
|
|
|
- /* Stop if we have reached the end of the string. */
|
|
|
- if (!*c) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Check whether this character needs escaping for the shell. */
|
|
|
- if (isUnix) {
|
|
|
- /* On Unix a few special characters need escaping even inside a
|
|
|
- quoted argument. */
|
|
|
- if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
|
|
|
- /* This character needs a backslash to escape it. */
|
|
|
- ++size;
|
|
|
- }
|
|
|
- } else if (flags & Shell_Flag_EchoWindows) {
|
|
|
- /* On Windows the built-in command shell echo never needs escaping. */
|
|
|
- } else {
|
|
|
- /* On Windows only backslashes and double-quotes need escaping. */
|
|
|
- if (*c == '\\') {
|
|
|
- /* Found a backslash. It may need to be escaped later. */
|
|
|
- ++windows_backslashes;
|
|
|
- } else if (*c == '"') {
|
|
|
- /* Found a double-quote. We need to escape it and all
|
|
|
- immediately preceding backslashes. */
|
|
|
- size += windows_backslashes + 1;
|
|
|
- windows_backslashes = 0;
|
|
|
- } else {
|
|
|
- /* Found another character. This eliminates the possibility
|
|
|
- that any immediately preceding backslashes will be
|
|
|
- escaped. */
|
|
|
- windows_backslashes = 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Check whether this character needs escaping for a make tool. */
|
|
|
- if (*c == '$') {
|
|
|
- if (flags & Shell_Flag_Make) {
|
|
|
- /* In Makefiles a dollar is written $$ so we need one extra
|
|
|
- character. */
|
|
|
- ++size;
|
|
|
- } else if (flags & Shell_Flag_VSIDE) {
|
|
|
- /* In a VS IDE a dollar is written "$" so we need two extra
|
|
|
- characters. */
|
|
|
- size += 2;
|
|
|
- }
|
|
|
- } else if (*c == '#') {
|
|
|
- if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
|
|
|
- /* In Watcom WMake makefiles a pound is written $# so we need
|
|
|
- one extra character. */
|
|
|
- ++size;
|
|
|
- }
|
|
|
- } else if (*c == '%') {
|
|
|
- if ((flags & Shell_Flag_VSIDE) ||
|
|
|
- ((flags & Shell_Flag_Make) &&
|
|
|
- ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
|
|
|
- /* In the VS IDE, NMake, or MinGW make a percent is written %%
|
|
|
- so we need one extra characters. */
|
|
|
- size += 1;
|
|
|
- }
|
|
|
- } else if (*c == ';') {
|
|
|
- if (flags & Shell_Flag_VSIDE) {
|
|
|
- /* In a VS IDE a semicolon is written ";" so we need two extra
|
|
|
- characters. */
|
|
|
- size += 2;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Check whether the argument needs surrounding quotes. */
|
|
|
- if (Shell__ArgumentNeedsQuotes(in, isUnix, flags)) {
|
|
|
- /* Surrounding quotes are needed. Allocate space for them. */
|
|
|
- if ((flags & Shell_Flag_WatcomQuote) && (isUnix)) {
|
|
|
- size += 2;
|
|
|
- }
|
|
|
- size += 2;
|
|
|
-
|
|
|
- /* We must escape all ending backslashes when quoting on windows. */
|
|
|
- size += windows_backslashes;
|
|
|
- }
|
|
|
-
|
|
|
- return size;
|
|
|
-}
|
|
|
-
|
|
|
-char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
- int isUnix, int flags)
|
|
|
-{
|
|
|
- /* String iterator. */
|
|
|
- const char* c;
|
|
|
-
|
|
|
- /* Keep track of how many backslashes have been encountered in a row. */
|
|
|
- int windows_backslashes = 0;
|
|
|
-
|
|
|
/* Whether the argument must be quoted. */
|
|
|
int needQuotes = Shell__ArgumentNeedsQuotes(in, isUnix, flags);
|
|
|
if (needQuotes) {
|
|
|
/* Add the opening quote for this argument. */
|
|
|
if (flags & Shell_Flag_WatcomQuote) {
|
|
|
if (isUnix) {
|
|
|
- *out++ = '"';
|
|
|
+ out << '"';
|
|
|
}
|
|
|
- *out++ = '\'';
|
|
|
+ out << '\'';
|
|
|
} else {
|
|
|
- *out++ = '"';
|
|
|
+ out << '"';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -720,7 +599,7 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
if (skip != c) {
|
|
|
/* Copy to the end of the make variable references. */
|
|
|
while (c != skip) {
|
|
|
- *out++ = *c++;
|
|
|
+ out << *c++;
|
|
|
}
|
|
|
|
|
|
/* The make variable reference eliminates any escaping needed
|
|
|
@@ -740,7 +619,7 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
quoted argument. */
|
|
|
if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
|
|
|
/* This character needs a backslash to escape it. */
|
|
|
- *out++ = '\\';
|
|
|
+ out << '\\';
|
|
|
}
|
|
|
} else if (flags & Shell_Flag_EchoWindows) {
|
|
|
/* On Windows the built-in command shell echo never needs escaping. */
|
|
|
@@ -754,11 +633,11 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
backslashes. */
|
|
|
while (windows_backslashes > 0) {
|
|
|
--windows_backslashes;
|
|
|
- *out++ = '\\';
|
|
|
+ out << '\\';
|
|
|
}
|
|
|
|
|
|
/* Add the backslash to escape the double-quote. */
|
|
|
- *out++ = '\\';
|
|
|
+ out << '\\';
|
|
|
} else {
|
|
|
/* We encountered a normal character. This eliminates any
|
|
|
escaping needed for preceding backslashes. */
|
|
|
@@ -771,8 +650,7 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
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. */
|
|
|
- *out++ = '$';
|
|
|
- *out++ = '$';
|
|
|
+ out << "$$";
|
|
|
} else if (flags & Shell_Flag_VSIDE) {
|
|
|
/* In a VS IDE a dollar is written "$". If this is written in
|
|
|
an un-quoted argument it starts a quoted segment, inserts
|
|
|
@@ -780,34 +658,30 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
argument it ends quoting, inserts the $ and restarts
|
|
|
quoting. Either way the $ is isolated from surrounding
|
|
|
text to avoid looking like a variable reference. */
|
|
|
- *out++ = '"';
|
|
|
- *out++ = '$';
|
|
|
- *out++ = '"';
|
|
|
+ out << "\"$\"";
|
|
|
} else {
|
|
|
/* Otherwise a dollar is written just $. */
|
|
|
- *out++ = '$';
|
|
|
+ out << '$';
|
|
|
}
|
|
|
} else if (*c == '#') {
|
|
|
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
|
|
|
shell. */
|
|
|
- *out++ = '$';
|
|
|
- *out++ = '#';
|
|
|
+ out << "$#";
|
|
|
} else {
|
|
|
/* Otherwise a pound is written just #. */
|
|
|
- *out++ = '#';
|
|
|
+ out << '#';
|
|
|
}
|
|
|
} else if (*c == '%') {
|
|
|
if ((flags & Shell_Flag_VSIDE) ||
|
|
|
((flags & Shell_Flag_Make) &&
|
|
|
((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
|
|
|
/* In the VS IDE, NMake, or MinGW make a percent is written %%. */
|
|
|
- *out++ = '%';
|
|
|
- *out++ = '%';
|
|
|
+ out << "%%";
|
|
|
} else {
|
|
|
/* Otherwise a percent is written just %. */
|
|
|
- *out++ = '%';
|
|
|
+ out << '%';
|
|
|
}
|
|
|
} else if (*c == ';') {
|
|
|
if (flags & Shell_Flag_VSIDE) {
|
|
|
@@ -816,16 +690,14 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
inserts the ; and ends the segment. If it is written in a
|
|
|
quoted argument it ends quoting, inserts the ; and restarts
|
|
|
quoting. Either way the ; is isolated. */
|
|
|
- *out++ = '"';
|
|
|
- *out++ = ';';
|
|
|
- *out++ = '"';
|
|
|
+ out << "\";\"";
|
|
|
} else {
|
|
|
/* Otherwise a semicolon is written just ;. */
|
|
|
- *out++ = ';';
|
|
|
+ out << ';';
|
|
|
}
|
|
|
} else {
|
|
|
/* Store this character. */
|
|
|
- *out++ = *c;
|
|
|
+ out << *c;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -833,45 +705,31 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
|
|
|
/* Add enough backslashes to escape any trailing ones. */
|
|
|
while (windows_backslashes > 0) {
|
|
|
--windows_backslashes;
|
|
|
- *out++ = '\\';
|
|
|
+ out << '\\';
|
|
|
}
|
|
|
|
|
|
/* Add the closing quote for this argument. */
|
|
|
if (flags & Shell_Flag_WatcomQuote) {
|
|
|
- *out++ = '\'';
|
|
|
+ out << '\'';
|
|
|
if (isUnix) {
|
|
|
- *out++ = '"';
|
|
|
+ out << '"';
|
|
|
}
|
|
|
} else {
|
|
|
- *out++ = '"';
|
|
|
+ out << '"';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* Store a terminating null without incrementing. */
|
|
|
- *out = 0;
|
|
|
-
|
|
|
- return out;
|
|
|
-}
|
|
|
-
|
|
|
-char* cmOutputConverter::Shell_GetArgumentForWindows(const char* in, char* out,
|
|
|
- int flags)
|
|
|
-{
|
|
|
- return Shell__GetArgument(in, out, 0, flags);
|
|
|
-}
|
|
|
-
|
|
|
-char* cmOutputConverter::Shell_GetArgumentForUnix(const char* in, char* out,
|
|
|
- int flags)
|
|
|
-{
|
|
|
- return Shell__GetArgument(in, out, 1, flags);
|
|
|
+ return out.str();
|
|
|
}
|
|
|
|
|
|
-int cmOutputConverter::Shell_GetArgumentSizeForWindows(const char* in,
|
|
|
- int flags)
|
|
|
+std::string cmOutputConverter::Shell_GetArgumentForWindows(const char* in,
|
|
|
+ int flags)
|
|
|
{
|
|
|
- return Shell__GetArgumentSize(in, 0, flags);
|
|
|
+ return Shell__GetArgument(in, 0, flags);
|
|
|
}
|
|
|
|
|
|
-int cmOutputConverter::Shell_GetArgumentSizeForUnix(const char* in, int flags)
|
|
|
+std::string cmOutputConverter::Shell_GetArgumentForUnix(const char* in,
|
|
|
+ int flags)
|
|
|
{
|
|
|
- return Shell__GetArgumentSize(in, 1, flags);
|
|
|
+ return Shell__GetArgument(in, 1, flags);
|
|
|
}
|