windows: use _WIN32 define everywhere
[platform/upstream/ninja.git] / src / test.cc
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
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
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 #include "test.h"
16
17 #include <algorithm>
18
19 #include <errno.h>
20
21 #include "parsers.h"
22 #include "util.h"
23
24 #ifdef _WIN32
25 #include <windows.h>
26 #endif
27
28 namespace {
29
30 #ifdef _WIN32
31 #ifndef _mktemp_s
32 /// mingw has no mktemp.  Implement one with the same type as the one
33 /// found in the Windows API.
34 int _mktemp_s(char* templ) {
35   char* ofs = strchr(templ, 'X');
36   sprintf(ofs, "%d", rand() % 1000000);
37   return 0;
38 }
39 #endif
40
41 /// Windows has no mkdtemp.  Implement it in terms of _mktemp_s.
42 char* mkdtemp(char* name_template) {
43   int err = _mktemp_s(name_template);
44   if (err < 0) {
45     perror("_mktemp_s");
46     return NULL;
47   }
48
49   err = _mkdir(name_template);
50   if (err < 0) {
51     perror("mkdir");
52     return NULL;
53   }
54
55   return name_template;
56 }
57 #endif  // _WIN32
58
59 string GetSystemTempDir() {
60 #ifdef _WIN32
61   char buf[1024];
62   if (!GetTempPath(sizeof(buf), buf))
63     return "";
64   return buf;
65 #else
66   const char* tempdir = getenv("TMPDIR");
67   if (tempdir)
68     return tempdir;
69   return "/tmp";
70 #endif
71 }
72
73 }  // anonymous namespace
74
75 StateTestWithBuiltinRules::StateTestWithBuiltinRules() {
76   AssertParse(&state_,
77 "rule cat\n"
78 "  command = cat $in > $out\n");
79 }
80
81 Node* StateTestWithBuiltinRules::GetNode(const string& path) {
82   return state_.GetNode(path);
83 }
84
85 void AssertParse(State* state, const char* input) {
86   ManifestParser parser(state, NULL);
87   string err;
88   ASSERT_TRUE(parser.ParseTest(input, &err)) << err;
89   ASSERT_EQ("", err);
90 }
91
92 void VirtualFileSystem::Create(const string& path, int time,
93                                const string& contents) {
94   files_[path].mtime = time;
95   files_[path].contents = contents;
96 }
97
98 TimeStamp VirtualFileSystem::Stat(const string& path) {
99   FileMap::iterator i = files_.find(path);
100   if (i != files_.end())
101     return i->second.mtime;
102   return 0;
103 }
104
105 bool VirtualFileSystem::MakeDir(const string& path) {
106   directories_made_.push_back(path);
107   return true;  // success
108 }
109
110 string VirtualFileSystem::ReadFile(const string& path, string* err) {
111   files_read_.push_back(path);
112   FileMap::iterator i = files_.find(path);
113   if (i != files_.end())
114     return i->second.contents;
115   return "";
116 }
117
118 int VirtualFileSystem::RemoveFile(const string& path) {
119   if (find(directories_made_.begin(), directories_made_.end(), path)
120       != directories_made_.end())
121     return -1;
122   FileMap::iterator i = files_.find(path);
123   if (i != files_.end()) {
124     files_.erase(i);
125     files_removed_.insert(path);
126     return 0;
127   } else {
128     return 1;
129   }
130 }
131
132 void ScopedTempDir::CreateAndEnter(const string& name) {
133   // First change into the system temp dir and save it for cleanup.
134   start_dir_ = GetSystemTempDir();
135   if (start_dir_.empty())
136     Fatal("couldn't get system temp dir");
137   if (chdir(start_dir_.c_str()) < 0)
138     Fatal("chdir: %s", strerror(errno));
139
140   // Create a temporary subdirectory of that.
141   char name_template[1024];
142   strcpy(name_template, name.c_str());
143   strcat(name_template, "-XXXXXX");
144   char* tempname = mkdtemp(name_template);
145   if (!tempname)
146     Fatal("mkdtemp: %s", strerror(errno));
147   temp_dir_name_ = tempname;
148
149   // chdir into the new temporary directory.
150   if (chdir(temp_dir_name_.c_str()) < 0)
151     Fatal("chdir: %s", strerror(errno));
152 }
153
154 void ScopedTempDir::Cleanup() {
155   if (temp_dir_name_.empty())
156     return;  // Something went wrong earlier.
157
158   // Move out of the directory we're about to clobber.
159   if (chdir(start_dir_.c_str()) < 0)
160     Fatal("chdir: %s", strerror(errno));
161
162 #ifdef _WIN32
163   string command = "rmdir /s /q " + temp_dir_name_;
164 #else
165   string command = "rm -rf " + temp_dir_name_;
166 #endif
167   if (system(command.c_str()) < 0)
168     Fatal("system: %s", strerror(errno));
169
170   temp_dir_name_.clear();
171 }