1 // Copyright 2011 Google Inc. All Rights Reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
20 #elif defined( _WIN32)
34 #include <sys/types.h>
43 #if defined(__APPLE__) || defined(__FreeBSD__)
44 #include <sys/sysctl.h>
45 #elif defined(__SVR4) && defined(__sun)
47 #include <sys/loadavg.h>
49 #include <libperfstat.h>
50 #elif defined(linux) || defined(__GLIBC__)
51 #include <sys/sysinfo.h>
54 #include "edit_distance.h"
57 void Fatal(const char* msg, ...) {
59 fprintf(stderr, "ninja: fatal: ");
61 vfprintf(stderr, msg, ap);
63 fprintf(stderr, "\n");
65 // On Windows, some tools may inject extra threads.
66 // exit() may block on locks held by those threads, so forcibly exit.
75 void Warning(const char* msg, ...) {
77 fprintf(stderr, "ninja: warning: ");
79 vfprintf(stderr, msg, ap);
81 fprintf(stderr, "\n");
84 void Error(const char* msg, ...) {
86 fprintf(stderr, "ninja: error: ");
88 vfprintf(stderr, msg, ap);
90 fprintf(stderr, "\n");
93 bool CanonicalizePath(string* path, uint64_t* slash_bits, string* err) {
94 METRIC_RECORD("canonicalize str");
95 size_t len = path->size();
99 if (!CanonicalizePath(str, &len, slash_bits, err))
105 static bool IsPathSeparator(char c) {
107 return c == '/' || c == '\\';
113 bool CanonicalizePath(char* path, size_t* len, uint64_t* slash_bits,
115 // WARNING: this function is performance-critical; please benchmark
116 // any changes you make to it.
117 METRIC_RECORD("canonicalize path");
123 const int kMaxPathComponents = 60;
124 char* components[kMaxPathComponents];
125 int component_count = 0;
129 const char* src = start;
130 const char* end = start + *len;
132 if (IsPathSeparator(*src)) {
135 // network path starts with //
136 if (*len > 1 && IsPathSeparator(*(src + 1))) {
151 if (src + 1 == end || IsPathSeparator(src[1])) {
152 // '.' component; eliminate.
155 } else if (src[1] == '.' && (src + 2 == end || IsPathSeparator(src[2]))) {
156 // '..' component. Back up if possible.
157 if (component_count > 0) {
158 dst = components[component_count - 1];
170 if (IsPathSeparator(*src)) {
175 if (component_count == kMaxPathComponents)
176 Fatal("path has too many components : %s", path);
177 components[component_count] = dst;
180 while (src != end && !IsPathSeparator(*src))
182 *dst++ = *src++; // Copy '/' or final \0 character as well.
190 *len = dst - start - 1;
193 uint64_t bits_mask = 1;
195 for (char* c = start; c < start + *len; ++c) {
200 // Intentional fallthrough.
213 static inline bool IsKnownShellSafeCharacter(char ch) {
214 if ('A' <= ch && ch <= 'Z') return true;
215 if ('a' <= ch && ch <= 'z') return true;
216 if ('0' <= ch && ch <= '9') return true;
230 static inline bool IsKnownWin32SafeCharacter(char ch) {
240 static inline bool StringNeedsShellEscaping(const string& input) {
241 for (size_t i = 0; i < input.size(); ++i) {
242 if (!IsKnownShellSafeCharacter(input[i])) return true;
247 static inline bool StringNeedsWin32Escaping(const string& input) {
248 for (size_t i = 0; i < input.size(); ++i) {
249 if (!IsKnownWin32SafeCharacter(input[i])) return true;
254 void GetShellEscapedString(const string& input, string* result) {
257 if (!StringNeedsShellEscaping(input)) {
258 result->append(input);
262 const char kQuote = '\'';
263 const char kEscapeSequence[] = "'\\'";
265 result->push_back(kQuote);
267 string::const_iterator span_begin = input.begin();
268 for (string::const_iterator it = input.begin(), end = input.end(); it != end;
271 result->append(span_begin, it);
272 result->append(kEscapeSequence);
276 result->append(span_begin, input.end());
277 result->push_back(kQuote);
281 void GetWin32EscapedString(const string& input, string* result) {
283 if (!StringNeedsWin32Escaping(input)) {
284 result->append(input);
288 const char kQuote = '"';
289 const char kBackslash = '\\';
291 result->push_back(kQuote);
292 size_t consecutive_backslash_count = 0;
293 string::const_iterator span_begin = input.begin();
294 for (string::const_iterator it = input.begin(), end = input.end(); it != end;
298 ++consecutive_backslash_count;
301 result->append(span_begin, it);
302 result->append(consecutive_backslash_count + 1, kBackslash);
304 consecutive_backslash_count = 0;
307 consecutive_backslash_count = 0;
311 result->append(span_begin, input.end());
312 result->append(consecutive_backslash_count, kBackslash);
313 result->push_back(kQuote);
316 int ReadFile(const string& path, string* contents, string* err) {
318 // This makes a ninja run on a set of 1500 manifest files about 4% faster
319 // than using the generic fopen code below.
321 HANDLE f = ::CreateFile(path.c_str(),
326 FILE_FLAG_SEQUENTIAL_SCAN,
328 if (f == INVALID_HANDLE_VALUE) {
329 err->assign(GetLastErrorString());
336 if (!::ReadFile(f, buf, sizeof(buf), &len, NULL)) {
337 err->assign(GetLastErrorString());
343 contents->append(buf, len);
348 FILE* f = fopen(path.c_str(), "rb");
350 err->assign(strerror(errno));
356 while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
357 contents->append(buf, len);
360 err->assign(strerror(errno)); // XXX errno?
370 void SetCloseOnExec(int fd) {
372 int flags = fcntl(fd, F_GETFD);
374 perror("fcntl(F_GETFD)");
376 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
377 perror("fcntl(F_SETFD)");
380 HANDLE hd = (HANDLE) _get_osfhandle(fd);
381 if (! SetHandleInformation(hd, HANDLE_FLAG_INHERIT, 0)) {
382 fprintf(stderr, "SetHandleInformation(): %s", GetLastErrorString().c_str());
388 const char* SpellcheckStringV(const string& text,
389 const vector<const char*>& words) {
390 const bool kAllowReplacements = true;
391 const int kMaxValidEditDistance = 3;
393 int min_distance = kMaxValidEditDistance + 1;
394 const char* result = NULL;
395 for (vector<const char*>::const_iterator i = words.begin();
396 i != words.end(); ++i) {
397 int distance = EditDistance(*i, text, kAllowReplacements,
398 kMaxValidEditDistance);
399 if (distance < min_distance) {
400 min_distance = distance;
407 const char* SpellcheckString(const char* text, ...) {
408 // Note: This takes a const char* instead of a string& because using
409 // va_start() with a reference parameter is undefined behavior.
412 vector<const char*> words;
414 while ((word = va_arg(ap, const char*)))
415 words.push_back(word);
417 return SpellcheckStringV(text, words);
421 string GetLastErrorString() {
422 DWORD err = GetLastError();
426 FORMAT_MESSAGE_ALLOCATE_BUFFER |
427 FORMAT_MESSAGE_FROM_SYSTEM |
428 FORMAT_MESSAGE_IGNORE_INSERTS,
431 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
435 string msg = msg_buf;
440 void Win32Fatal(const char* function) {
441 Fatal("%s: %s", function, GetLastErrorString().c_str());
445 bool islatinalpha(int c) {
446 // isalpha() is locale-dependent.
447 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
450 string StripAnsiEscapeCodes(const string& in) {
452 stripped.reserve(in.size());
454 for (size_t i = 0; i < in.size(); ++i) {
455 if (in[i] != '\33') {
456 // Not an escape code.
457 stripped.push_back(in[i]);
461 // Only strip CSIs for now.
462 if (i + 1 >= in.size()) break;
463 if (in[i + 1] != '[') continue; // Not a CSI.
466 // Skip everything up to and including the next [a-zA-Z].
467 while (i < in.size() && !islatinalpha(in[i]))
473 int GetProcessorCount() {
476 GetNativeSystemInfo(&info);
477 return info.dwNumberOfProcessors;
479 return sysconf(_SC_NPROCESSORS_ONLN);
483 #if defined(_WIN32) || defined(__CYGWIN__)
484 static double CalculateProcessorLoad(uint64_t idle_ticks, uint64_t total_ticks)
486 static uint64_t previous_idle_ticks = 0;
487 static uint64_t previous_total_ticks = 0;
488 static double previous_load = -0.0;
490 uint64_t idle_ticks_since_last_time = idle_ticks - previous_idle_ticks;
491 uint64_t total_ticks_since_last_time = total_ticks - previous_total_ticks;
493 bool first_call = (previous_total_ticks == 0);
494 bool ticks_not_updated_since_last_call = (total_ticks_since_last_time == 0);
497 if (first_call || ticks_not_updated_since_last_call) {
498 load = previous_load;
501 double idle_to_total_ratio =
502 ((double)idle_ticks_since_last_time) / total_ticks_since_last_time;
503 double load_since_last_call = 1.0 - idle_to_total_ratio;
505 // Filter/smooth result when possible.
506 if(previous_load > 0) {
507 load = 0.9 * previous_load + 0.1 * load_since_last_call;
509 load = load_since_last_call;
513 previous_load = load;
514 previous_total_ticks = total_ticks;
515 previous_idle_ticks = idle_ticks;
520 static uint64_t FileTimeToTickCount(const FILETIME & ft)
522 uint64_t high = (((uint64_t)(ft.dwHighDateTime)) << 32);
523 uint64_t low = ft.dwLowDateTime;
527 double GetLoadAverage() {
528 FILETIME idle_time, kernel_time, user_time;
529 BOOL get_system_time_succeeded =
530 GetSystemTimes(&idle_time, &kernel_time, &user_time);
532 double posix_compatible_load;
533 if (get_system_time_succeeded) {
534 uint64_t idle_ticks = FileTimeToTickCount(idle_time);
536 // kernel_time from GetSystemTimes already includes idle_time.
537 uint64_t total_ticks =
538 FileTimeToTickCount(kernel_time) + FileTimeToTickCount(user_time);
540 double processor_load = CalculateProcessorLoad(idle_ticks, total_ticks);
541 posix_compatible_load = processor_load * GetProcessorCount();
544 posix_compatible_load = -0.0;
547 return posix_compatible_load;
550 double GetLoadAverage() {
551 perfstat_cpu_total_t cpu_stats;
552 if (perfstat_cpu_total(NULL, &cpu_stats, sizeof(cpu_stats), 1) < 0) {
556 // Calculation taken from comment in libperfstats.h
557 return double(cpu_stats.loadavg[0]) / double(1 << SBITS);
559 #elif defined(__UCLIBC__)
560 double GetLoadAverage() {
562 if (sysinfo(&si) != 0)
564 return 1.0 / (1 << SI_LOAD_SHIFT) * si.loads[0];
567 double GetLoadAverage() {
568 double loadavg[3] = { 0.0f, 0.0f, 0.0f };
569 if (getloadavg(loadavg, 3) < 0) {
570 // Maybe we should return an error here or the availability of
571 // getloadavg(3) should be checked when ninja is configured.
578 string ElideMiddle(const string& str, size_t width) {
579 const int kMargin = 3; // Space for "...".
581 if (result.size() + kMargin > width) {
582 size_t elide_size = (width - kMargin) / 2;
583 result = result.substr(0, elide_size)
585 + result.substr(result.size() - elide_size, elide_size);
590 bool Truncate(const string& path, size_t size, string* err) {
592 int fh = _sopen(path.c_str(), _O_RDWR | _O_CREAT, _SH_DENYNO,
593 _S_IREAD | _S_IWRITE);
594 int success = _chsize(fh, size);
597 int success = truncate(path.c_str(), size);
599 // Both truncate() and _chsize() return 0 on success and set errno and return
602 *err = strerror(errno);