blob: 84945ffb568e2602a1f7481ecac963ea9ec52751 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.org20a5c462013-05-27 08:02:22 +000011#include "webrtc/test/testsupport/fileutils.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000012
13#ifdef WIN32
14#include <direct.h>
15#define GET_CURRENT_DIR _getcwd
16#else
17#include <unistd.h>
18#define GET_CURRENT_DIR getcwd
19#endif
20
21#include <sys/stat.h> // To check for directory existence.
22#ifndef S_ISDIR // Not defined in stat.h on Windows.
23#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
24#endif
25
26#include <cstdio>
27#include <cstring>
28
pbos@webrtc.org20a5c462013-05-27 08:02:22 +000029#include "webrtc/typedefs.h" // For architecture defines
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000030
31namespace webrtc {
32namespace test {
33
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000034namespace {
35
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000036#ifdef WIN32
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000037const char* kPathDelimiter = "\\";
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000038#else
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000039const char* kPathDelimiter = "/";
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000040#endif
41
42#ifdef WEBRTC_ANDROID
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000043const char* kResourcesDirName = "resources";
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000044#else
45// The file we're looking for to identify the project root dir.
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000046const char* kProjectRootFileName = "DEPS";
47const char* kResourcesDirName = "resources";
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000048#endif
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000049
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000050const char* kFallbackPath = "./";
51const char* kOutputDirName = "out";
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000052char relative_dir_path[FILENAME_MAX];
53bool relative_dir_path_set = false;
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000054
55} // namespace
56
57const char* kCannotFindProjectRootDir = "ERROR_CANNOT_FIND_PROJECT_ROOT_DIR";
58
59std::string OutputPathAndroid();
60std::string ProjectRoothPathAndroid();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000061
62void SetExecutablePath(const std::string& path) {
63 std::string working_dir = WorkingDir();
64 std::string temp_path = path;
65
66 // Handle absolute paths; convert them to relative paths to the working dir.
67 if (path.find(working_dir) != std::string::npos) {
68 temp_path = path.substr(working_dir.length() + 1);
69 }
70 // Trim away the executable name; only store the relative dir path.
71 temp_path = temp_path.substr(0, temp_path.find_last_of(kPathDelimiter));
72 strncpy(relative_dir_path, temp_path.c_str(), FILENAME_MAX);
73 relative_dir_path_set = true;
74}
75
76bool FileExists(std::string& file_name) {
77 struct stat file_info = {0};
78 return stat(file_name.c_str(), &file_info) == 0;
79}
80
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000081std::string OutputPathImpl() {
82 std::string path = ProjectRootPath();
83 if (path == kCannotFindProjectRootDir) {
84 return kFallbackPath;
85 }
86 path += kOutputDirName;
87 if (!CreateDirectory(path)) {
88 return kFallbackPath;
89 }
90 return path + kPathDelimiter;
91}
92
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000093#ifdef WEBRTC_ANDROID
94
95std::string ProjectRootPath() {
henrike@webrtc.org222efdc2013-07-05 04:15:38 +000096 return ProjectRoothPathAndroid();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000097}
98
99std::string OutputPath() {
henrike@webrtc.org222efdc2013-07-05 04:15:38 +0000100 return OutputPathAndroid();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000101}
102
103std::string WorkingDir() {
henrike@webrtc.org222efdc2013-07-05 04:15:38 +0000104 return ProjectRootPath();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000105}
106
107#else // WEBRTC_ANDROID
108
109std::string ProjectRootPath() {
110 std::string path = WorkingDir();
111 if (path == kFallbackPath) {
112 return kCannotFindProjectRootDir;
113 }
114 if (relative_dir_path_set) {
115 path = path + kPathDelimiter + relative_dir_path;
116 }
117 // Check for our file that verifies the root dir.
118 size_t path_delimiter_index = path.find_last_of(kPathDelimiter);
119 while (path_delimiter_index != std::string::npos) {
120 std::string root_filename = path + kPathDelimiter + kProjectRootFileName;
121 if (FileExists(root_filename)) {
122 return path + kPathDelimiter;
123 }
124 // Move up one directory in the directory tree.
125 path = path.substr(0, path_delimiter_index);
126 path_delimiter_index = path.find_last_of(kPathDelimiter);
127 }
128 // Reached the root directory.
129 fprintf(stderr, "Cannot find project root directory!\n");
130 return kCannotFindProjectRootDir;
131}
132
133std::string OutputPath() {
henrike@webrtc.org222efdc2013-07-05 04:15:38 +0000134 return OutputPathImpl();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000135}
136
137std::string WorkingDir() {
138 char path_buffer[FILENAME_MAX];
139 if (!GET_CURRENT_DIR(path_buffer, sizeof(path_buffer))) {
140 fprintf(stderr, "Cannot get current directory!\n");
141 return kFallbackPath;
142 } else {
143 return std::string(path_buffer);
144 }
145}
146
147#endif // !WEBRTC_ANDROID
148
149bool CreateDirectory(std::string directory_name) {
150 struct stat path_info = {0};
151 // Check if the path exists already:
152 if (stat(directory_name.c_str(), &path_info) == 0) {
153 if (!S_ISDIR(path_info.st_mode)) {
154 fprintf(stderr, "Path %s exists but is not a directory! Remove this "
155 "file and re-run to create the directory.\n",
156 directory_name.c_str());
157 return false;
158 }
159 } else {
160#ifdef WIN32
161 return _mkdir(directory_name.c_str()) == 0;
162#else
163 return mkdir(directory_name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0;
164#endif
165 }
166 return true;
167}
168
169std::string ResourcePath(std::string name, std::string extension) {
170 std::string platform = "win";
171#ifdef WEBRTC_LINUX
172 platform = "linux";
173#endif // WEBRTC_LINUX
174#ifdef WEBRTC_MAC
175 platform = "mac";
176#endif // WEBRTC_MAC
177
178#ifdef WEBRTC_ARCH_64_BITS
179 std::string architecture = "64";
180#else
181 std::string architecture = "32";
182#endif // WEBRTC_ARCH_64_BITS
183
184 std::string resources_path = ProjectRootPath() + kResourcesDirName +
185 kPathDelimiter;
186 std::string resource_file = resources_path + name + "_" + platform + "_" +
187 architecture + "." + extension;
188 if (FileExists(resource_file)) {
189 return resource_file;
190 }
191 // Try without architecture.
192 resource_file = resources_path + name + "_" + platform + "." + extension;
193 if (FileExists(resource_file)) {
194 return resource_file;
195 }
196 // Try without platform.
197 resource_file = resources_path + name + "_" + architecture + "." + extension;
198 if (FileExists(resource_file)) {
199 return resource_file;
200 }
201
202 // Fall back on name without architecture or platform.
203 return resources_path + name + "." + extension;
204}
205
206size_t GetFileSize(std::string filename) {
207 FILE* f = fopen(filename.c_str(), "rb");
208 size_t size = 0;
209 if (f != NULL) {
210 if (fseek(f, 0, SEEK_END) == 0) {
211 size = ftell(f);
212 }
213 fclose(f);
214 }
215 return size;
216}
217
218} // namespace test
219} // namespace webrtc