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> 48 #elif defined(_AIX) && !defined(__PASE__) 49 #include <libperfstat.h> 50 #elif defined(linux) || defined(__GLIBC__) 51 #include <sys/sysinfo.h> 59 void Fatal(
const char* msg, ...) {
61 fprintf(stderr,
"ninja: fatal: ");
63 vfprintf(stderr, msg, ap);
65 fprintf(stderr,
"\n");
79 fprintf(stderr,
"ninja: warning: ");
81 vfprintf(stderr, msg, ap);
83 fprintf(stderr,
"\n");
86 void Error(
const char* msg, ...) {
88 fprintf(stderr,
"ninja: error: ");
90 vfprintf(stderr, msg, ap);
92 fprintf(stderr,
"\n");
97 size_t len = path->size();
109 return c ==
'/' || c ==
'\\';
125 const int kMaxPathComponents = 60;
126 char* components[kMaxPathComponents];
127 int component_count = 0;
131 const char* src = start;
132 const char* end = start + *len;
157 }
else if (src[1] ==
'.' && (src + 2 == end ||
IsPathSeparator(src[2]))) {
159 if (component_count > 0) {
160 dst = components[component_count - 1];
177 if (component_count == kMaxPathComponents)
178 Fatal(
"path has too many components : %s", path);
179 components[component_count] = dst;
192 *len = dst - start - 1;
197 for (
char* c = start; c < start + *len; ++c) {
216 if (
'A' <= ch && ch <=
'Z')
return true;
217 if (
'a' <= ch && ch <=
'z')
return true;
218 if (
'0' <= ch && ch <=
'9')
return true;
243 for (
size_t i = 0; i < input.size(); ++i) {
250 for (
size_t i = 0; i < input.size(); ++i) {
260 result->append(input);
264 const char kQuote =
'\'';
265 const char kEscapeSequence[] =
"'\\'";
267 result->push_back(kQuote);
269 string::const_iterator span_begin = input.begin();
270 for (string::const_iterator it = input.begin(), end = input.end(); it != end;
273 result->append(span_begin, it);
274 result->append(kEscapeSequence);
278 result->append(span_begin, input.end());
279 result->push_back(kQuote);
286 result->append(input);
290 const char kQuote =
'"';
291 const char kBackslash =
'\\';
293 result->push_back(kQuote);
294 size_t consecutive_backslash_count = 0;
295 string::const_iterator span_begin = input.begin();
296 for (string::const_iterator it = input.begin(), end = input.end(); it != end;
300 ++consecutive_backslash_count;
303 result->append(span_begin, it);
304 result->append(consecutive_backslash_count + 1, kBackslash);
306 consecutive_backslash_count = 0;
309 consecutive_backslash_count = 0;
313 result->append(span_begin, input.end());
314 result->append(consecutive_backslash_count, kBackslash);
315 result->push_back(kQuote);
318 int ReadFile(
const string& path,
string* contents,
string* err) {
323 HANDLE f = ::CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
324 OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
325 if (f == INVALID_HANDLE_VALUE) {
326 err->assign(GetLastErrorString());
333 if (!::
ReadFile(f, buf,
sizeof(buf), &len, NULL)) {
334 err->assign(GetLastErrorString());
340 contents->append(buf, len);
345 FILE* f = fopen(path.c_str(),
"rb");
347 err->assign(strerror(errno));
352 if (fstat(fileno(f), &st) < 0) {
353 err->assign(strerror(errno));
359 contents->reserve(st.st_size + 1);
363 while (!feof(f) && (len = fread(buf, 1,
sizeof(buf), f)) > 0) {
364 contents->append(buf, len);
367 err->assign(strerror(errno));
379 int flags = fcntl(fd, F_GETFD);
381 perror(
"fcntl(F_GETFD)");
383 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
384 perror(
"fcntl(F_SETFD)");
387 HANDLE hd = (HANDLE) _get_osfhandle(fd);
388 if (! SetHandleInformation(hd, HANDLE_FLAG_INHERIT, 0)) {
389 fprintf(stderr,
"SetHandleInformation(): %s", GetLastErrorString().c_str());
396 const vector<const char*>& words) {
397 const bool kAllowReplacements =
true;
398 const int kMaxValidEditDistance = 3;
400 int min_distance = kMaxValidEditDistance + 1;
401 const char* result = NULL;
402 for (vector<const char*>::const_iterator i = words.begin();
403 i != words.end(); ++i) {
404 int distance =
EditDistance(*i, text, kAllowReplacements,
405 kMaxValidEditDistance);
406 if (distance < min_distance) {
407 min_distance = distance;
419 vector<const char*> words;
421 while ((word = va_arg(ap,
const char*)))
422 words.push_back(word);
428 string GetLastErrorString() {
429 DWORD err = GetLastError();
433 FORMAT_MESSAGE_ALLOCATE_BUFFER |
434 FORMAT_MESSAGE_FROM_SYSTEM |
435 FORMAT_MESSAGE_IGNORE_INSERTS,
438 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
442 string msg = msg_buf;
447 void Win32Fatal(
const char*
function,
const char* hint) {
449 Fatal(
"%s: %s (%s)",
function, GetLastErrorString().c_str(), hint);
451 Fatal(
"%s: %s",
function, GetLastErrorString().c_str());
458 return (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z');
463 stripped.reserve(in.size());
465 for (
size_t i = 0; i < in.size(); ++i) {
466 if (in[i] !=
'\33') {
468 stripped.push_back(in[i]);
473 if (i + 1 >= in.size())
break;
474 if (in[i + 1] !=
'[')
continue;
486 return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
493 if (sched_getaffinity(getpid(),
sizeof(
set), &
set) == 0) {
494 return CPU_COUNT(&
set);
497 return sysconf(_SC_NPROCESSORS_ONLN);
501 #if defined(_WIN32) || defined(__CYGWIN__) 502 static double CalculateProcessorLoad(
uint64_t idle_ticks,
uint64_t total_ticks)
504 static uint64_t previous_idle_ticks = 0;
505 static uint64_t previous_total_ticks = 0;
506 static double previous_load = -0.0;
508 uint64_t idle_ticks_since_last_time = idle_ticks - previous_idle_ticks;
509 uint64_t total_ticks_since_last_time = total_ticks - previous_total_ticks;
511 bool first_call = (previous_total_ticks == 0);
512 bool ticks_not_updated_since_last_call = (total_ticks_since_last_time == 0);
515 if (first_call || ticks_not_updated_since_last_call) {
516 load = previous_load;
519 double idle_to_total_ratio =
520 ((double)idle_ticks_since_last_time) / total_ticks_since_last_time;
521 double load_since_last_call = 1.0 - idle_to_total_ratio;
524 if(previous_load > 0) {
525 load = 0.9 * previous_load + 0.1 * load_since_last_call;
527 load = load_since_last_call;
531 previous_load = load;
532 previous_total_ticks = total_ticks;
533 previous_idle_ticks = idle_ticks;
538 static uint64_t FileTimeToTickCount(
const FILETIME & ft)
546 FILETIME idle_time, kernel_time, user_time;
547 BOOL get_system_time_succeeded =
548 GetSystemTimes(&idle_time, &kernel_time, &user_time);
550 double posix_compatible_load;
551 if (get_system_time_succeeded) {
552 uint64_t idle_ticks = FileTimeToTickCount(idle_time);
556 FileTimeToTickCount(kernel_time) + FileTimeToTickCount(user_time);
558 double processor_load = CalculateProcessorLoad(idle_ticks, total_ticks);
562 posix_compatible_load = -0.0;
565 return posix_compatible_load;
567 #elif defined(__PASE__) 573 perfstat_cpu_total_t cpu_stats;
574 if (perfstat_cpu_total(NULL, &cpu_stats,
sizeof(cpu_stats), 1) < 0) {
579 return double(cpu_stats.loadavg[0]) / double(1 << SBITS);
581 #elif defined(__UCLIBC__) || (defined(__BIONIC__) && __ANDROID_API__ < 29) 584 if (sysinfo(&si) != 0)
586 return 1.0 / (1 << SI_LOAD_SHIFT) * si.loads[0];
590 double loadavg[3] = { 0.0f, 0.0f, 0.0f };
591 if (getloadavg(loadavg, 3) < 0) {
605 case 3:
return "...";
607 const int kMargin = 3;
609 if (result.size() > width) {
610 size_t elide_size = (width - kMargin) / 2;
611 result = result.substr(0, elide_size)
613 + result.substr(result.size() - elide_size, elide_size);
618 bool Truncate(
const string& path,
size_t size,
string* err) {
620 int fh = _sopen(path.c_str(), _O_RDWR | _O_CREAT, _SH_DENYNO,
621 _S_IREAD | _S_IWRITE);
622 int success = _chsize(fh, size);
625 int success = truncate(path.c_str(), size);
630 *err = strerror(errno);
const char * SpellcheckStringV(const string &text, const vector< const char *> &words)
static bool StringNeedsShellEscaping(const string &input)
static bool IsPathSeparator(char c)
const char * SpellcheckString(const char *text,...)
Like SpellcheckStringV, but takes a NULL-terminated list.
bool CanonicalizePath(string *path, uint64_t *slash_bits, string *err)
void GetWin32EscapedString(const string &input, string *result)
void GetShellEscapedString(const string &input, string *result)
void SetCloseOnExec(int fd)
Mark a file descriptor to not be inherited on exec()s.
static bool IsKnownWin32SafeCharacter(char ch)
static bool StringNeedsWin32Escaping(const string &input)
#define NINJA_FALLTHROUGH
int ReadFile(const string &path, string *contents, string *err)
#define METRIC_RECORD(name)
The primary interface to metrics.
static bool IsKnownShellSafeCharacter(char ch)
bool Truncate(const string &path, size_t size, string *err)
string StripAnsiEscapeCodes(const string &in)
void Fatal(const char *msg,...)
Log a fatal message and exit.
unsigned long long uint64_t
void Warning(const char *msg,...)
Log a warning message.
int EditDistance(const StringPiece &s1, const StringPiece &s2, bool allow_replacements, int max_edit_distance)
void Error(const char *msg,...)
Log an error message.
string ElideMiddle(const string &str, size_t width)