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> 57 void Fatal(
const char* msg, ...) {
59 fprintf(stderr,
"ninja: fatal: ");
61 vfprintf(stderr, msg, ap);
63 fprintf(stderr,
"\n");
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");
95 size_t len = path->size();
107 return c ==
'/' || c ==
'\\';
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;
155 }
else if (src[1] ==
'.' && (src + 2 == end ||
IsPathSeparator(src[2]))) {
157 if (component_count > 0) {
158 dst = components[component_count - 1];
175 if (component_count == kMaxPathComponents)
176 Fatal(
"path has too many components : %s", path);
177 components[component_count] = dst;
190 *len = dst - start - 1;
195 for (
char* c = start; c < start + *len; ++c) {
214 if (
'A' <= ch && ch <=
'Z')
return true;
215 if (
'a' <= ch && ch <=
'z')
return true;
216 if (
'0' <= ch && ch <=
'9')
return true;
241 for (
size_t i = 0; i < input.size(); ++i) {
248 for (
size_t i = 0; i < input.size(); ++i) {
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);
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) {
321 HANDLE f = ::CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
322 OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
323 if (f == INVALID_HANDLE_VALUE) {
324 err->assign(GetLastErrorString());
331 if (!::
ReadFile(f, buf,
sizeof(buf), &len, NULL)) {
332 err->assign(GetLastErrorString());
338 contents->append(buf, len);
343 FILE* f = fopen(path.c_str(),
"rb");
345 err->assign(strerror(errno));
350 if (fstat(fileno(f), &st) < 0) {
351 err->assign(strerror(errno));
357 contents->reserve(st.st_size + 1);
361 while (!feof(f) && (len = fread(buf, 1,
sizeof(buf), f)) > 0) {
362 contents->append(buf, len);
365 err->assign(strerror(errno));
377 int flags = fcntl(fd, F_GETFD);
379 perror(
"fcntl(F_GETFD)");
381 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
382 perror(
"fcntl(F_SETFD)");
385 HANDLE hd = (HANDLE) _get_osfhandle(fd);
386 if (! SetHandleInformation(hd, HANDLE_FLAG_INHERIT, 0)) {
387 fprintf(stderr,
"SetHandleInformation(): %s", GetLastErrorString().c_str());
394 const vector<const char*>& words) {
395 const bool kAllowReplacements =
true;
396 const int kMaxValidEditDistance = 3;
398 int min_distance = kMaxValidEditDistance + 1;
399 const char* result = NULL;
400 for (vector<const char*>::const_iterator i = words.begin();
401 i != words.end(); ++i) {
402 int distance =
EditDistance(*i, text, kAllowReplacements,
403 kMaxValidEditDistance);
404 if (distance < min_distance) {
405 min_distance = distance;
417 vector<const char*> words;
419 while ((word = va_arg(ap,
const char*)))
420 words.push_back(word);
426 string GetLastErrorString() {
427 DWORD err = GetLastError();
431 FORMAT_MESSAGE_ALLOCATE_BUFFER |
432 FORMAT_MESSAGE_FROM_SYSTEM |
433 FORMAT_MESSAGE_IGNORE_INSERTS,
436 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
440 string msg = msg_buf;
445 void Win32Fatal(
const char*
function,
const char* hint) {
447 Fatal(
"%s: %s (%s)",
function, GetLastErrorString().c_str(), hint);
449 Fatal(
"%s: %s",
function, GetLastErrorString().c_str());
456 return (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z');
461 stripped.reserve(in.size());
463 for (
size_t i = 0; i < in.size(); ++i) {
464 if (in[i] !=
'\33') {
466 stripped.push_back(in[i]);
471 if (i + 1 >= in.size())
break;
472 if (in[i + 1] !=
'[')
continue;
485 GetNativeSystemInfo(&info);
486 return info.dwNumberOfProcessors;
488 return sysconf(_SC_NPROCESSORS_ONLN);
492 #if defined(_WIN32) || defined(__CYGWIN__) 493 static double CalculateProcessorLoad(
uint64_t idle_ticks,
uint64_t total_ticks)
495 static uint64_t previous_idle_ticks = 0;
496 static uint64_t previous_total_ticks = 0;
497 static double previous_load = -0.0;
499 uint64_t idle_ticks_since_last_time = idle_ticks - previous_idle_ticks;
500 uint64_t total_ticks_since_last_time = total_ticks - previous_total_ticks;
502 bool first_call = (previous_total_ticks == 0);
503 bool ticks_not_updated_since_last_call = (total_ticks_since_last_time == 0);
506 if (first_call || ticks_not_updated_since_last_call) {
507 load = previous_load;
510 double idle_to_total_ratio =
511 ((double)idle_ticks_since_last_time) / total_ticks_since_last_time;
512 double load_since_last_call = 1.0 - idle_to_total_ratio;
515 if(previous_load > 0) {
516 load = 0.9 * previous_load + 0.1 * load_since_last_call;
518 load = load_since_last_call;
522 previous_load = load;
523 previous_total_ticks = total_ticks;
524 previous_idle_ticks = idle_ticks;
529 static uint64_t FileTimeToTickCount(
const FILETIME & ft)
537 FILETIME idle_time, kernel_time, user_time;
538 BOOL get_system_time_succeeded =
539 GetSystemTimes(&idle_time, &kernel_time, &user_time);
541 double posix_compatible_load;
542 if (get_system_time_succeeded) {
543 uint64_t idle_ticks = FileTimeToTickCount(idle_time);
547 FileTimeToTickCount(kernel_time) + FileTimeToTickCount(user_time);
549 double processor_load = CalculateProcessorLoad(idle_ticks, total_ticks);
553 posix_compatible_load = -0.0;
556 return posix_compatible_load;
560 perfstat_cpu_total_t cpu_stats;
561 if (perfstat_cpu_total(NULL, &cpu_stats,
sizeof(cpu_stats), 1) < 0) {
566 return double(cpu_stats.loadavg[0]) / double(1 << SBITS);
568 #elif defined(__UCLIBC__) 571 if (sysinfo(&si) != 0)
573 return 1.0 / (1 << SI_LOAD_SHIFT) * si.loads[0];
577 double loadavg[3] = { 0.0f, 0.0f, 0.0f };
578 if (getloadavg(loadavg, 3) < 0) {
588 const int kMargin = 3;
590 if (result.size() > width) {
591 size_t elide_size = (width - kMargin) / 2;
592 result = result.substr(0, elide_size)
594 + result.substr(result.size() - elide_size, elide_size);
599 bool Truncate(
const string& path,
size_t size,
string* err) {
601 int fh = _sopen(path.c_str(), _O_RDWR | _O_CREAT, _SH_DENYNO,
602 _S_IREAD | _S_IWRITE);
603 int success = _chsize(fh, size);
606 int success = truncate(path.c_str(), size);
611 *err = strerror(errno);
const char * SpellcheckStringV(const string &text, const vector< const char *> &words)
Given a misspelled string and a list of correct spellings, returns the closest match or NULL if there...
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)
Canonicalize a path like "foo/../bar.h" into just "bar.h".
void GetWin32EscapedString(const string &input, string *result)
void GetShellEscapedString(const string &input, string *result)
Appends |input| to |*result|, escaping according to the whims of either Bash, or Win32's CommandLineT...
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)
Read a file to a string (in text mode: with CRLF conversion on Windows).
#define METRIC_RECORD(name)
The primary interface to metrics.
static bool IsKnownShellSafeCharacter(char ch)
bool Truncate(const string &path, size_t size, string *err)
Truncates a file to the given size.
string StripAnsiEscapeCodes(const string &in)
Removes all Ansi escape codes (http://www.termsys.demon.co.uk/vtansi.htm).
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)
Elide the given string str with '...' in the middle if the length exceeds width.