1dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//===-- PathV2.cpp - Implement OS Path Concept ------------------*- C++ -*-===//
2dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//
3dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//                     The LLVM Compiler Infrastructure
4dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//
5dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// This file is distributed under the University of Illinois Open Source
6dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// License. See LICENSE.TXT for details.
7dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//
8dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//===----------------------------------------------------------------------===//
9dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//
10dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//  This file implements the operating system PathV2 API.
11dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//
12dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//===----------------------------------------------------------------------===//
13dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
14dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "llvm/Support/PathV2.h"
15bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencer#include "llvm/Support/FileSystem.h"
165b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer#include "llvm/Support/Endian.h"
17dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "llvm/Support/ErrorHandling.h"
18dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include <cctype>
19628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer#include <cstdio>
20628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer#include <cstring>
21dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
22dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace {
23dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  using llvm::StringRef;
2463cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  using llvm::sys::path::is_separator;
25dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
26dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
2780fd2a1972fa1955cdea1bf2a37b47659331870cBenjamin Kramer  const char *separators = "\\/";
2880fd2a1972fa1955cdea1bf2a37b47659331870cBenjamin Kramer  const char  prefered_separator = '\\';
29dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
3080fd2a1972fa1955cdea1bf2a37b47659331870cBenjamin Kramer  const char  separators = '/';
3180fd2a1972fa1955cdea1bf2a37b47659331870cBenjamin Kramer  const char  prefered_separator = '/';
32dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
33dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
347fb866643e76dc598473b666439a42a11d97a58cBenjamin Kramer  StringRef find_first_component(StringRef path) {
35dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Look for this first component in the following order.
36dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * empty (in this case we return an empty string)
37dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * either C: or {//,\\}net.
38dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {/,\}
39dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {.,..}
40dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {file,directory}name
41dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
42dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path.empty())
43dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return path;
44dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
45ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer#ifdef LLVM_ON_WIN32
46dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // C:
47dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path.size() >= 2 && std::isalpha(path[0]) && path[1] == ':')
483ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      return path.substr(0, 2);
49ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer#endif
50dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
51dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // //net
52dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if ((path.size() > 2) &&
53ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer        is_separator(path[0]) &&
54ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer        path[0] == path[1] &&
55ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer        !is_separator(path[2])) {
56dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Find the next directory separator.
57ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer      size_t end = path.find_first_of(separators, 2);
583ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      return path.substr(0, end);
59dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
60dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
61dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // {/,\}
62ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer    if (is_separator(path[0]))
633ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      return path.substr(0, 1);
64dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
65dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path.startswith(".."))
663ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      return path.substr(0, 2);
67dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
68dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path[0] == '.')
693ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      return path.substr(0, 1);
70dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
71dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {file,directory}name
72ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer    size_t end = path.find_first_of(separators, 2);
733ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer    return path.substr(0, end);
74dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
75a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
76d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramer  size_t filename_pos(StringRef str) {
77a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() == 2 &&
78a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[0]) &&
79ca3a339d767882ef726d898d29f06bc94568c701Michael J. Spencer        str[0] == str[1])
80a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 0;
81a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
82a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 0 && is_separator(str[str.size() - 1]))
83a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return str.size() - 1;
84a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
85a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    size_t pos = str.find_last_of(separators, str.size() - 1);
86a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
87a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32
88a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (pos == StringRef::npos)
89a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      pos = str.find_last_of(':', str.size() - 2);
90a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif
91a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
92a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (pos == StringRef::npos ||
93a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        (pos == 1 && is_separator(str[0])))
94a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 0;
95a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
96a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return pos + 1;
97a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
98a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
99d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramer  size_t root_dir_start(StringRef str) {
100a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "c:/"
101a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32
102a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 2 &&
103a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        str[1] == ':' &&
104a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[2]))
105a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 2;
106a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif
107a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
108a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "//"
109a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() == 2 &&
110a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[0]) &&
111a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        str[0] == str[1])
112a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return StringRef::npos;
113a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
114a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "//net"
115a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 3 &&
116a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[0]) &&
117a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        str[0] == str[1] &&
118a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        !is_separator(str[2])) {
119a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return str.find_first_of(separators, 2);
120a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    }
121a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
122a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "/"
123a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 0 && is_separator(str[0]))
124a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 0;
125a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
126a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return StringRef::npos;
127a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
128a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
129d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramer  size_t parent_path_end(StringRef path) {
130a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    size_t end_pos = filename_pos(path);
131a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
132a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
133a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
134a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // Skip separators except for root dir.
1353ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer    size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
136a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
137a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    while(end_pos > 0 &&
138a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer          (end_pos - 1) != root_dir_pos &&
139a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer          is_separator(path[end_pos - 1]))
140a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      --end_pos;
141a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
142a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
143a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return StringRef::npos;
144a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
145a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return end_pos;
146a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
14763cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan} // end unnamed namespace
148dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
149dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace llvm {
150dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace sys  {
151dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace path {
152dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
153d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst_iterator begin(StringRef path) {
154dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator i;
155dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Path      = path;
156dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Component = find_first_component(path);
157dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Position  = 0;
158dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return i;
159dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
160dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
161d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst_iterator end(StringRef path) {
162dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator i;
163dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Path      = path;
164dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Position  = path.size();
165dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return i;
166dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
167dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
168dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerconst_iterator &const_iterator::operator++() {
169dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  assert(Position < Path.size() && "Tried to increment past end!");
170dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
171dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Increment Position to past the current component
172dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  Position += Component.size();
173dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
174dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Check for end.
175dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (Position == Path.size()) {
176dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    Component = StringRef();
177dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return *this;
178dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
179dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
180dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Both POSIX and Windows treat paths that begin with exactly two separators
181dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // specially.
182dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  bool was_net = Component.size() > 2 &&
183dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    is_separator(Component[0]) &&
184dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    Component[1] == Component[0] &&
185dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    !is_separator(Component[2]);
186dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
187dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Handle separators.
188dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (is_separator(Path[Position])) {
189dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Root dir.
190dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (was_net
191dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
192dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // c:/
193dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        || Component.endswith(":")
194dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
195dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        ) {
1963ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      Component = Path.substr(Position, 1);
197dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return *this;
198dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
199dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
200dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Skip extra separators.
201dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    while (Position != Path.size() &&
202dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer           is_separator(Path[Position])) {
203dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      ++Position;
204dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
205dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
206dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Treat trailing '/' as a '.'.
207dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (Position == Path.size()) {
208dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      --Position;
209dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      Component = ".";
210dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return *this;
211dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
212dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
213dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
214dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Find next component.
215dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  size_t end_pos = Path.find_first_of(separators, Position);
2163ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer  Component = Path.slice(Position, end_pos);
217dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
218dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return *this;
219dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
220dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
221a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencerconst_iterator &const_iterator::operator--() {
222a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  // If we're at the end and the previous char was a '/', return '.'.
223a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  if (Position == Path.size() &&
224a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      Path.size() > 1 &&
225a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      is_separator(Path[Position - 1])
226a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32
227a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      && Path[Position - 2] != ':'
228a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif
229a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      ) {
230a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    --Position;
231a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    Component = ".";
232a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return *this;
233a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
234a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
235a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  // Skip separators unless it's the root directory.
236a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t root_dir_pos = root_dir_start(Path);
237a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t end_pos = Position;
238a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
239a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  while(end_pos > 0 &&
240a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        (end_pos - 1) != root_dir_pos &&
241a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(Path[end_pos - 1]))
242a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    --end_pos;
243a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
244a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  // Find next separator.
2453ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer  size_t start_pos = filename_pos(Path.substr(0, end_pos));
2463ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer  Component = Path.slice(start_pos, end_pos);
247a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  Position = start_pos;
248a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  return *this;
249a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer}
250a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
251dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerbool const_iterator::operator==(const const_iterator &RHS) const {
252dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return Path.begin() == RHS.Path.begin() &&
253dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer         Position == RHS.Position;
254dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
255dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
256dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerbool const_iterator::operator!=(const const_iterator &RHS) const {
257dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return !(*this == RHS);
258dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
259dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
260a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencerptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
261a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  return Position - RHS.Position;
262a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer}
263a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
264d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef root_path(StringRef path) {
265dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator b = begin(path),
266dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 pos = b,
267dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 e = end(path);
268dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (b != e) {
269dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
270dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_drive =
271dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
272dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      b->endswith(":");
273dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
274dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      false;
275dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
276dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
277dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (has_net || has_drive) {
278dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      if ((++pos != e) && is_separator((*pos)[0])) {
279dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // {C:/,//net/}, so get the first two components.
2803ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer        return path.substr(0, b->size() + pos->size());
281dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      } else {
282dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // just {C:,//net}, return the first component.
2835029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer        return *b;
284dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      }
285dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
286dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
287dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // POSIX style root directory.
288dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (is_separator((*b)[0])) {
2895029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer      return *b;
290dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
291dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
292dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
2935029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return StringRef();
294dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
295dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
296d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef root_name(StringRef path) {
297dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator b = begin(path),
298dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 e = end(path);
299dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (b != e) {
300dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
301dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_drive =
302dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
303dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      b->endswith(":");
304dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
305dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      false;
306dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
307dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
308dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (has_net || has_drive) {
309dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // just {C:,//net}, return the first component.
3105029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer      return *b;
311dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
312dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
313dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
314dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // No path or no name.
3155029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return StringRef();
316dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
317dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
318d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef root_directory(StringRef path) {
319dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator b = begin(path),
320dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 pos = b,
321dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 e = end(path);
322dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (b != e) {
323dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
324dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_drive =
325dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
326dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      b->endswith(":");
327dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
328dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      false;
329dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
330dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
331dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if ((has_net || has_drive) &&
332dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // {C:,//net}, skip to the next component.
333dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        (++pos != e) && is_separator((*pos)[0])) {
3345029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer      return *pos;
335dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
336dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
337dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // POSIX style root directory.
338dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (!has_net && is_separator((*b)[0])) {
3395029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer      return *b;
340dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
341dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
342dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
343dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // No path or no root.
3445029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return StringRef();
345dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
346dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
347d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef relative_path(StringRef path) {
3485029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  StringRef root = root_path(path);
349d0fff1886cbace4e663761f2c26dc0a5eed2b6b1Michael J. Spencer  return path.substr(root.size());
350dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
351dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
352936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencervoid append(SmallVectorImpl<char> &path, const Twine &a,
353936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer                                         const Twine &b,
354936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer                                         const Twine &c,
355936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer                                         const Twine &d) {
356dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> a_storage;
357dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> b_storage;
358dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> c_storage;
359dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> d_storage;
360dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
361dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallVector<StringRef, 4> components;
362dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
363dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
364dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
365dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
366dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
367dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(),
368dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  e = components.end();
369dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  i != e; ++i) {
370dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
371dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool component_has_sep = !i->empty() && is_separator((*i)[0]);
3725029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    bool is_root_name = has_root_name(*i);
373dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
374dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path_has_sep) {
375dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Strip separators from beginning of component.
376dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      size_t loc = i->find_first_not_of(separators);
3773ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      StringRef c = i->substr(loc);
378dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
379dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Append it.
380dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      path.append(c.begin(), c.end());
381dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      continue;
382dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
383dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
384f150e7695e32d42856d86499fcde970825371637Michael J. Spencer    if (!component_has_sep && !(path.empty() || is_root_name)) {
385dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Add a separator.
386dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      path.push_back(prefered_separator);
387dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
388dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
389dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    path.append(i->begin(), i->end());
390dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
391dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
392dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
3936e31b9b8c36c6dc1ed2bf9d47d9e04f1af17d0f4Argyrios Kyrtzidisvoid append(SmallVectorImpl<char> &path,
3946e31b9b8c36c6dc1ed2bf9d47d9e04f1af17d0f4Argyrios Kyrtzidis            const_iterator begin, const_iterator end) {
3956e31b9b8c36c6dc1ed2bf9d47d9e04f1af17d0f4Argyrios Kyrtzidis  for (; begin != end; ++begin)
3966e31b9b8c36c6dc1ed2bf9d47d9e04f1af17d0f4Argyrios Kyrtzidis    path::append(path, *begin);
3976e31b9b8c36c6dc1ed2bf9d47d9e04f1af17d0f4Argyrios Kyrtzidis}
3986e31b9b8c36c6dc1ed2bf9d47d9e04f1af17d0f4Argyrios Kyrtzidis
399d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef parent_path(StringRef path) {
400a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t end_pos = parent_path_end(path);
401a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  if (end_pos == StringRef::npos)
4025029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    return StringRef();
403a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  else
4043ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer    return path.substr(0, end_pos);
405a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer}
406a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
407936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencervoid remove_filename(SmallVectorImpl<char> &path) {
408dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer  size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
409936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer  if (end_pos != StringRef::npos)
410936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path.set_size(end_pos);
411dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer}
412dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer
4135029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencervoid replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
41452ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  StringRef p(path.begin(), path.size());
41552ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  SmallString<32> ext_storage;
41652ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  StringRef ext = extension.toStringRef(ext_storage);
41752ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
41852ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  // Erase existing extension.
41952ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  size_t pos = p.find_last_of('.');
42052ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  if (pos != StringRef::npos && pos >= filename_pos(p))
42152ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer    path.set_size(pos);
42252ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
42352ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  // Append '.' if needed.
42452ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  if (ext.size() > 0 && ext[0] != '.')
42552ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer    path.push_back('.');
42652ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
42752ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  // Append extension.
42852ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  path.append(ext.begin(), ext.end());
42952ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer}
43052ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
431936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencervoid native(const Twine &path, SmallVectorImpl<char> &result) {
432722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  // Clear result.
433fbd1bbd7fa0ca592d09edea557806da05084a432Michael J. Spencer  result.clear();
434722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#ifdef LLVM_ON_WIN32
435722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  SmallString<128> path_storage;
436722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  StringRef p = path.toStringRef(path_storage);
437722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  result.reserve(p.size());
438722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  for (StringRef::const_iterator i = p.begin(),
439722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer                                 e = p.end();
440722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer                                 i != e;
441722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer                                 ++i) {
442722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer    if (*i == '/')
443722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer      result.push_back('\\');
444722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer    else
445722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer      result.push_back(*i);
446722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  }
447722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#else
448722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  path.toVector(result);
449722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#endif
450722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer}
451722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer
452d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef filename(StringRef path) {
4535029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return *(--end(path));
454a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer}
455a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer
456d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef stem(StringRef path) {
4575029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  StringRef fname = filename(path);
45834ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  size_t pos = fname.find_last_of('.');
45934ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  if (pos == StringRef::npos)
4605029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    return fname;
46134ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  else
46234ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer    if ((fname.size() == 1 && fname == ".") ||
46334ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer        (fname.size() == 2 && fname == ".."))
4645029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer      return fname;
46534ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer    else
4663ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      return fname.substr(0, pos);
46734ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer}
46834ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer
469d53f3c864bf94d158a2ae677fe92fd41afaec2f3Benjamin Kramerconst StringRef extension(StringRef path) {
4705029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  StringRef fname = filename(path);
4715265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer  size_t pos = fname.find_last_of('.');
4725265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer  if (pos == StringRef::npos)
4735029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    return StringRef();
4745265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer  else
4755265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer    if ((fname.size() == 1 && fname == ".") ||
4765265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer        (fname.size() == 2 && fname == ".."))
4775029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer      return StringRef();
4785265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer    else
4793ce88c92905c173e39e9ae29c53d0755504a76f6Benjamin Kramer      return fname.substr(pos);
4805265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer}
4815265f22f4558f376dece4744b3fe2ae1c637d223Michael J. Spencer
48263cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wanbool is_separator(char value) {
48363cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  switch(value) {
48463cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#ifdef LLVM_ON_WIN32
48563cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan    case '\\': // fall through
48663cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#endif
48763cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan    case '/': return true;
48863cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan    default: return false;
48963cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  }
49063cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan}
49163cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan
49255cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregorvoid system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
49355cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  result.clear();
494faebf11a3468767bb702b8e9fca98237f1d3a126Michael J. Spencer
49555cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  // Check whether the temporary directory is specified by an environment
49655cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  // variable.
49755cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  const char *EnvironmentVariable;
49855cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor#ifdef LLVM_ON_WIN32
49955cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  EnvironmentVariable = "TEMP";
50055cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor#else
50155cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  EnvironmentVariable = "TMPDIR";
50255cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor#endif
50355cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  if (char *RequestedDir = getenv(EnvironmentVariable)) {
50455cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor    result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
50555cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor    return;
50655cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  }
507faebf11a3468767bb702b8e9fca98237f1d3a126Michael J. Spencer
50855cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  // Fall back to a system default.
50955cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  const char *DefaultResult;
51055cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor#ifdef LLVM_ON_WIN32
51155cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  (void)erasedOnReboot;
512d26d6b68dd5ad6cea00331182d70432e4bac3393Douglas Gregor  DefaultResult = "C:\\TEMP";
51355cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor#else
51455cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  if (erasedOnReboot)
51555cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor    DefaultResult = "/tmp";
51655cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  else
51755cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor    DefaultResult = "/var/tmp";
51855cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor#endif
51955cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor  result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
52055cf815e19691d8a1cda40a331943ebfee9d7255Douglas Gregor}
521faebf11a3468767bb702b8e9fca98237f1d3a126Michael J. Spencer
52212ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool has_root_name(const Twine &path) {
523ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  SmallString<128> path_storage;
524ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
525ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5265029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !root_name(p).empty();
527ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer}
528ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
52912ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool has_root_directory(const Twine &path) {
530ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  SmallString<128> path_storage;
531ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
532ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5335029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !root_directory(p).empty();
534ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer}
535ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
53612ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool has_root_path(const Twine &path) {
537ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  SmallString<128> path_storage;
538ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
539ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5405029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !root_path(p).empty();
541ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer}
542ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5432d484eb88d82aa53db509fca14f36ebe8f108706Michael J. Spencerbool has_relative_path(const Twine &path) {
5442d484eb88d82aa53db509fca14f36ebe8f108706Michael J. Spencer  SmallString<128> path_storage;
5452d484eb88d82aa53db509fca14f36ebe8f108706Michael J. Spencer  StringRef p = path.toStringRef(path_storage);
5462d484eb88d82aa53db509fca14f36ebe8f108706Michael J. Spencer
5472d484eb88d82aa53db509fca14f36ebe8f108706Michael J. Spencer  return !relative_path(p).empty();
5482d484eb88d82aa53db509fca14f36ebe8f108706Michael J. Spencer}
5492d484eb88d82aa53db509fca14f36ebe8f108706Michael J. Spencer
55012ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool has_filename(const Twine &path) {
551ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  SmallString<128> path_storage;
552ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
553ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5545029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !filename(p).empty();
555ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer}
556ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
55712ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool has_parent_path(const Twine &path) {
558ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  SmallString<128> path_storage;
559ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
560ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5615029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !parent_path(p).empty();
562ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer}
563ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
56412ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool has_stem(const Twine &path) {
565ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  SmallString<128> path_storage;
566ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
567ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5685029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !stem(p).empty();
569ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer}
570ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
57112ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool has_extension(const Twine &path) {
572ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  SmallString<128> path_storage;
573ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
574ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
5755029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !extension(p).empty();
576ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer}
577ae18008584b5b38a44991bf7cdf02870f75c349aMichael J. Spencer
57812ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool is_absolute(const Twine &path) {
579ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer  SmallString<128> path_storage;
580ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
581ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer
5825029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  bool rootDir = has_root_directory(p),
583ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer#ifdef LLVM_ON_WIN32
5845029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer       rootName = has_root_name(p);
585ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer#else
5865029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer       rootName = true;
587ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer#endif
588ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer
5895029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return rootDir && rootName;
590ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer}
591ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer
59212ccf67457cddc7841bd23bae342994a21d25eb0Michael J. Spencerbool is_relative(const Twine &path) {
5935029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  return !is_absolute(path);
594ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer}
595ce2b68fb5444e712da14d214994c05bd231f221fMichael J. Spencer
596bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencer} // end namespace path
597bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencer
598bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencernamespace fs {
599bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencer
600ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencererror_code make_absolute(SmallVectorImpl<char> &path) {
601ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  StringRef p(path.data(), path.size());
602ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
603d1d721660edf3f4e76ea69fd5579f857b97a3150Daniel Dunbar  bool rootDirectory = path::has_root_directory(p),
604d1d721660edf3f4e76ea69fd5579f857b97a3150Daniel Dunbar#ifdef LLVM_ON_WIN32
60595fe7b9b7251d33ad4128603087edac70cec7c72Daniel Dunbar       rootName = path::has_root_name(p);
606d1d721660edf3f4e76ea69fd5579f857b97a3150Daniel Dunbar#else
607d1d721660edf3f4e76ea69fd5579f857b97a3150Daniel Dunbar       rootName = true;
608d1d721660edf3f4e76ea69fd5579f857b97a3150Daniel Dunbar#endif
609ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
610ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  // Already absolute.
611ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  if (rootName && rootDirectory)
61258604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie    return error_code::success();
613ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
614ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  // All of the following conditions will need the current directory.
615ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  SmallString<128> current_dir;
616ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  if (error_code ec = current_path(current_dir)) return ec;
617ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
618ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  // Relative path. Prepend the current directory.
619ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  if (!rootName && !rootDirectory) {
620ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    // Append path to the current directory.
621936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::append(current_dir, p);
622ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    // Set path to the result.
623ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    path.swap(current_dir);
62458604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie    return error_code::success();
625ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  }
626ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
627ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  if (!rootName && rootDirectory) {
6285029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    StringRef cdrn = path::root_name(current_dir);
629ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
630936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::append(curDirRootName, p);
631ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    // Set path to the result.
632ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    path.swap(curDirRootName);
63358604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie    return error_code::success();
634ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  }
635ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
636ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  if (rootName && !rootDirectory) {
6375029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    StringRef pRootName      = path::root_name(p);
6385029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    StringRef bRootDirectory = path::root_directory(current_dir);
6395029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    StringRef bRelativePath  = path::relative_path(current_dir);
6405029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    StringRef pRelativePath  = path::relative_path(p);
641ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
642ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    SmallString<128> res;
643936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
644ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer    path.swap(res);
64558604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie    return error_code::success();
646ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  }
647ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
648ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer  llvm_unreachable("All rootName and rootDirectory combinations should have "
649ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer                   "occurred above!");
650ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer}
651ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer
652b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencererror_code create_directories(const Twine &path, bool &existed) {
653b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencer  SmallString<128> path_storage;
654b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
655b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencer
6565029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer  StringRef parent = path::parent_path(p);
65755f43d6b7e3ad1f08f5392205ab0feabf4c9933dMichael J. Spencer  if (!parent.empty()) {
65855f43d6b7e3ad1f08f5392205ab0feabf4c9933dMichael J. Spencer    bool parent_exists;
65955f43d6b7e3ad1f08f5392205ab0feabf4c9933dMichael J. Spencer    if (error_code ec = fs::exists(parent, parent_exists)) return ec;
6605029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer
66155f43d6b7e3ad1f08f5392205ab0feabf4c9933dMichael J. Spencer    if (!parent_exists)
66255f43d6b7e3ad1f08f5392205ab0feabf4c9933dMichael J. Spencer      if (error_code ec = create_directories(parent, existed)) return ec;
66355f43d6b7e3ad1f08f5392205ab0feabf4c9933dMichael J. Spencer  }
664b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencer
665b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencer  return create_directory(p, existed);
666b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencer}
667b83769f36afe5221ca6aa7741561801836a179cbMichael J. Spencer
66861187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencerbool exists(file_status status) {
66961187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer  return status_known(status) && status.type() != file_type::file_not_found;
67061187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer}
67161187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer
67261187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencerbool status_known(file_status s) {
67361187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer  return s.type() != file_type::status_error;
67461187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer}
67561187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer
67661187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencerbool is_directory(file_status status) {
67761187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer  return status.type() == file_type::directory_file;
67861187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer}
67961187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer
680218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencererror_code is_directory(const Twine &path, bool &result) {
681218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer  file_status st;
682218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer  if (error_code ec = status(path, st))
683218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer    return ec;
684218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer  result = is_directory(st);
68558604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie  return error_code::success();
686218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer}
687218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer
68861187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencerbool is_regular_file(file_status status) {
68961187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer  return status.type() == file_type::regular_file;
69061187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer}
69161187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer
692218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencererror_code is_regular_file(const Twine &path, bool &result) {
693218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer  file_status st;
694218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer  if (error_code ec = status(path, st))
695218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer    return ec;
696218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer  result = is_regular_file(st);
69758604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie  return error_code::success();
698218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer}
699218dc3e2fe54c28b0292a3e89c5ed6563f62ac23Michael J. Spencer
70061187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencerbool is_symlink(file_status status) {
70161187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer  return status.type() == file_type::symlink_file;
70261187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer}
70361187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer
7049df536ca7873af6dd9d9ca4aa6cea2872de5c028Michael J. Spencererror_code is_symlink(const Twine &path, bool &result) {
7059df536ca7873af6dd9d9ca4aa6cea2872de5c028Michael J. Spencer  file_status st;
7069df536ca7873af6dd9d9ca4aa6cea2872de5c028Michael J. Spencer  if (error_code ec = status(path, st))
7079df536ca7873af6dd9d9ca4aa6cea2872de5c028Michael J. Spencer    return ec;
7089df536ca7873af6dd9d9ca4aa6cea2872de5c028Michael J. Spencer  result = is_symlink(st);
70958604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie  return error_code::success();
7109df536ca7873af6dd9d9ca4aa6cea2872de5c028Michael J. Spencer}
7119df536ca7873af6dd9d9ca4aa6cea2872de5c028Michael J. Spencer
71261187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencerbool is_other(file_status status) {
71361187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer  return exists(status) &&
71461187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer         !is_regular_file(status) &&
71561187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer         !is_directory(status) &&
71661187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer         !is_symlink(status);
71761187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer}
71861187dd0ad3d8574f655074e3e7948193d90bb1eMichael J. Spencer
719357b5718411c4a15427d69590651fb8103ae7ba9Benjamin Kramervoid directory_entry::replace_filename(const Twine &filename, file_status st) {
720753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  SmallString<128> path(Path.begin(), Path.end());
721753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  path::remove_filename(path);
722753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  path::append(path, filename);
723753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  Path = path.str();
724753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  Status = st;
725753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer}
726753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer
727628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencererror_code has_magic(const Twine &path, const Twine &magic, bool &result) {
728628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer  SmallString<32>  MagicStorage;
729b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer  StringRef Magic = magic.toStringRef(MagicStorage);
730b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer  SmallString<32> Buffer;
731b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer
732b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer  if (error_code ec = get_magic(path, Magic.size(), Buffer)) {
733b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer    if (ec == errc::value_too_large) {
734b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer      // Magic.size() > file_size(Path).
735628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer      result = false;
73658604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie      return error_code::success();
737628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer    }
738b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer    return ec;
739628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer  }
740628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer
741b33594be3de0e73e0b79f5d9827228d58eef62faMichael J. Spencer  result = Magic == Buffer;
74258604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie  return error_code::success();
743628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer}
744628467ef1f230e40ee00626ddfdcc7ca77b45a11Michael J. Spencer
7455b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer/// @brief Identify the magic in magic.
7465b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencerfile_magic identify_magic(StringRef magic) {
747b51c8e9bb5769ed17261392ff4222ad3a6668285Michael J. Spencer  if (magic.size() < 4)
748b51c8e9bb5769ed17261392ff4222ad3a6668285Michael J. Spencer    return file_magic::unknown;
7495b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  switch ((unsigned char)magic[0]) {
7505b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0xDE:  // 0x0B17C0DE = BC wraper
7515b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == (char)0xC0 && magic[2] == (char)0x17 &&
7525b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          magic[3] == (char)0x0B)
7535b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        return file_magic::bitcode;
7545b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
7555b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 'B':
7565b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE)
7575b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        return file_magic::bitcode;
7585b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
7595b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case '!':
7605b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic.size() >= 8)
7615b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        if (memcmp(magic.data(),"!<arch>\n",8) == 0)
7625b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          return file_magic::archive;
7635b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
7645b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
7655b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case '\177':
7665b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') {
7675b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        if (magic.size() >= 18 && magic[17] == 0)
7685b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          switch (magic[16]) {
7695b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer            default: break;
7705b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer            case 1: return file_magic::elf_relocatable;
7715b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer            case 2: return file_magic::elf_executable;
7725b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer            case 3: return file_magic::elf_shared_object;
7735b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer            case 4: return file_magic::elf_core;
7745b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          }
7755b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      }
7765b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
7775b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
7785b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0xCA:
7795b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == char(0xFE) && magic[2] == char(0xBA) &&
7805b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          magic[3] == char(0xBE)) {
7815b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        // This is complicated by an overlap with Java class files.
7825b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        // See the Mach-O section in /usr/share/file/magic for details.
7835b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        if (magic.size() >= 8 && magic[7] < 43)
7845b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          // FIXME: Universal Binary of any type.
7855b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          return file_magic::macho_dynamically_linked_shared_lib;
7865b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      }
7875b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
7885b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
7895b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      // The two magic numbers for mach-o are:
7905b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      // 0xfeedface - 32-bit mach-o
7915b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      // 0xfeedfacf - 64-bit mach-o
7925b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0xFE:
7935b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0xCE:
7945b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0xCF: {
7955b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      uint16_t type = 0;
7965b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[0] == char(0xFE) && magic[1] == char(0xED) &&
7975b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          magic[2] == char(0xFA) &&
7985b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          (magic[3] == char(0xCE) || magic[3] == char(0xCF))) {
7995b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        /* Native endian */
8005b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        if (magic.size() >= 16) type = magic[14] << 8 | magic[15];
8015b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      } else if ((magic[0] == char(0xCE) || magic[0] == char(0xCF)) &&
8025b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer                 magic[1] == char(0xFA) && magic[2] == char(0xED) &&
8035b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer                 magic[3] == char(0xFE)) {
8045b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        /* Reverse endian */
8055b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        if (magic.size() >= 14) type = magic[13] << 8 | magic[12];
8065b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      }
8075b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      switch (type) {
8085b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        default: break;
8095b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 1: return file_magic::macho_object;
8105b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 2: return file_magic::macho_executable;
8115b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
8125b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 4: return file_magic::macho_core;
8135b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 5: return file_magic::macho_preload_executabl;
8145b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 6: return file_magic::macho_dynamically_linked_shared_lib;
8155b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 7: return file_magic::macho_dynamic_linker;
8165b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 8: return file_magic::macho_bundle;
8175b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 9: return file_magic::macho_dynamic_linker;
8185b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        case 10: return file_magic::macho_dsym_companion;
8195b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      }
8205b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
8215b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    }
8225b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0xF0: // PowerPC Windows
8235b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x83: // Alpha 32-bit
8245b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x84: // Alpha 64-bit
8255b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x66: // MPS R4000 Windows
8265b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x50: // mc68K
8275b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x4c: // 80386 Windows
8285b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == 0x01)
8295b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        return file_magic::coff_object;
8305b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
8315b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x90: // PA-RISC Windows
8325b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x68: // mc68K Windows
8335b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == 0x02)
8345b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        return file_magic::coff_object;
8355b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
8365b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
8375b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x4d: // Possible MS-DOS stub on Windows PE file
8385b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == 0x5a) {
8395b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        uint32_t off =
8405b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          *reinterpret_cast<const support::ulittle32_t*>(magic.data() + 0x3c);
8415b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        // PE/COFF file, either EXE or DLL.
8425b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        if (off < magic.size() && memcmp(magic.data() + off, "PE\0\0",4) == 0)
8435b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer          return file_magic::pecoff_executable;
8445b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      }
8455b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
8465b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
8475b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case 0x64: // x86-64 Windows.
8485b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      if (magic[1] == char(0x86))
8495b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer        return file_magic::coff_object;
8505b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
8515b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
8525b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    default:
8535b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer      break;
8545b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  }
8555b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  return file_magic::unknown;
8565b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer}
8575b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer
8585b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencererror_code identify_magic(const Twine &path, file_magic &result) {
85928f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  SmallString<32> Magic;
86028f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  error_code ec = get_magic(path, Magic.capacity(), Magic);
86128f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  if (ec && ec != errc::value_too_large)
86228f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer    return ec;
86328f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer
8645b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  result = identify_magic(Magic);
86558604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie  return error_code::success();
86628f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer}
86728f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer
8687fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencernamespace {
8697fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencererror_code remove_all_r(StringRef path, file_type ft, uint32_t &count) {
8707fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  if (ft == file_type::directory_file) {
8717fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    // This code would be a lot better with exceptions ;/.
8727fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    error_code ec;
8731dd2ee7bf4d848e368829cb01033f297afb674abMichael J. Spencer    directory_iterator i(path, ec);
8741dd2ee7bf4d848e368829cb01033f297afb674abMichael J. Spencer    if (ec) return ec;
8751dd2ee7bf4d848e368829cb01033f297afb674abMichael J. Spencer    for (directory_iterator e; i != e; i.increment(ec)) {
8767fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer      if (ec) return ec;
8777fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer      file_status st;
8787fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer      if (error_code ec = i->status(st)) return ec;
8797fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer      if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec;
8807fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    }
8817fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    bool obviously_this_exists;
8827fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    if (error_code ec = remove(path, obviously_this_exists)) return ec;
8837fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    assert(obviously_this_exists);
8847fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    ++count; // Include the directory itself in the items removed.
8857fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  } else {
8867fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    bool obviously_this_exists;
8877fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    if (error_code ec = remove(path, obviously_this_exists)) return ec;
8887fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    assert(obviously_this_exists);
8897fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    ++count;
8907fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  }
8917fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer
89258604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie  return error_code::success();
8937fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer}
89463cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan} // end unnamed namespace
8957fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer
8967fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencererror_code remove_all(const Twine &path, uint32_t &num_removed) {
8977fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  SmallString<128> path_storage;
8987fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  StringRef p = path.toStringRef(path_storage);
8997fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer
9007fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  file_status fs;
9017fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  if (error_code ec = status(path, fs))
9027fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer    return ec;
9037fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  num_removed = 0;
9047fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer  return remove_all_r(p, fs.type(), num_removed);
9057fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer}
9067fd682aaf2ceeb953da190a2add326963ff45c3eMichael J. Spencer
9075bcdc7f7c4f1b5aa053b07a4b2ea95b750ed1715Michael J. Spencererror_code directory_entry::status(file_status &result) const {
9085bcdc7f7c4f1b5aa053b07a4b2ea95b750ed1715Michael J. Spencer  return fs::status(Path, result);
9095bcdc7f7c4f1b5aa053b07a4b2ea95b750ed1715Michael J. Spencer}
9105bcdc7f7c4f1b5aa053b07a4b2ea95b750ed1715Michael J. Spencer
911bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencer} // end namespace fs
912bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencer} // end namespace sys
913bee0c38f595f52d424161dc1db9c0bfe61421957Michael J. Spencer} // end namespace llvm
914dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
915dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// Include the truly platform-specific parts.
916dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#if defined(LLVM_ON_UNIX)
917dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "Unix/PathV2.inc"
918dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
919dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#if defined(LLVM_ON_WIN32)
920dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "Windows/PathV2.inc"
921dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
922