diff options
Diffstat (limited to 'Source/cmOutputConverter.cxx')
-rw-r--r-- | Source/cmOutputConverter.cxx | 275 |
1 files changed, 62 insertions, 213 deletions
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index 8e80bd0..411184c 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -15,6 +15,7 @@ #include "cmake.h" #include <assert.h> +#include <sstream> #include <ctype.h> /* isalpha */ #include <string.h> /* strlen */ @@ -26,14 +27,14 @@ cmOutputConverter::cmOutputConverter(cmState::Snapshot snapshot) assert(this->StateSnapshot.IsValid()); } -std::string cmOutputConverter::ConvertToOutputForExistingCommon( - const std::string& remote, std::string const& result, - OutputFormat format) const +std::string cmOutputConverter::ConvertToOutputForExisting( + const std::string& remote, OutputFormat format) const { // If this is a windows shell, the result has a space, and the path // already exists, we can use a short-path to reference it without a // space. - if (this->GetState()->UseWindowsShell() && result.find(' ') != result.npos && + if (this->GetState()->UseWindowsShell() && + remote.find(' ') != std::string::npos && cmSystemTools::FileExists(remote.c_str())) { std::string tmp; if (cmSystemTools::GetShortPath(remote, tmp)) { @@ -41,31 +42,21 @@ std::string cmOutputConverter::ConvertToOutputForExistingCommon( } } - // Otherwise, leave it unchanged. - return result; -} - -std::string cmOutputConverter::ConvertToOutputForExisting( - const std::string& remote, RelativeRoot local, OutputFormat format) const -{ - static_cast<void>(local); - - // Perform standard conversion. - std::string result = this->ConvertToOutputFormat(remote, format); - - // Consider short-path. - return this->ConvertToOutputForExistingCommon(remote, result, format); + // Otherwise, perform standard conversion. + return this->ConvertToOutputFormat(remote, format); } std::string cmOutputConverter::ConvertToOutputForExisting( - RelativeRoot remote, const std::string& local, OutputFormat format) const + RelativeRoot remote, OutputFormat format) const { - // Perform standard conversion. - std::string result = this->Convert(remote, local, format, true); + // The relative root must have a path (i.e. not FULL or NONE) + assert(remote != FULL); + assert(remote != NONE); - // Consider short-path. const char* remotePath = this->GetRelativeRootPath(remote); - return this->ConvertToOutputForExistingCommon(remotePath, result, format); + assert(remotePath != CM_NULLPTR); + + return this->ConvertToOutputForExisting(remotePath, format); } const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const @@ -82,7 +73,7 @@ const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const default: break; } - return 0; + return CM_NULLPTR; } std::string cmOutputConverter::Convert(const std::string& source, @@ -157,22 +148,23 @@ std::string cmOutputConverter::ConvertDirectorySeparatorsForShell( std::string cmOutputConverter::Convert(RelativeRoot remote, const std::string& local, - OutputFormat output, - bool optional) const + OutputFormat output) const { - const char* remotePath = this->GetRelativeRootPath(remote); - // The relative root must have a path (i.e. not FULL or NONE) - assert(remotePath != 0); + assert(remote != FULL); + assert(remote != NONE); + + const char* remotePath = this->GetRelativeRootPath(remote); + assert(remotePath != CM_NULLPTR); - if (!local.empty() && !optional) { - std::vector<std::string> components; - cmSystemTools::SplitPath(local, components); - std::string result = this->ConvertToRelativePath(components, remotePath); - return this->ConvertToOutputFormat(result, output); + if (local.empty()) { + return this->ConvertToOutputFormat(remotePath, output); } - return this->ConvertToOutputFormat(remotePath, output); + std::vector<std::string> components; + cmSystemTools::SplitPath(local, components); + std::string result = this->ConvertToRelativePath(components, remotePath); + return this->ConvertToOutputFormat(result, output); } static bool cmOutputConverterNotAbove(const char* a, const char* b) @@ -328,19 +320,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 +351,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,112 +557,11 @@ 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; - - /* String iterator. */ - const char* c; - - /* 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; - } - } + std::ostringstream out; - /* 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; @@ -704,11 +574,11 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out, /* Add the opening quote for this argument. */ if (flags & Shell_Flag_WatcomQuote) { if (isUnix) { - *out++ = '"'; + out << '"'; } - *out++ = '\''; + out << '\''; } else { - *out++ = '"'; + out << '"'; } } @@ -720,7 +590,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 +610,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 +624,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 +641,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 +649,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 +681,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 +696,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); } |