|
Ninja
|
00001 // Copyright 2011 Google Inc. All Rights Reserved. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // http://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 00015 #include "util.h" 00016 00017 #ifdef _WIN32 00018 #include <windows.h> 00019 #endif 00020 00021 #include <errno.h> 00022 #include <fcntl.h> 00023 #include <stdarg.h> 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include <sys/stat.h> 00028 #include <sys/types.h> 00029 00030 #ifndef _WIN32 00031 #include <sys/time.h> 00032 #endif 00033 00034 #include <vector> 00035 00036 #ifdef _WIN32 00037 #include <direct.h> // _mkdir 00038 #endif 00039 00040 void Fatal(const char* msg, ...) { 00041 va_list ap; 00042 fprintf(stderr, "ninja: FATAL: "); 00043 va_start(ap, msg); 00044 vfprintf(stderr, msg, ap); 00045 va_end(ap); 00046 fprintf(stderr, "\n"); 00047 exit(1); 00048 } 00049 00050 void Warning(const char* msg, ...) { 00051 va_list ap; 00052 fprintf(stderr, "ninja: WARNING: "); 00053 va_start(ap, msg); 00054 vfprintf(stderr, msg, ap); 00055 va_end(ap); 00056 fprintf(stderr, "\n"); 00057 } 00058 00059 void Error(const char* msg, ...) { 00060 va_list ap; 00061 fprintf(stderr, "ninja: error: "); 00062 va_start(ap, msg); 00063 vfprintf(stderr, msg, ap); 00064 va_end(ap); 00065 fprintf(stderr, "\n"); 00066 } 00067 00068 bool CanonicalizePath(string* path, string* err) { 00069 // WARNING: this function is performance-critical; please benchmark 00070 // any changes you make to it. 00071 00072 if (path->empty()) { 00073 *err = "empty path"; 00074 return false; 00075 } 00076 00077 const int kMaxPathComponents = 30; 00078 char* components[kMaxPathComponents]; 00079 int component_count = 0; 00080 00081 char* start = &(*path)[0]; 00082 char* dst = start; 00083 const char* src = start; 00084 const char* end = start + path->size(); 00085 00086 if (*src == '/') { 00087 ++src; 00088 ++dst; 00089 } 00090 00091 while (src < end) { 00092 const char* sep = (const char*)memchr(src, '/', end - src); 00093 if (sep == NULL) 00094 sep = end; 00095 00096 if (*src == '.') { 00097 if (sep - src == 1) { 00098 // '.' component; eliminate. 00099 src += 2; 00100 continue; 00101 } else if (sep - src == 2 && src[1] == '.') { 00102 // '..' component. Back up if possible. 00103 if (component_count > 0) { 00104 dst = components[component_count - 1]; 00105 src += 3; 00106 --component_count; 00107 } else { 00108 while (src <= sep) 00109 *dst++ = *src++; 00110 } 00111 continue; 00112 } 00113 } 00114 00115 if (sep > src) { 00116 if (component_count == kMaxPathComponents) 00117 Fatal("path has too many components"); 00118 components[component_count] = dst; 00119 ++component_count; 00120 while (src <= sep) { 00121 *dst++ = *src++; 00122 } 00123 } 00124 00125 src = sep + 1; 00126 } 00127 00128 path->resize(dst - path->c_str() - 1); 00129 return true; 00130 } 00131 00132 int MakeDir(const string& path) { 00133 #ifdef _WIN32 00134 return _mkdir(path.c_str()); 00135 #else 00136 return mkdir(path.c_str(), 0777); 00137 #endif 00138 } 00139 00140 int ReadFile(const string& path, string* contents, string* err) { 00141 FILE* f = fopen(path.c_str(), "r"); 00142 if (!f) { 00143 err->assign(strerror(errno)); 00144 return -errno; 00145 } 00146 00147 char buf[64 << 10]; 00148 size_t len; 00149 while ((len = fread(buf, 1, sizeof(buf), f)) > 0) { 00150 contents->append(buf, len); 00151 } 00152 if (ferror(f)) { 00153 err->assign(strerror(errno)); // XXX errno? 00154 contents->clear(); 00155 fclose(f); 00156 return -errno; 00157 } 00158 fclose(f); 00159 return 0; 00160 } 00161 00162 void SetCloseOnExec(int fd) { 00163 #ifndef _WIN32 00164 int flags = fcntl(fd, F_GETFD); 00165 if (flags < 0) { 00166 perror("fcntl(F_GETFD)"); 00167 } else { 00168 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) 00169 perror("fcntl(F_SETFD)"); 00170 } 00171 #else 00172 // On Windows, handles must be explicitly marked to be passed to a 00173 // spawned process, so there's nothing to do here. 00174 #endif // WIN32 00175 } 00176 00177 int64_t GetTimeMillis() { 00178 #ifdef _WIN32 00179 // GetTickCount64 is only available on Vista or later. 00180 return GetTickCount(); 00181 #else 00182 timeval now; 00183 gettimeofday(&now, NULL); 00184 return ((int64_t)now.tv_sec * 1000) + (now.tv_usec / 1000); 00185 #endif 00186 }
1.7.5.1