diff options
Diffstat (limited to 'ninja/src/util.cc')
-rw-r--r-- | ninja/src/util.cc | 127 |
1 files changed, 105 insertions, 22 deletions
diff --git a/ninja/src/util.cc b/ninja/src/util.cc index b9c2c0d59b9..24d231f9fd4 100644 --- a/ninja/src/util.cc +++ b/ninja/src/util.cc @@ -20,6 +20,7 @@ #include <share.h> #endif +#include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdarg.h> @@ -175,6 +176,108 @@ bool CanonicalizePath(char* path, size_t* len, string* err) { return true; } +static inline bool IsKnownShellSafeCharacter(char ch) { + if ('A' <= ch && ch <= 'Z') return true; + if ('a' <= ch && ch <= 'z') return true; + if ('0' <= ch && ch <= '9') return true; + + switch (ch) { + case '_': + case '-': + case '.': + case '/': + return true; + default: + return false; + } +} + +static inline bool IsKnownWin32SafeCharacter(char ch) { + switch (ch) { + case ' ': + case '"': + return false; + default: + return true; + } +} + +static inline bool StringNeedsShellEscaping(const string& input) { + for (size_t i = 0; i < input.size(); ++i) { + if (!IsKnownShellSafeCharacter(input[i])) return true; + } + return false; +} + +static inline bool StringNeedsWin32Escaping(const string& input) { + for (size_t i = 0; i < input.size(); ++i) { + if (!IsKnownWin32SafeCharacter(input[i])) return true; + } + return false; +} + +void GetShellEscapedString(const string& input, string* result) { + assert(result); + + if (!StringNeedsShellEscaping(input)) { + result->append(input); + return; + } + + const char kQuote = '\''; + const char kEscapeSequence[] = "'\\'"; + + result->push_back(kQuote); + + string::const_iterator span_begin = input.begin(); + for (string::const_iterator it = input.begin(), end = input.end(); it != end; + ++it) { + if (*it == kQuote) { + result->append(span_begin, it); + result->append(kEscapeSequence); + span_begin = it; + } + } + result->append(span_begin, input.end()); + result->push_back(kQuote); +} + + +void GetWin32EscapedString(const string& input, string* result) { + assert(result); + if (!StringNeedsWin32Escaping(input)) { + result->append(input); + return; + } + + const char kQuote = '"'; + const char kBackslash = '\\'; + + result->push_back(kQuote); + size_t consecutive_backslash_count = 0; + string::const_iterator span_begin = input.begin(); + for (string::const_iterator it = input.begin(), end = input.end(); it != end; + ++it) { + switch (*it) { + case kBackslash: + ++consecutive_backslash_count; + break; + case kQuote: + result->append(span_begin, it); + result->append(consecutive_backslash_count + 1, kBackslash); + span_begin = it; + consecutive_backslash_count = 0; + break; + default: + consecutive_backslash_count = 0; + break; + } + } + result->append(span_begin, input.end()); + result->append(consecutive_backslash_count, kBackslash); + result->push_back(kQuote); +} + int ReadFile(const string& path, string* contents, string* err) { FILE* f = fopen(path.c_str(), "r"); if (!f) { @@ -300,35 +403,15 @@ string StripAnsiEscapeCodes(const string& in) { return stripped; } -#if defined(linux) || defined(__GLIBC__) -int GetProcessorCount() { - return get_nprocs(); -} -#elif defined(__APPLE__) || defined(__FreeBSD__) -int GetProcessorCount() { - int processors; - size_t processors_size = sizeof(processors); - int name[] = {CTL_HW, HW_NCPU}; - if (sysctl(name, sizeof(name) / sizeof(int), - &processors, &processors_size, - NULL, 0) < 0) { - return 0; - } - return processors; -} -#elif defined(_WIN32) int GetProcessorCount() { +#ifdef _WIN32 SYSTEM_INFO info; GetSystemInfo(&info); return info.dwNumberOfProcessors; -} #else -// This is what get_nprocs() should be doing in the Linux implementation -// above, but in a more standard way. -int GetProcessorCount() { return sysconf(_SC_NPROCESSORS_ONLN); -} #endif +} #if defined(_WIN32) || defined(__CYGWIN__) double GetLoadAverage() { |