30 #include <sys/types.h>
39 #if defined(__APPLE__) || defined(__FreeBSD__)
40 #include <sys/sysctl.h>
41 #elif defined(__SVR4) && defined(__sun)
43 #include <sys/loadavg.h>
44 #elif defined(linux) || defined(__GLIBC__)
45 #include <sys/sysinfo.h>
51 void Fatal(
const char* msg, ...) {
53 fprintf(stderr,
"ninja: fatal: ");
55 vfprintf(stderr, msg, ap);
57 fprintf(stderr,
"\n");
71 fprintf(stderr,
"ninja: warning: ");
73 vfprintf(stderr, msg, ap);
75 fprintf(stderr,
"\n");
78 void Error(
const char* msg, ...) {
80 fprintf(stderr,
"ninja: error: ");
82 vfprintf(stderr, msg, ap);
84 fprintf(stderr,
"\n");
89 size_t len = path->size();
108 const int kMaxPathComponents = 30;
109 char* components[kMaxPathComponents];
110 int component_count = 0;
114 const char* src = start;
115 const char* end = start + *len;
120 if (*len > 1 && *(src + 1) ==
'/') {
135 if (src + 1 == end || src[1] ==
'/') {
139 }
else if (src[1] ==
'.' && (src + 2 == end || src[2] ==
'/')) {
141 if (component_count > 0) {
142 dst = components[component_count - 1];
159 if (component_count == kMaxPathComponents)
160 Fatal(
"path has too many components : %s", path);
161 components[component_count] = dst;
164 while (*src !=
'/' && src != end)
170 *err =
"path canonicalizes to the empty path";
174 *len = dst - start - 1;
178 int ReadFile(
const string& path,
string* contents,
string* err) {
179 FILE* f = fopen(path.c_str(),
"r");
181 err->assign(strerror(errno));
187 while ((len = fread(buf, 1,
sizeof(buf), f)) > 0) {
188 contents->append(buf, len);
191 err->assign(strerror(errno));
202 int flags = fcntl(fd, F_GETFD);
204 perror(
"fcntl(F_GETFD)");
206 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
207 perror(
"fcntl(F_SETFD)");
211 if (! SetHandleInformation(hd, HANDLE_FLAG_INHERIT, 0)) {
212 fprintf(stderr,
"SetHandleInformation(): %s", GetLastErrorString().c_str());
219 const vector<const char*>& words) {
220 const bool kAllowReplacements =
true;
221 const int kMaxValidEditDistance = 3;
223 int min_distance = kMaxValidEditDistance + 1;
224 const char* result = NULL;
225 for (vector<const char*>::const_iterator i = words.begin();
226 i != words.end(); ++i) {
227 int distance =
EditDistance(*i, text, kAllowReplacements,
228 kMaxValidEditDistance);
229 if (distance < min_distance) {
230 min_distance = distance;
242 vector<const char*> words;
244 while ((word = va_arg(ap,
const char*)))
245 words.push_back(word);
251 string GetLastErrorString() {
252 DWORD err = GetLastError();
256 FORMAT_MESSAGE_ALLOCATE_BUFFER |
257 FORMAT_MESSAGE_FROM_SYSTEM |
258 FORMAT_MESSAGE_IGNORE_INSERTS,
261 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
265 string msg = msg_buf;
270 void Win32Fatal(
const char*
function) {
271 Fatal(
"%s: %s",
function, GetLastErrorString().c_str());
277 return (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z');
282 stripped.reserve(in.size());
284 for (
size_t i = 0; i < in.size(); ++i) {
285 if (in[i] !=
'\33') {
287 stripped.push_back(in[i]);
292 if (i + 1 >= in.size())
break;
293 if (in[i + 1] !=
'[')
continue;
303 #if defined(linux) || defined(__GLIBC__)
307 #elif defined(__APPLE__) || defined(__FreeBSD__)
310 size_t processors_size =
sizeof(processors);
311 int name[] = {CTL_HW, HW_NCPU};
312 if (sysctl(name,
sizeof(name) /
sizeof(
int),
313 &processors, &processors_size,
319 #elif defined(_WIN32)
322 GetSystemInfo(&info);
323 return info.dwNumberOfProcessors;
329 return sysconf(_SC_NPROCESSORS_ONLN);
333 #if defined(_WIN32) || defined(__CYGWIN__)
341 double loadavg[3] = { 0.0f, 0.0f, 0.0f };
342 if (getloadavg(loadavg, 3) < 0) {
352 const int kMargin = 3;
354 if (result.size() + kMargin > width) {
355 size_t elide_size = (width - kMargin) / 2;
356 result = result.substr(0, elide_size)
358 + result.substr(result.size() - elide_size, elide_size);
363 bool Truncate(
const string& path,
size_t size,
string* err) {
365 int fh = _sopen(path.c_str(), _O_RDWR | _O_CREAT, _SH_DENYNO,
366 _S_IREAD | _S_IWRITE);
367 int success = _chsize(fh, size);
370 int success = truncate(path.c_str(), size);
375 *err = strerror(errno);
const char * SpellcheckString(const char *text,...)
Like SpellcheckStringV, but takes a NULL-terminated list.
bool CanonicalizePath(string *path, string *err)
Canonicalize a path like "foo/../bar.h" into just "bar.h".
void SetCloseOnExec(int fd)
Mark a file descriptor to not be inherited on exec()s.
static bool islatinalpha(int c)
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.
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.
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...
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.