PathV2.cpp revision 34ab1f6087bc0da1df0e3a73ac99762ef070d419
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"
15dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "llvm/Support/ErrorHandling.h"
16dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include <cctype>
17dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
18dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace {
19dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  using llvm::StringRef;
20dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
21dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  bool is_separator(const char value) {
22dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    switch(value) {
23dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
24dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    case '\\': // fall through
25dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
26dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    case '/': return true;
27dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    default: return false;
28dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
29dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
30dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
31dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
32dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const StringRef separators = "\\/";
33dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const char       prefered_separator = '\\';
34dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
35dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const StringRef separators = "/";
36dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const char      prefered_separator = '/';
37dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
38dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
39dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  StringRef find_first_component(const StringRef  &path) {
40dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Look for this first component in the following order.
41dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * empty (in this case we return an empty string)
42dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * either C: or {//,\\}net.
43dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {/,\}
44dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {.,..}
45dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {file,directory}name
46dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
47dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path.empty())
48dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return path;
49dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
50dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // C:
51dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path.size() >= 2 && std::isalpha(path[0]) && path[1] == ':')
52dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return StringRef(path.begin(), 2);
53dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
54dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // //net
55dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if ((path.size() > 2) &&
56dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        (path.startswith("\\\\") || path.startswith("//")) &&
57dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        (path[2] != '\\' && path[2] != '/')) {
58dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Find the next directory separator.
59dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      size_t end = path.find_first_of("\\/", 2);
60dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      if (end == StringRef::npos)
61dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        return path;
62dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      else
63dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        return StringRef(path.begin(), end);
64dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
65dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
66dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // {/,\}
67dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path[0] == '\\' || path[0] == '/')
68dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return StringRef(path.begin(), 1);
69dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
70dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path.startswith(".."))
71dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return StringRef(path.begin(), 2);
72dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
73dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path[0] == '.')
74dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return StringRef(path.begin(), 1);
75dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
76dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // * {file,directory}name
77dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    size_t end = path.find_first_of("\\/", 2);
78dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (end == StringRef::npos)
79dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return path;
80dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    else
81dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return StringRef(path.begin(), end);
82dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
83dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return StringRef();
84dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
85a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
86a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t filename_pos(const StringRef &str) {
87a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() == 2 &&
88a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[0]) &&
89a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[1]))
90a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 0;
91a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
92a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 0 && is_separator(str[str.size() - 1]))
93a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return str.size() - 1;
94a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
95a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    size_t pos = str.find_last_of(separators, str.size() - 1);
96a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
97a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32
98a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (pos == StringRef::npos)
99a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      pos = str.find_last_of(':', str.size() - 2);
100a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif
101a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
102a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (pos == StringRef::npos ||
103a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        (pos == 1 && is_separator(str[0])))
104a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 0;
105a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
106a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return pos + 1;
107a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
108a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
109a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t root_dir_start(const StringRef &str) {
110a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "c:/"
111a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32
112a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 2 &&
113a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        str[1] == ':' &&
114a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[2]))
115a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 2;
116a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif
117a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
118a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "//"
119a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() == 2 &&
120a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[0]) &&
121a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        str[0] == str[1])
122a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return StringRef::npos;
123a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
124a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "//net"
125a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 3 &&
126a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(str[0]) &&
127a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        str[0] == str[1] &&
128a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        !is_separator(str[2])) {
129a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return str.find_first_of(separators, 2);
130a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    }
131a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
132a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // case "/"
133a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (str.size() > 0 && is_separator(str[0]))
134a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return 0;
135a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
136a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return StringRef::npos;
137a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
138a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
139a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t parent_path_end(const StringRef &path) {
140a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    size_t end_pos = filename_pos(path);
141a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
142a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
143a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
144a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    // Skip separators except for root dir.
145a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    size_t root_dir_pos = root_dir_start(StringRef(path.begin(), end_pos));
146a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
147a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    while(end_pos > 0 &&
148a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer          (end_pos - 1) != root_dir_pos &&
149a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer          is_separator(path[end_pos - 1]))
150a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      --end_pos;
151a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
152a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
153a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      return StringRef::npos;
154a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
155a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return end_pos;
156a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
157dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
158dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
159dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace llvm {
160dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace sys  {
161dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace path {
162dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
163dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerconst_iterator begin(const StringRef &path) {
164dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator i;
165dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Path      = path;
166dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Component = find_first_component(path);
167dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Position  = 0;
168dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return i;
169dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
170dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
171dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerconst_iterator end(const StringRef &path) {
172dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator i;
173dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Path      = path;
174dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  i.Position  = path.size();
175dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return i;
176dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
177dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
178dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerconst_iterator &const_iterator::operator++() {
179dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  assert(Position < Path.size() && "Tried to increment past end!");
180dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
181dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Increment Position to past the current component
182dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  Position += Component.size();
183dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
184dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Check for end.
185dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (Position == Path.size()) {
186dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    Component = StringRef();
187dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return *this;
188dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
189dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
190dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Both POSIX and Windows treat paths that begin with exactly two separators
191dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // specially.
192dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  bool was_net = Component.size() > 2 &&
193dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    is_separator(Component[0]) &&
194dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    Component[1] == Component[0] &&
195dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    !is_separator(Component[2]);
196dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
197dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Handle separators.
198dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (is_separator(Path[Position])) {
199dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Root dir.
200dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (was_net
201dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
202dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // c:/
203dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        || Component.endswith(":")
204dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
205dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        ) {
206dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      Component = StringRef(Path.begin() + Position, 1);
207dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return *this;
208dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
209dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
210dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Skip extra separators.
211dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    while (Position != Path.size() &&
212dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer           is_separator(Path[Position])) {
213dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      ++Position;
214dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
215dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
216dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Treat trailing '/' as a '.'.
217dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (Position == Path.size()) {
218dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      --Position;
219dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      Component = ".";
220dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return *this;
221dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
222dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
223dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
224dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Find next component.
225dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  size_t end_pos = Path.find_first_of(separators, Position);
226dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (end_pos == StringRef::npos)
227dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    end_pos = Path.size();
228dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  Component = StringRef(Path.begin() + Position, end_pos - Position);
229dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
230dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return *this;
231dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
232dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
233a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencerconst_iterator &const_iterator::operator--() {
234a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  // If we're at the end and the previous char was a '/', return '.'.
235a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  if (Position == Path.size() &&
236a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      Path.size() > 1 &&
237a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      is_separator(Path[Position - 1])
238a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32
239a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      && Path[Position - 2] != ':'
240a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif
241a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      ) {
242a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    --Position;
243a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    Component = ".";
244a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    return *this;
245a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  }
246a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
247a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  // Skip separators unless it's the root directory.
248a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t root_dir_pos = root_dir_start(Path);
249a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t end_pos = Position;
250a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
251a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  while(end_pos > 0 &&
252a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        (end_pos - 1) != root_dir_pos &&
253a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer        is_separator(Path[end_pos - 1]))
254a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    --end_pos;
255a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
256a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  // Find next separator.
257a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t start_pos = filename_pos(StringRef(Path.begin(), end_pos));
258a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  Component = StringRef(Path.begin() + start_pos, end_pos - start_pos);
259a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  Position = start_pos;
260a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  return *this;
261a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer}
262a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
263dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerbool const_iterator::operator==(const const_iterator &RHS) const {
264dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return Path.begin() == RHS.Path.begin() &&
265dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer         Position == RHS.Position;
266dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
267dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
268dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerbool const_iterator::operator!=(const const_iterator &RHS) const {
269dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return !(*this == RHS);
270dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
271dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
272a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencerptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
273a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  return Position - RHS.Position;
274a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer}
275a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
276dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code root_path(const StringRef &path, StringRef &result) {
277dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator b = begin(path),
278dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 pos = b,
279dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 e = end(path);
280dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (b != e) {
281dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
282dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_drive =
283dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
284dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      b->endswith(":");
285dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
286dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      false;
287dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
288dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
289dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (has_net || has_drive) {
290dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      if ((++pos != e) && is_separator((*pos)[0])) {
291dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // {C:/,//net/}, so get the first two components.
292dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        result = StringRef(path.begin(), b->size() + pos->size());
293dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        return make_error_code(errc::success);
294dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      } else {
295dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // just {C:,//net}, return the first component.
296dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        result = *b;
297dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        return make_error_code(errc::success);
298dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      }
299dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
300dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
301dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // POSIX style root directory.
302dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (is_separator((*b)[0])) {
303dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      result = *b;
304dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return make_error_code(errc::success);
305dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
306dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
307dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // No root_path.
308dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    result = StringRef();
309dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return make_error_code(errc::success);
310dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
311dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
312dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // No path :(.
313dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  result = StringRef();
314dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return make_error_code(errc::success);
315dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
316dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
317dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code root_name(const StringRef &path, StringRef &result) {
318dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator b = begin(path),
319dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 e = end(path);
320dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (b != e) {
321dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
322dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_drive =
323dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
324dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      b->endswith(":");
325dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
326dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      false;
327dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
328dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
329dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (has_net || has_drive) {
330dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // just {C:,//net}, return the first component.
331dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      result = *b;
332dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return make_error_code(errc::success);
333dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
334dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
335dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
336dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // No path or no name.
337dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  result = StringRef();
338dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return make_error_code(errc::success);
339dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
340dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
341dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code root_directory(const StringRef &path, StringRef &result) {
342dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  const_iterator b = begin(path),
343dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 pos = b,
344dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                 e = end(path);
345dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (b != e) {
346dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
347dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool has_drive =
348dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32
349dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      b->endswith(":");
350dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else
351dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      false;
352dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
353dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
354dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if ((has_net || has_drive) &&
355dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        // {C:,//net}, skip to the next component.
356dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer        (++pos != e) && is_separator((*pos)[0])) {
357dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      result = *pos;
358dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return make_error_code(errc::success);
359dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
360dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
361dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // POSIX style root directory.
362dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (!has_net && is_separator((*b)[0])) {
363dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      result = *b;
364dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      return make_error_code(errc::success);
365dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
366dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
367dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
368dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // No path or no root.
369dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  result = StringRef();
370dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return make_error_code(errc::success);
371dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
372dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
373dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code has_root_name(const Twine &path, bool &result) {
374dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<128> storage;
375dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  StringRef p = path.toStringRef(storage);
376dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
377dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (error_code ec = root_name(p, p)) return ec;
378dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  result = !p.empty();
379dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return make_error_code(errc::success);
380dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
381dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
382dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code has_root_directory(const Twine &path, bool &result) {
383dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<128> storage;
384dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  StringRef p = path.toStringRef(storage);
385dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
386dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (error_code ec = root_directory(p, p)) return ec;
387dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  result = !p.empty();
388dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return make_error_code(errc::success);
389dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
390dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
391dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code relative_path(const StringRef &path, StringRef &result) {
392dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  StringRef root;
393dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (error_code ec = root_path(path, root)) return ec;
394dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  result = StringRef(path.begin() + root.size(), path.size() - root.size());
395dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return make_error_code(errc::success);
396dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
397dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
398dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code append(SmallVectorImpl<char> &path, const Twine &a,
399dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                               const Twine &b,
400dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                               const Twine &c,
401dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                               const Twine &d) {
402dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> a_storage;
403dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> b_storage;
404dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> c_storage;
405dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<32> d_storage;
406dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
407dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallVector<StringRef, 4> components;
408dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
409dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
410dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
411dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
412dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
413dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(),
414dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  e = components.end();
415dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  i != e; ++i) {
416dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
417dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool component_has_sep = !i->empty() && is_separator((*i)[0]);
418dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    bool is_root_name;
419dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = has_root_name(*i, is_root_name)) return ec;
420dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
421dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (path_has_sep) {
422dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Strip separators from beginning of component.
423dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      size_t loc = i->find_first_not_of(separators);
424dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      StringRef c = StringRef(i->begin() + loc, i->size() - loc);
425dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
426dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Append it.
427dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      path.append(c.begin(), c.end());
428dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      continue;
429dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
430dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
431dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (!component_has_sep && !(path.empty() && is_root_name)) {
432dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      // Add a separator.
433dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer      path.push_back(prefered_separator);
434dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
435dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
436dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    path.append(i->begin(), i->end());
437dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
438dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
439dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  return make_error_code(errc::success);
440dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
441dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
442dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code make_absolute(SmallVectorImpl<char> &path) {
443dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  StringRef p(path.data(), path.size());
444dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
445dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  bool rootName, rootDirectory;
446dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (error_code ec = has_root_name(p, rootName)) return ec;
447dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (error_code ec = has_root_directory(p, rootDirectory)) return ec;
448dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
449dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Already absolute.
450dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (rootName && rootDirectory)
451dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return make_error_code(errc::success);
452dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
453dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // All of the following conditions will need the current directory.
454dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallString<128> current_dir;
455dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (error_code ec = current_path(current_dir)) return ec;
456dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
457dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  // Relative path. Prepend the current directory.
458dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!rootName && !rootDirectory) {
459dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Append path to the current directory.
460dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = append(current_dir, p)) return ec;
461dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Set path to the result.
462dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    path.swap(current_dir);
463dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return make_error_code(errc::success);
464dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
465dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
466dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (!rootName && rootDirectory) {
467dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    StringRef cdrn;
468dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = root_name(current_dir, cdrn)) return ec;
469dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
470dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = append(curDirRootName, p)) return ec;
471dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    // Set path to the result.
472dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    path.swap(curDirRootName);
473dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return make_error_code(errc::success);
474dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
475dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
476dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  if (rootName && !rootDirectory) {
477dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    StringRef pRootName;
478dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    StringRef bRootDirectory;
479dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    StringRef bRelativePath;
480dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    StringRef pRelativePath;
481dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = root_name(p, pRootName)) return ec;
482dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = root_directory(current_dir, bRootDirectory)) return ec;
483dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = relative_path(current_dir, bRelativePath)) return ec;
484dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = relative_path(p, pRelativePath)) return ec;
485dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
486dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    SmallString<128> res;
487dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    if (error_code ec = append(res, pRootName, bRootDirectory,
488dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                    bRelativePath, pRelativePath)) return ec;
489dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    path.swap(res);
490dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    return make_error_code(errc::success);
491dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
492dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
493dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  llvm_unreachable("All rootName and rootDirectory combinations should have "
494dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                   "occurred above!");
495dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
496dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
497a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencererror_code parent_path(const StringRef &path, StringRef &result) {
498a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  size_t end_pos = parent_path_end(path);
499a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  if (end_pos == StringRef::npos)
500a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    result = StringRef();
501a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  else
502a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    result = StringRef(path.data(), end_pos);
503a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer  return make_error_code(errc::success);
504a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer}
505a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
506dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencererror_code remove_filename(SmallVectorImpl<char> &path) {
507dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer  size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
508dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer  if (end_pos == StringRef::npos)
509dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer    return make_error_code(errc::success);
510dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer  path.set_size(end_pos);
511dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer  return make_error_code(errc::success);
512dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer}
513dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer
51452ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencererror_code replace_extension(SmallVectorImpl<char> &path,
51552ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer                             const Twine &extension) {
51652ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  StringRef p(path.begin(), path.size());
51752ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  SmallString<32> ext_storage;
51852ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  StringRef ext = extension.toStringRef(ext_storage);
51952ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
52052ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  // Erase existing extension.
52152ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  size_t pos = p.find_last_of('.');
52252ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  if (pos != StringRef::npos && pos >= filename_pos(p))
52352ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer    path.set_size(pos);
52452ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
52552ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  // Append '.' if needed.
52652ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  if (ext.size() > 0 && ext[0] != '.')
52752ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer    path.push_back('.');
52852ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
52952ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  // Append extension.
53052ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  path.append(ext.begin(), ext.end());
53152ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer  return make_error_code(errc::success);
53252ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer}
53352ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer
534722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencererror_code native(const Twine &path, SmallVectorImpl<char> &result) {
535722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  // Clear result.
536722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  result.set_size(0);
537722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#ifdef LLVM_ON_WIN32
538722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  SmallString<128> path_storage;
539722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  StringRef p = path.toStringRef(path_storage);
540722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  result.reserve(p.size());
541722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  for (StringRef::const_iterator i = p.begin(),
542722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer                                 e = p.end();
543722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer                                 i != e;
544722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer                                 ++i) {
545722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer    if (*i == '/')
546722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer      result.push_back('\\');
547722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer    else
548722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer      result.push_back(*i);
549722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  }
550722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#else
551722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  path.toVector(result);
552722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#endif
553722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer  return make_error_code(errc::success);
554722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer}
555722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer
556a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencererror_code filename(const StringRef &path, StringRef &result) {
557a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer  result = *(--end(path));
558a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer  return make_error_code(errc::success);
559a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer}
560a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer
56134ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencererror_code stem(const StringRef &path, StringRef &result) {
56234ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  StringRef fname;
56334ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  if (error_code ec = filename(path, fname)) return ec;
56434ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  size_t pos = fname.find_last_of('.');
56534ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  if (pos == StringRef::npos)
56634ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer    result = fname;
56734ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  else
56834ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer    if ((fname.size() == 1 && fname == ".") ||
56934ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer        (fname.size() == 2 && fname == ".."))
57034ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer      result = fname;
57134ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer    else
57234ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer      result = StringRef(fname.begin(), pos);
57334ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer
57434ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer  return make_error_code(errc::success);
57534ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer}
57634ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer
577dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
578dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
579dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer}
580dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
581dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// Include the truly platform-specific parts.
582dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#if defined(LLVM_ON_UNIX)
583dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "Unix/PathV2.inc"
584dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
585dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#if defined(LLVM_ON_WIN32)
586dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "Windows/PathV2.inc"
587dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif
588