xref: /aosp_15_r20/external/deqp/framework/delibs/decpp/deFilePath.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements C++ Base Library
3*35238bceSAndroid Build Coastguard Worker  * -----------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Filesystem path class.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "deFilePath.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include <vector>
27*35238bceSAndroid Build Coastguard Worker #include <stdexcept>
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker #include <sys/stat.h>
30*35238bceSAndroid Build Coastguard Worker #include <sys/types.h>
31*35238bceSAndroid Build Coastguard Worker 
32*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_WIN32)
33*35238bceSAndroid Build Coastguard Worker #define VC_EXTRALEAN
34*35238bceSAndroid Build Coastguard Worker #define WIN32_LEAN_AND_MEAN
35*35238bceSAndroid Build Coastguard Worker #define NOMINMAX
36*35238bceSAndroid Build Coastguard Worker #include <windows.h>
37*35238bceSAndroid Build Coastguard Worker #endif
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker using std::string;
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker namespace de
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_WIN32)
45*35238bceSAndroid Build Coastguard Worker const std::string FilePath::separator = "\\";
46*35238bceSAndroid Build Coastguard Worker #else
47*35238bceSAndroid Build Coastguard Worker const std::string FilePath::separator = "/";
48*35238bceSAndroid Build Coastguard Worker #endif
49*35238bceSAndroid Build Coastguard Worker 
FilePath(const std::vector<std::string> & components)50*35238bceSAndroid Build Coastguard Worker FilePath::FilePath(const std::vector<std::string> &components)
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker     for (size_t ndx = 0; ndx < components.size(); ndx++)
53*35238bceSAndroid Build Coastguard Worker     {
54*35238bceSAndroid Build Coastguard Worker         if (!m_path.empty() && !isSeparator(m_path[m_path.size() - 1]))
55*35238bceSAndroid Build Coastguard Worker             m_path += separator;
56*35238bceSAndroid Build Coastguard Worker         m_path += components[ndx];
57*35238bceSAndroid Build Coastguard Worker     }
58*35238bceSAndroid Build Coastguard Worker }
59*35238bceSAndroid Build Coastguard Worker 
split(std::vector<std::string> & components) const60*35238bceSAndroid Build Coastguard Worker void FilePath::split(std::vector<std::string> &components) const
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker     components.clear();
63*35238bceSAndroid Build Coastguard Worker 
64*35238bceSAndroid Build Coastguard Worker     int curCompStart = 0;
65*35238bceSAndroid Build Coastguard Worker     int pos;
66*35238bceSAndroid Build Coastguard Worker 
67*35238bceSAndroid Build Coastguard Worker     if (isWinNetPath())
68*35238bceSAndroid Build Coastguard Worker         components.push_back(separator + separator);
69*35238bceSAndroid Build Coastguard Worker     else if (isRootPath() && !beginsWithDrive())
70*35238bceSAndroid Build Coastguard Worker         components.push_back(separator);
71*35238bceSAndroid Build Coastguard Worker 
72*35238bceSAndroid Build Coastguard Worker     for (pos = 0; pos < (int)m_path.length(); pos++)
73*35238bceSAndroid Build Coastguard Worker     {
74*35238bceSAndroid Build Coastguard Worker         const char c = m_path[pos];
75*35238bceSAndroid Build Coastguard Worker 
76*35238bceSAndroid Build Coastguard Worker         if (isSeparator(c))
77*35238bceSAndroid Build Coastguard Worker         {
78*35238bceSAndroid Build Coastguard Worker             if (pos - curCompStart > 0)
79*35238bceSAndroid Build Coastguard Worker                 components.push_back(m_path.substr(curCompStart, pos - curCompStart));
80*35238bceSAndroid Build Coastguard Worker 
81*35238bceSAndroid Build Coastguard Worker             curCompStart = pos + 1;
82*35238bceSAndroid Build Coastguard Worker         }
83*35238bceSAndroid Build Coastguard Worker     }
84*35238bceSAndroid Build Coastguard Worker 
85*35238bceSAndroid Build Coastguard Worker     if (pos - curCompStart > 0)
86*35238bceSAndroid Build Coastguard Worker         components.push_back(m_path.substr(curCompStart, pos - curCompStart));
87*35238bceSAndroid Build Coastguard Worker }
88*35238bceSAndroid Build Coastguard Worker 
join(const std::vector<std::string> & components)89*35238bceSAndroid Build Coastguard Worker FilePath FilePath::join(const std::vector<std::string> &components)
90*35238bceSAndroid Build Coastguard Worker {
91*35238bceSAndroid Build Coastguard Worker     return FilePath(components);
92*35238bceSAndroid Build Coastguard Worker }
93*35238bceSAndroid Build Coastguard Worker 
normalize(void)94*35238bceSAndroid Build Coastguard Worker FilePath &FilePath::normalize(void)
95*35238bceSAndroid Build Coastguard Worker {
96*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> components;
97*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> reverseNormalizedComponents;
98*35238bceSAndroid Build Coastguard Worker 
99*35238bceSAndroid Build Coastguard Worker     split(components);
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker     m_path = "";
102*35238bceSAndroid Build Coastguard Worker 
103*35238bceSAndroid Build Coastguard Worker     int numUp = 0;
104*35238bceSAndroid Build Coastguard Worker 
105*35238bceSAndroid Build Coastguard Worker     // Do in reverse order and eliminate any . or .. components
106*35238bceSAndroid Build Coastguard Worker     for (int ndx = (int)components.size() - 1; ndx >= 0; ndx--)
107*35238bceSAndroid Build Coastguard Worker     {
108*35238bceSAndroid Build Coastguard Worker         const std::string &comp = components[ndx];
109*35238bceSAndroid Build Coastguard Worker         if (comp == "..")
110*35238bceSAndroid Build Coastguard Worker             numUp += 1;
111*35238bceSAndroid Build Coastguard Worker         else if (comp == ".")
112*35238bceSAndroid Build Coastguard Worker             continue;
113*35238bceSAndroid Build Coastguard Worker         else if (numUp > 0)
114*35238bceSAndroid Build Coastguard Worker             numUp -= 1; // Skip part
115*35238bceSAndroid Build Coastguard Worker         else
116*35238bceSAndroid Build Coastguard Worker             reverseNormalizedComponents.push_back(comp);
117*35238bceSAndroid Build Coastguard Worker     }
118*35238bceSAndroid Build Coastguard Worker 
119*35238bceSAndroid Build Coastguard Worker     if (isAbsolutePath() && numUp > 0)
120*35238bceSAndroid Build Coastguard Worker         throw std::runtime_error("Cannot normalize path: invalid path");
121*35238bceSAndroid Build Coastguard Worker 
122*35238bceSAndroid Build Coastguard Worker     // Prepend necessary ".." components
123*35238bceSAndroid Build Coastguard Worker     while (numUp--)
124*35238bceSAndroid Build Coastguard Worker         reverseNormalizedComponents.push_back("..");
125*35238bceSAndroid Build Coastguard Worker 
126*35238bceSAndroid Build Coastguard Worker     if (reverseNormalizedComponents.empty() && components.back() == ".")
127*35238bceSAndroid Build Coastguard Worker         reverseNormalizedComponents.push_back("."); // Composed of "." components only
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker     *this = join(std::vector<std::string>(reverseNormalizedComponents.rbegin(), reverseNormalizedComponents.rend()));
130*35238bceSAndroid Build Coastguard Worker 
131*35238bceSAndroid Build Coastguard Worker     return *this;
132*35238bceSAndroid Build Coastguard Worker }
133*35238bceSAndroid Build Coastguard Worker 
normalize(const FilePath & path)134*35238bceSAndroid Build Coastguard Worker FilePath FilePath::normalize(const FilePath &path)
135*35238bceSAndroid Build Coastguard Worker {
136*35238bceSAndroid Build Coastguard Worker     return FilePath(path).normalize();
137*35238bceSAndroid Build Coastguard Worker }
138*35238bceSAndroid Build Coastguard Worker 
getBaseName(void) const139*35238bceSAndroid Build Coastguard Worker std::string FilePath::getBaseName(void) const
140*35238bceSAndroid Build Coastguard Worker {
141*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> components;
142*35238bceSAndroid Build Coastguard Worker     split(components);
143*35238bceSAndroid Build Coastguard Worker     return !components.empty() ? components[components.size() - 1] : std::string("");
144*35238bceSAndroid Build Coastguard Worker }
145*35238bceSAndroid Build Coastguard Worker 
getDirName(void) const146*35238bceSAndroid Build Coastguard Worker std::string FilePath::getDirName(void) const
147*35238bceSAndroid Build Coastguard Worker {
148*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> components;
149*35238bceSAndroid Build Coastguard Worker     split(components);
150*35238bceSAndroid Build Coastguard Worker     if (components.size() > 1)
151*35238bceSAndroid Build Coastguard Worker     {
152*35238bceSAndroid Build Coastguard Worker         components.pop_back();
153*35238bceSAndroid Build Coastguard Worker         return FilePath(components).getPath();
154*35238bceSAndroid Build Coastguard Worker     }
155*35238bceSAndroid Build Coastguard Worker     else if (isAbsolutePath())
156*35238bceSAndroid Build Coastguard Worker         return separator;
157*35238bceSAndroid Build Coastguard Worker     else
158*35238bceSAndroid Build Coastguard Worker         return std::string(".");
159*35238bceSAndroid Build Coastguard Worker }
160*35238bceSAndroid Build Coastguard Worker 
getFileExtension(void) const161*35238bceSAndroid Build Coastguard Worker std::string FilePath::getFileExtension(void) const
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker     std::string baseName = getBaseName();
164*35238bceSAndroid Build Coastguard Worker     size_t dotPos        = baseName.find_last_of('.');
165*35238bceSAndroid Build Coastguard Worker     if (dotPos == std::string::npos)
166*35238bceSAndroid Build Coastguard Worker         return std::string("");
167*35238bceSAndroid Build Coastguard Worker     else
168*35238bceSAndroid Build Coastguard Worker         return baseName.substr(dotPos + 1);
169*35238bceSAndroid Build Coastguard Worker }
170*35238bceSAndroid Build Coastguard Worker 
exists(void) const171*35238bceSAndroid Build Coastguard Worker bool FilePath::exists(void) const
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker     FilePath normPath = FilePath::normalize(*this);
174*35238bceSAndroid Build Coastguard Worker     struct stat st;
175*35238bceSAndroid Build Coastguard Worker     int result = stat(normPath.getPath(), &st);
176*35238bceSAndroid Build Coastguard Worker     return result == 0;
177*35238bceSAndroid Build Coastguard Worker }
178*35238bceSAndroid Build Coastguard Worker 
getType(void) const179*35238bceSAndroid Build Coastguard Worker FilePath::Type FilePath::getType(void) const
180*35238bceSAndroid Build Coastguard Worker {
181*35238bceSAndroid Build Coastguard Worker     FilePath normPath = FilePath::normalize(*this);
182*35238bceSAndroid Build Coastguard Worker     struct stat st;
183*35238bceSAndroid Build Coastguard Worker     int result = stat(normPath.getPath(), &st);
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker     if (result != 0)
186*35238bceSAndroid Build Coastguard Worker         return TYPE_UNKNOWN;
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker     int type = st.st_mode & S_IFMT;
189*35238bceSAndroid Build Coastguard Worker     if (type == S_IFREG)
190*35238bceSAndroid Build Coastguard Worker         return TYPE_FILE;
191*35238bceSAndroid Build Coastguard Worker     else if (type == S_IFDIR)
192*35238bceSAndroid Build Coastguard Worker         return TYPE_DIRECTORY;
193*35238bceSAndroid Build Coastguard Worker     else
194*35238bceSAndroid Build Coastguard Worker         return TYPE_UNKNOWN;
195*35238bceSAndroid Build Coastguard Worker }
196*35238bceSAndroid Build Coastguard Worker 
beginsWithDrive(void) const197*35238bceSAndroid Build Coastguard Worker bool FilePath::beginsWithDrive(void) const
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_path.length(); ndx++)
200*35238bceSAndroid Build Coastguard Worker     {
201*35238bceSAndroid Build Coastguard Worker         if (m_path[ndx] == ':' && ndx + 1 < (int)m_path.length() && isSeparator(m_path[ndx + 1]))
202*35238bceSAndroid Build Coastguard Worker             return true; // First part is drive letter.
203*35238bceSAndroid Build Coastguard Worker         if (isSeparator(m_path[ndx]))
204*35238bceSAndroid Build Coastguard Worker             return false;
205*35238bceSAndroid Build Coastguard Worker     }
206*35238bceSAndroid Build Coastguard Worker     return false;
207*35238bceSAndroid Build Coastguard Worker }
208*35238bceSAndroid Build Coastguard Worker 
isAbsolutePath(void) const209*35238bceSAndroid Build Coastguard Worker bool FilePath::isAbsolutePath(void) const
210*35238bceSAndroid Build Coastguard Worker {
211*35238bceSAndroid Build Coastguard Worker     return isRootPath() || isWinNetPath() || beginsWithDrive();
212*35238bceSAndroid Build Coastguard Worker }
213*35238bceSAndroid Build Coastguard Worker 
FilePath_selfTest(void)214*35238bceSAndroid Build Coastguard Worker void FilePath_selfTest(void)
215*35238bceSAndroid Build Coastguard Worker {
216*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(!FilePath(".").isAbsolutePath());
217*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(!FilePath("..\\foo").isAbsolutePath());
218*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(!FilePath("foo").isAbsolutePath());
219*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("\\foo/bar").isAbsolutePath());
220*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("/foo").isAbsolutePath());
221*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("\\").isAbsolutePath());
222*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("\\\\net\\loc").isAbsolutePath());
223*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("C:\\file.txt").isAbsolutePath());
224*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("c:/file.txt").isAbsolutePath());
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(string(".") == FilePath(".//.").normalize().getPath());
227*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(string(".") == FilePath(".").normalize().getPath());
228*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT((string("..") + FilePath::separator + "test") ==
229*35238bceSAndroid Build Coastguard Worker                    FilePath("foo/../bar/../../test").normalize().getPath());
230*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT((FilePath::separator + "foo" + FilePath::separator + "foo.txt") ==
231*35238bceSAndroid Build Coastguard Worker                    FilePath("/foo\\bar/..\\dir\\..\\foo.txt").normalize().getPath());
232*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT((string("c:") + FilePath::separator + "foo" + FilePath::separator + "foo.txt") ==
233*35238bceSAndroid Build Coastguard Worker                    FilePath("c:/foo\\bar/..\\dir\\..\\foo.txt").normalize().getPath());
234*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT((FilePath::separator + FilePath::separator + "foo" + FilePath::separator + "foo.txt") ==
235*35238bceSAndroid Build Coastguard Worker                    FilePath("\\\\foo\\bar/..\\dir\\..\\foo.txt").normalize().getPath());
236*35238bceSAndroid Build Coastguard Worker 
237*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo/bar").getBaseName() == "bar");
238*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo/bar/").getBaseName() == "bar");
239*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo\\bar").getBaseName() == "bar");
240*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo\\bar\\").getBaseName() == "bar");
241*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo/bar").getDirName() == "foo");
242*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo/bar/").getDirName() == "foo");
243*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo\\bar").getDirName() == "foo");
244*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("foo\\bar\\").getDirName() == "foo");
245*35238bceSAndroid Build Coastguard Worker     DE_TEST_ASSERT(FilePath("/foo/bar/baz").getDirName() == FilePath::separator + "foo" + FilePath::separator + "bar");
246*35238bceSAndroid Build Coastguard Worker }
247*35238bceSAndroid Build Coastguard Worker 
createDirectoryImpl(const char * path)248*35238bceSAndroid Build Coastguard Worker static void createDirectoryImpl(const char *path)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_WIN32)
251*35238bceSAndroid Build Coastguard Worker     if (!CreateDirectory(path, DE_NULL))
252*35238bceSAndroid Build Coastguard Worker         throw std::runtime_error("Failed to create directory");
253*35238bceSAndroid Build Coastguard Worker #elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || \
254*35238bceSAndroid Build Coastguard Worker     (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA)
255*35238bceSAndroid Build Coastguard Worker     if (mkdir(path, 0777) != 0)
256*35238bceSAndroid Build Coastguard Worker         throw std::runtime_error("Failed to create directory");
257*35238bceSAndroid Build Coastguard Worker #else
258*35238bceSAndroid Build Coastguard Worker #error Implement createDirectoryImpl() for your platform.
259*35238bceSAndroid Build Coastguard Worker #endif
260*35238bceSAndroid Build Coastguard Worker }
261*35238bceSAndroid Build Coastguard Worker 
createDirectory(const char * path)262*35238bceSAndroid Build Coastguard Worker void createDirectory(const char *path)
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker     FilePath dirPath = FilePath::normalize(path);
265*35238bceSAndroid Build Coastguard Worker     FilePath parentPath(dirPath.getDirName());
266*35238bceSAndroid Build Coastguard Worker 
267*35238bceSAndroid Build Coastguard Worker     if (dirPath.exists())
268*35238bceSAndroid Build Coastguard Worker         throw std::runtime_error("Destination exists already");
269*35238bceSAndroid Build Coastguard Worker     else if (!parentPath.exists())
270*35238bceSAndroid Build Coastguard Worker         throw std::runtime_error("Parent directory doesn't exist");
271*35238bceSAndroid Build Coastguard Worker     else if (parentPath.getType() != FilePath::TYPE_DIRECTORY)
272*35238bceSAndroid Build Coastguard Worker         throw std::runtime_error("Parent is not directory");
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker     createDirectoryImpl(path);
275*35238bceSAndroid Build Coastguard Worker }
276*35238bceSAndroid Build Coastguard Worker 
createDirectoryAndParents(const char * path)277*35238bceSAndroid Build Coastguard Worker void createDirectoryAndParents(const char *path)
278*35238bceSAndroid Build Coastguard Worker {
279*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> createPaths;
280*35238bceSAndroid Build Coastguard Worker     FilePath curPath(path);
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker     if (curPath.exists())
283*35238bceSAndroid Build Coastguard Worker         throw std::runtime_error("Destination exists already");
284*35238bceSAndroid Build Coastguard Worker 
285*35238bceSAndroid Build Coastguard Worker     while (!curPath.exists())
286*35238bceSAndroid Build Coastguard Worker     {
287*35238bceSAndroid Build Coastguard Worker         createPaths.push_back(curPath.getPath());
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker         std::string parent = curPath.getDirName();
290*35238bceSAndroid Build Coastguard Worker         DE_CHECK_RUNTIME_ERR(parent != curPath.getPath());
291*35238bceSAndroid Build Coastguard Worker         curPath = FilePath(parent);
292*35238bceSAndroid Build Coastguard Worker     }
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker     // Create in reverse order.
295*35238bceSAndroid Build Coastguard Worker     for (std::vector<std::string>::const_reverse_iterator parentIter = createPaths.rbegin();
296*35238bceSAndroid Build Coastguard Worker          parentIter != createPaths.rend(); parentIter++)
297*35238bceSAndroid Build Coastguard Worker         createDirectory(parentIter->c_str());
298*35238bceSAndroid Build Coastguard Worker }
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker } // namespace de
301