123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635 |
- #include "cmOutputConverter.h"
- #include <algorithm>
- #include <assert.h>
- #include <ctype.h>
- #include <set>
- #include <sstream>
- #include <vector>
- #include "cmAlgorithms.h"
- #include "cmState.h"
- #include "cmStateDirectory.h"
- #include "cmSystemTools.h"
- cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot)
- : StateSnapshot(snapshot)
- , LinkScriptShell(false)
- {
- assert(this->StateSnapshot.IsValid());
- }
- std::string cmOutputConverter::ConvertToOutputForExisting(
- const std::string& remote, OutputFormat format) const
- {
-
-
-
- if (this->GetState()->UseWindowsShell() &&
- remote.find(' ') != std::string::npos &&
- cmSystemTools::FileExists(remote)) {
- std::string tmp;
- if (cmSystemTools::GetShortPath(remote, tmp)) {
- return this->ConvertToOutputFormat(tmp, format);
- }
- }
-
- return this->ConvertToOutputFormat(remote, format);
- }
- std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
- OutputFormat output) const
- {
- std::string result = source;
-
- if (output == SHELL || output == WATCOMQUOTE) {
- result = this->ConvertDirectorySeparatorsForShell(source);
- result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
- } else if (output == RESPONSE) {
- result = this->EscapeForShell(result, false, false, false);
- }
- return result;
- }
- std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
- const std::string& source) const
- {
- std::string result = source;
-
-
-
- if (this->GetState()->UseMSYSShell() && !this->LinkScriptShell) {
- if (result.size() > 2 && result[1] == ':') {
- result[1] = result[0];
- result[0] = '/';
- }
- }
- if (this->GetState()->UseWindowsShell()) {
- std::replace(result.begin(), result.end(), '/', '\\');
- }
- return result;
- }
- static bool cmOutputConverterNotAbove(const char* a, const char* b)
- {
- return (cmSystemTools::ComparePath(a, b) ||
- cmSystemTools::IsSubDirectory(a, b));
- }
- bool cmOutputConverter::ContainedInDirectory(std::string const& local_path,
- std::string const& remote_path,
- cmStateDirectory const& directory)
- {
- const std::string relativePathTopBinary =
- directory.GetRelativePathTopBinary();
- const std::string relativePathTopSource =
- directory.GetRelativePathTopSource();
- const bool bothInBinary =
- cmOutputConverterNotAbove(local_path.c_str(),
- relativePathTopBinary.c_str()) &&
- cmOutputConverterNotAbove(remote_path.c_str(),
- relativePathTopBinary.c_str());
- const bool bothInSource =
- cmOutputConverterNotAbove(local_path.c_str(),
- relativePathTopSource.c_str()) &&
- cmOutputConverterNotAbove(remote_path.c_str(),
- relativePathTopSource.c_str());
- return bothInSource || bothInBinary;
- }
- std::string cmOutputConverter::ConvertToRelativePath(
- std::string const& local_path, std::string const& remote_path) const
- {
- if (!ContainedInDirectory(local_path, remote_path,
- this->StateSnapshot.GetDirectory())) {
- return remote_path;
- }
- return this->ForceToRelativePath(local_path, remote_path);
- }
- std::string cmOutputConverter::ForceToRelativePath(
- std::string const& local_path, std::string const& remote_path)
- {
-
- assert(local_path[0] != '\"');
- assert(remote_path[0] != '\"');
-
- assert(local_path.empty() || local_path[local_path.size() - 1] != '/');
-
- if (!cmSystemTools::FileIsFullPath(remote_path)) {
- return remote_path;
- }
-
-
- std::vector<std::string> local;
- cmSystemTools::SplitPath(local_path, local);
- std::vector<std::string> remote;
- cmSystemTools::SplitPath(remote_path, remote);
- unsigned int common = 0;
- while (common < remote.size() && common < local.size() &&
- cmSystemTools::ComparePath(remote[common], local[common])) {
- ++common;
- }
-
- if (common == 0) {
- return remote_path;
- }
-
- if (common == remote.size() && common == local.size()) {
- return ".";
- }
-
-
- if (common + 1 == remote.size() && remote[common].empty() &&
- common == local.size()) {
- return "./";
- }
-
- std::string relative;
-
-
-
-
- for (unsigned int i = common; i < local.size(); ++i) {
- relative += "..";
- if (i < local.size() - 1) {
- relative += "/";
- }
- }
-
-
-
-
-
-
- if (!relative.empty() && !remote.empty()) {
- relative += "/";
- }
- relative += cmJoin(cmMakeRange(remote).advance(common), "/");
-
- return relative;
- }
- static bool cmOutputConverterIsShellOperator(const std::string& str)
- {
- static std::set<std::string> shellOperators;
- if (shellOperators.empty()) {
- shellOperators.insert("<");
- shellOperators.insert(">");
- shellOperators.insert("<<");
- shellOperators.insert(">>");
- shellOperators.insert("|");
- shellOperators.insert("||");
- shellOperators.insert("&&");
- shellOperators.insert("&>");
- shellOperators.insert("1>");
- shellOperators.insert("2>");
- shellOperators.insert("2>&1");
- shellOperators.insert("1>&2");
- }
- return shellOperators.count(str) > 0;
- }
- std::string cmOutputConverter::EscapeForShell(const std::string& str,
- bool makeVars, bool forEcho,
- bool useWatcomQuote) const
- {
-
- if (cmOutputConverterIsShellOperator(str)) {
- return str;
- }
-
- int flags = 0;
- if (this->GetState()->UseWindowsVSIDE()) {
- flags |= Shell_Flag_VSIDE;
- } else if (!this->LinkScriptShell) {
- flags |= Shell_Flag_Make;
- }
- if (makeVars) {
- flags |= Shell_Flag_AllowMakeVariables;
- }
- if (forEcho) {
- flags |= Shell_Flag_EchoWindows;
- }
- if (useWatcomQuote) {
- flags |= Shell_Flag_WatcomQuote;
- }
- if (this->GetState()->UseWatcomWMake()) {
- flags |= Shell_Flag_WatcomWMake;
- }
- if (this->GetState()->UseMinGWMake()) {
- flags |= Shell_Flag_MinGWMake;
- }
- if (this->GetState()->UseNMake()) {
- flags |= Shell_Flag_NMake;
- }
- if (!this->GetState()->UseWindowsShell()) {
- flags |= Shell_Flag_IsUnix;
- }
- return Shell__GetArgument(str.c_str(), flags);
- }
- std::string cmOutputConverter::EscapeForCMake(const std::string& str)
- {
-
- std::string result = "\"";
- for (const char* c = str.c_str(); *c; ++c) {
- if (*c == '"') {
-
- result += "\\\"";
- } else if (*c == '$') {
-
- result += "\\$";
- } else if (*c == '\\') {
-
- result += "\\\\";
- } else {
-
- result += *c;
- }
- }
- result += "\"";
- return result;
- }
- std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
- int shell_flags)
- {
- return Shell__GetArgument(arg, shell_flags);
- }
- cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
- const char* value)
- {
- FortranFormat format = FortranFormatNone;
- if (value && *value) {
- std::vector<std::string> fmt;
- cmSystemTools::ExpandListArgument(value, fmt);
- for (std::string const& fi : fmt) {
- if (fi == "FIXED") {
- format = FortranFormatFixed;
- }
- if (fi == "FREE") {
- format = FortranFormatFree;
- }
- }
- }
- return format;
- }
- void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
- {
- this->LinkScriptShell = linkScriptShell;
- }
- cmState* cmOutputConverter::GetState() const
- {
- return this->StateSnapshot.GetState();
- }
- int cmOutputConverter::Shell__CharIsWhitespace(char c)
- {
- return ((c == ' ') || (c == '\t'));
- }
- int cmOutputConverter::Shell__CharNeedsQuotesOnUnix(char c)
- {
- return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
- (c == '&') || (c == '$') || (c == '(') || (c == ')') || (c == '~') ||
- (c == '<') || (c == '>') || (c == '|') || (c == '*') || (c == '^') ||
- (c == '\\'));
- }
- int cmOutputConverter::Shell__CharNeedsQuotesOnWindows(char c)
- {
- return ((c == '\'') || (c == '#') || (c == '&') || (c == '<') ||
- (c == '>') || (c == '|') || (c == '^'));
- }
- int cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
- {
-
- if (!(flags & Shell_Flag_IsUnix) && (flags & Shell_Flag_EchoWindows)) {
- return 0;
- }
-
- if (Shell__CharIsWhitespace(c)) {
- return 1;
- }
- if (flags & Shell_Flag_IsUnix) {
-
- if (Shell__CharNeedsQuotesOnUnix(c)) {
- return 1;
- }
- } else {
-
- if (Shell__CharNeedsQuotesOnWindows(c)) {
- return 1;
- }
- }
- return 0;
- }
- int cmOutputConverter::Shell__CharIsMakeVariableName(char c)
- {
- return c && (c == '_' || isalpha((static_cast<int>(c))));
- }
- const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
- {
- while (*c == '$' && *(c + 1) == '(') {
- const char* skip = c + 2;
- while (Shell__CharIsMakeVariableName(*skip)) {
- ++skip;
- }
- if (*skip == ')') {
- c = skip + 1;
- } else {
- break;
- }
- }
- return c;
- }
- #define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
- int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int flags)
- {
-
- if (!*in) {
- return 1;
- }
-
- {
- const char* c;
- for (c = in; *c; ++c) {
-
- if (flags & Shell_Flag_AllowMakeVariables) {
- #if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
- const char* skip = Shell__SkipMakeVariables(c);
- if (skip != c) {
-
- return 1;
- }
- #else
-
- c = Shell__SkipMakeVariables(c);
-
- if (!*c) {
- break;
- }
- #endif
- }
-
- if (Shell__CharNeedsQuotes(*c, flags)) {
- return 1;
- }
- }
- }
-
- if (flags & Shell_Flag_IsUnix && *in && !*(in + 1)) {
- char c = *in;
- if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) {
- return 1;
- }
- }
- return 0;
- }
- std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
- {
- std::ostringstream out;
-
- const char* c;
-
- int windows_backslashes = 0;
-
- int needQuotes = Shell__ArgumentNeedsQuotes(in, flags);
- if (needQuotes) {
-
- if (flags & Shell_Flag_WatcomQuote) {
- if (flags & Shell_Flag_IsUnix) {
- out << '"';
- }
- out << '\'';
- } else {
- out << '"';
- }
- }
-
- for (c = in; *c; ++c) {
-
- if (flags & Shell_Flag_AllowMakeVariables) {
- const char* skip = Shell__SkipMakeVariables(c);
- if (skip != c) {
-
- while (c != skip) {
- out << *c++;
- }
-
- windows_backslashes = 0;
-
- if (!*c) {
- break;
- }
- }
- }
-
- if (flags & Shell_Flag_IsUnix) {
-
- if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
-
- out << '\\';
- }
- } else if (flags & Shell_Flag_EchoWindows) {
-
- } else {
-
- if (*c == '\\') {
-
- ++windows_backslashes;
- } else if (*c == '"') {
-
- while (windows_backslashes > 0) {
- --windows_backslashes;
- out << '\\';
- }
-
- out << '\\';
- } else {
-
- windows_backslashes = 0;
- }
- }
-
- if (*c == '$') {
- if (flags & Shell_Flag_Make) {
-
- out << "$$";
- } else if (flags & Shell_Flag_VSIDE) {
-
- out << "\"$\"";
- } else {
-
- out << '$';
- }
- } else if (*c == '#') {
- if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
-
- out << "$#";
- } else {
-
- out << '#';
- }
- } else if (*c == '%') {
- if ((flags & Shell_Flag_VSIDE) ||
- ((flags & Shell_Flag_Make) &&
- ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
-
- out << "%%";
- } else {
-
- out << '%';
- }
- } else if (*c == ';') {
- if (flags & Shell_Flag_VSIDE) {
-
- out << "\";\"";
- } else {
-
- out << ';';
- }
- } else {
-
- out << *c;
- }
- }
- if (needQuotes) {
-
- while (windows_backslashes > 0) {
- --windows_backslashes;
- out << '\\';
- }
-
- if (flags & Shell_Flag_WatcomQuote) {
- out << '\'';
- if (flags & Shell_Flag_IsUnix) {
- out << '"';
- }
- } else {
- out << '"';
- }
- }
- return out.str();
- }
|