LLVM  4.0.0
Path.cpp
Go to the documentation of this file.
1 //===-- Path.cpp - Implement OS Path Concept ------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the operating system Path API.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Support/COFF.h"
15 #include "llvm/Support/MachO.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/Errc.h"
20 #include "llvm/Support/Path.h"
21 #include "llvm/Support/Process.h"
22 #include <cctype>
23 #include <cstring>
24 
25 #if !defined(_MSC_VER) && !defined(__MINGW32__)
26 #include <unistd.h>
27 #else
28 #include <io.h>
29 #endif
30 
31 using namespace llvm;
32 using namespace llvm::support::endian;
33 
34 namespace {
35  using llvm::StringRef;
37 
38 #ifdef LLVM_ON_WIN32
39  const char *separators = "\\/";
40  const char preferred_separator = '\\';
41 #else
42  const char separators = '/';
43  const char preferred_separator = '/';
44 #endif
45 
46  StringRef find_first_component(StringRef path) {
47  // Look for this first component in the following order.
48  // * empty (in this case we return an empty string)
49  // * either C: or {//,\\}net.
50  // * {/,\}
51  // * {file,directory}name
52 
53  if (path.empty())
54  return path;
55 
56 #ifdef LLVM_ON_WIN32
57  // C:
58  if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
59  path[1] == ':')
60  return path.substr(0, 2);
61 #endif
62 
63  // //net
64  if ((path.size() > 2) &&
65  is_separator(path[0]) &&
66  path[0] == path[1] &&
67  !is_separator(path[2])) {
68  // Find the next directory separator.
69  size_t end = path.find_first_of(separators, 2);
70  return path.substr(0, end);
71  }
72 
73  // {/,\}
74  if (is_separator(path[0]))
75  return path.substr(0, 1);
76 
77  // * {file,directory}name
78  size_t end = path.find_first_of(separators);
79  return path.substr(0, end);
80  }
81 
82  size_t filename_pos(StringRef str) {
83  if (str.size() == 2 &&
84  is_separator(str[0]) &&
85  str[0] == str[1])
86  return 0;
87 
88  if (str.size() > 0 && is_separator(str[str.size() - 1]))
89  return str.size() - 1;
90 
91  size_t pos = str.find_last_of(separators, str.size() - 1);
92 
93 #ifdef LLVM_ON_WIN32
94  if (pos == StringRef::npos)
95  pos = str.find_last_of(':', str.size() - 2);
96 #endif
97 
98  if (pos == StringRef::npos ||
99  (pos == 1 && is_separator(str[0])))
100  return 0;
101 
102  return pos + 1;
103  }
104 
105  size_t root_dir_start(StringRef str) {
106  // case "c:/"
107 #ifdef LLVM_ON_WIN32
108  if (str.size() > 2 &&
109  str[1] == ':' &&
110  is_separator(str[2]))
111  return 2;
112 #endif
113 
114  // case "//"
115  if (str.size() == 2 &&
116  is_separator(str[0]) &&
117  str[0] == str[1])
118  return StringRef::npos;
119 
120  // case "//net"
121  if (str.size() > 3 &&
122  is_separator(str[0]) &&
123  str[0] == str[1] &&
124  !is_separator(str[2])) {
125  return str.find_first_of(separators, 2);
126  }
127 
128  // case "/"
129  if (str.size() > 0 && is_separator(str[0]))
130  return 0;
131 
132  return StringRef::npos;
133  }
134 
135  size_t parent_path_end(StringRef path) {
136  size_t end_pos = filename_pos(path);
137 
138  bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
139 
140  // Skip separators except for root dir.
141  size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
142 
143  while(end_pos > 0 &&
144  (end_pos - 1) != root_dir_pos &&
145  is_separator(path[end_pos - 1]))
146  --end_pos;
147 
148  if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
149  return StringRef::npos;
150 
151  return end_pos;
152  }
153 } // end unnamed namespace
154 
155 enum FSEntity {
159 };
160 
161 static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
162  SmallVectorImpl<char> &ResultPath,
163  bool MakeAbsolute, unsigned Mode,
164  FSEntity Type) {
165  SmallString<128> ModelStorage;
166  Model.toVector(ModelStorage);
167 
168  if (MakeAbsolute) {
169  // Make model absolute by prepending a temp directory if it's not already.
170  if (!sys::path::is_absolute(Twine(ModelStorage))) {
171  SmallString<128> TDir;
173  sys::path::append(TDir, Twine(ModelStorage));
174  ModelStorage.swap(TDir);
175  }
176  }
177 
178  // From here on, DO NOT modify model. It may be needed if the randomly chosen
179  // path already exists.
180  ResultPath = ModelStorage;
181  // Null terminate.
182  ResultPath.push_back(0);
183  ResultPath.pop_back();
184 
185 retry_random_path:
186  // Replace '%' with random chars.
187  for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
188  if (ModelStorage[i] == '%')
189  ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
190  }
191 
192  // Try to open + create the file.
193  switch (Type) {
194  case FS_File: {
195  if (std::error_code EC =
196  sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
197  sys::fs::F_RW | sys::fs::F_Excl, Mode)) {
198  if (EC == errc::file_exists)
199  goto retry_random_path;
200  return EC;
201  }
202 
203  return std::error_code();
204  }
205 
206  case FS_Name: {
207  std::error_code EC =
210  return std::error_code();
211  if (EC)
212  return EC;
213  goto retry_random_path;
214  }
215 
216  case FS_Dir: {
217  if (std::error_code EC =
218  sys::fs::create_directory(ResultPath.begin(), false)) {
219  if (EC == errc::file_exists)
220  goto retry_random_path;
221  return EC;
222  }
223  return std::error_code();
224  }
225  }
226  llvm_unreachable("Invalid Type");
227 }
228 
229 namespace llvm {
230 namespace sys {
231 namespace path {
232 
235  i.Path = path;
236  i.Component = find_first_component(path);
237  i.Position = 0;
238  return i;
239 }
240 
243  i.Path = path;
244  i.Position = path.size();
245  return i;
246 }
247 
248 const_iterator &const_iterator::operator++() {
249  assert(Position < Path.size() && "Tried to increment past end!");
250 
251  // Increment Position to past the current component
252  Position += Component.size();
253 
254  // Check for end.
255  if (Position == Path.size()) {
256  Component = StringRef();
257  return *this;
258  }
259 
260  // Both POSIX and Windows treat paths that begin with exactly two separators
261  // specially.
262  bool was_net = Component.size() > 2 &&
263  is_separator(Component[0]) &&
264  Component[1] == Component[0] &&
265  !is_separator(Component[2]);
266 
267  // Handle separators.
268  if (is_separator(Path[Position])) {
269  // Root dir.
270  if (was_net
271 #ifdef LLVM_ON_WIN32
272  // c:/
273  || Component.endswith(":")
274 #endif
275  ) {
276  Component = Path.substr(Position, 1);
277  return *this;
278  }
279 
280  // Skip extra separators.
281  while (Position != Path.size() &&
282  is_separator(Path[Position])) {
283  ++Position;
284  }
285 
286  // Treat trailing '/' as a '.'.
287  if (Position == Path.size()) {
288  --Position;
289  Component = ".";
290  return *this;
291  }
292  }
293 
294  // Find next component.
295  size_t end_pos = Path.find_first_of(separators, Position);
296  Component = Path.slice(Position, end_pos);
297 
298  return *this;
299 }
300 
302  return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
303 }
304 
305 ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
306  return Position - RHS.Position;
307 }
308 
311  I.Path = Path;
312  I.Position = Path.size();
313  return ++I;
314 }
315 
318  I.Path = Path;
319  I.Component = Path.substr(0, 0);
320  I.Position = 0;
321  return I;
322 }
323 
324 reverse_iterator &reverse_iterator::operator++() {
325  // If we're at the end and the previous char was a '/', return '.' unless
326  // we are the root path.
327  size_t root_dir_pos = root_dir_start(Path);
328  if (Position == Path.size() &&
329  Path.size() > root_dir_pos + 1 &&
330  is_separator(Path[Position - 1])) {
331  --Position;
332  Component = ".";
333  return *this;
334  }
335 
336  // Skip separators unless it's the root directory.
337  size_t end_pos = Position;
338 
339  while(end_pos > 0 &&
340  (end_pos - 1) != root_dir_pos &&
341  is_separator(Path[end_pos - 1]))
342  --end_pos;
343 
344  // Find next separator.
345  size_t start_pos = filename_pos(Path.substr(0, end_pos));
346  Component = Path.slice(start_pos, end_pos);
347  Position = start_pos;
348  return *this;
349 }
350 
352  return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
353  Position == RHS.Position;
354 }
355 
356 ptrdiff_t reverse_iterator::operator-(const reverse_iterator &RHS) const {
357  return Position - RHS.Position;
358 }
359 
361  const_iterator b = begin(path),
362  pos = b,
363  e = end(path);
364  if (b != e) {
365  bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
366  bool has_drive =
367 #ifdef LLVM_ON_WIN32
368  b->endswith(":");
369 #else
370  false;
371 #endif
372 
373  if (has_net || has_drive) {
374  if ((++pos != e) && is_separator((*pos)[0])) {
375  // {C:/,//net/}, so get the first two components.
376  return path.substr(0, b->size() + pos->size());
377  } else {
378  // just {C:,//net}, return the first component.
379  return *b;
380  }
381  }
382 
383  // POSIX style root directory.
384  if (is_separator((*b)[0])) {
385  return *b;
386  }
387  }
388 
389  return StringRef();
390 }
391 
393  const_iterator b = begin(path),
394  e = end(path);
395  if (b != e) {
396  bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
397  bool has_drive =
398 #ifdef LLVM_ON_WIN32
399  b->endswith(":");
400 #else
401  false;
402 #endif
403 
404  if (has_net || has_drive) {
405  // just {C:,//net}, return the first component.
406  return *b;
407  }
408  }
409 
410  // No path or no name.
411  return StringRef();
412 }
413 
415  const_iterator b = begin(path),
416  pos = b,
417  e = end(path);
418  if (b != e) {
419  bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
420  bool has_drive =
421 #ifdef LLVM_ON_WIN32
422  b->endswith(":");
423 #else
424  false;
425 #endif
426 
427  if ((has_net || has_drive) &&
428  // {C:,//net}, skip to the next component.
429  (++pos != e) && is_separator((*pos)[0])) {
430  return *pos;
431  }
432 
433  // POSIX style root directory.
434  if (!has_net && is_separator((*b)[0])) {
435  return *b;
436  }
437  }
438 
439  // No path or no root.
440  return StringRef();
441 }
442 
444  StringRef root = root_path(path);
445  return path.substr(root.size());
446 }
447 
448 void append(SmallVectorImpl<char> &path, const Twine &a,
449  const Twine &b,
450  const Twine &c,
451  const Twine &d) {
452  SmallString<32> a_storage;
453  SmallString<32> b_storage;
454  SmallString<32> c_storage;
455  SmallString<32> d_storage;
456 
457  SmallVector<StringRef, 4> components;
458  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
459  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
460  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
461  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
462 
463  for (auto &component : components) {
464  bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
465  bool component_has_sep = !component.empty() && is_separator(component[0]);
466  bool is_root_name = has_root_name(component);
467 
468  if (path_has_sep) {
469  // Strip separators from beginning of component.
470  size_t loc = component.find_first_not_of(separators);
471  StringRef c = component.substr(loc);
472 
473  // Append it.
474  path.append(c.begin(), c.end());
475  continue;
476  }
477 
478  if (!component_has_sep && !(path.empty() || is_root_name)) {
479  // Add a separator.
480  path.push_back(preferred_separator);
481  }
482 
483  path.append(component.begin(), component.end());
484  }
485 }
486 
489  for (; begin != end; ++begin)
490  path::append(path, *begin);
491 }
492 
494  size_t end_pos = parent_path_end(path);
495  if (end_pos == StringRef::npos)
496  return StringRef();
497  else
498  return path.substr(0, end_pos);
499 }
500 
502  size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
503  if (end_pos != StringRef::npos)
504  path.set_size(end_pos);
505 }
506 
508  StringRef p(path.begin(), path.size());
509  SmallString<32> ext_storage;
510  StringRef ext = extension.toStringRef(ext_storage);
511 
512  // Erase existing extension.
513  size_t pos = p.find_last_of('.');
514  if (pos != StringRef::npos && pos >= filename_pos(p))
515  path.set_size(pos);
516 
517  // Append '.' if needed.
518  if (ext.size() > 0 && ext[0] != '.')
519  path.push_back('.');
520 
521  // Append extension.
522  path.append(ext.begin(), ext.end());
523 }
524 
526  const StringRef &OldPrefix,
527  const StringRef &NewPrefix) {
528  if (OldPrefix.empty() && NewPrefix.empty())
529  return;
530 
531  StringRef OrigPath(Path.begin(), Path.size());
532  if (!OrigPath.startswith(OldPrefix))
533  return;
534 
535  // If prefixes have the same size we can simply copy the new one over.
536  if (OldPrefix.size() == NewPrefix.size()) {
537  std::copy(NewPrefix.begin(), NewPrefix.end(), Path.begin());
538  return;
539  }
540 
541  StringRef RelPath = OrigPath.substr(OldPrefix.size());
542  SmallString<256> NewPath;
543  path::append(NewPath, NewPrefix);
544  path::append(NewPath, RelPath);
545  Path.swap(NewPath);
546 }
547 
548 void native(const Twine &path, SmallVectorImpl<char> &result) {
549  assert((!path.isSingleStringRef() ||
550  path.getSingleStringRef().data() != result.data()) &&
551  "path and result are not allowed to overlap!");
552  // Clear result.
553  result.clear();
554  path.toVector(result);
555  native(result);
556 }
557 
559 #ifdef LLVM_ON_WIN32
560  std::replace(Path.begin(), Path.end(), '/', '\\');
561 #else
562  for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
563  if (*PI == '\\') {
564  auto PN = PI + 1;
565  if (PN < PE && *PN == '\\')
566  ++PI; // increment once, the for loop will move over the escaped slash
567  else
568  *PI = '/';
569  }
570  }
571 #endif
572 }
573 
574 std::string convert_to_slash(StringRef path) {
575 #ifdef LLVM_ON_WIN32
576  std::string s = path.str();
577  std::replace(s.begin(), s.end(), '\\', '/');
578  return s;
579 #else
580  return path;
581 #endif
582 }
583 
585  return *rbegin(path);
586 }
587 
589  StringRef fname = filename(path);
590  size_t pos = fname.find_last_of('.');
591  if (pos == StringRef::npos)
592  return fname;
593  else
594  if ((fname.size() == 1 && fname == ".") ||
595  (fname.size() == 2 && fname == ".."))
596  return fname;
597  else
598  return fname.substr(0, pos);
599 }
600 
602  StringRef fname = filename(path);
603  size_t pos = fname.find_last_of('.');
604  if (pos == StringRef::npos)
605  return StringRef();
606  else
607  if ((fname.size() == 1 && fname == ".") ||
608  (fname.size() == 2 && fname == ".."))
609  return StringRef();
610  else
611  return fname.substr(pos);
612 }
613 
614 bool is_separator(char value) {
615  switch(value) {
616 #ifdef LLVM_ON_WIN32
617  case '\\': // fall through
618 #endif
619  case '/': return true;
620  default: return false;
621  }
622 }
623 
624 static const char preferred_separator_string[] = { preferred_separator, '\0' };
625 
628 }
629 
630 bool has_root_name(const Twine &path) {
631  SmallString<128> path_storage;
632  StringRef p = path.toStringRef(path_storage);
633 
634  return !root_name(p).empty();
635 }
636 
637 bool has_root_directory(const Twine &path) {
638  SmallString<128> path_storage;
639  StringRef p = path.toStringRef(path_storage);
640 
641  return !root_directory(p).empty();
642 }
643 
644 bool has_root_path(const Twine &path) {
645  SmallString<128> path_storage;
646  StringRef p = path.toStringRef(path_storage);
647 
648  return !root_path(p).empty();
649 }
650 
651 bool has_relative_path(const Twine &path) {
652  SmallString<128> path_storage;
653  StringRef p = path.toStringRef(path_storage);
654 
655  return !relative_path(p).empty();
656 }
657 
658 bool has_filename(const Twine &path) {
659  SmallString<128> path_storage;
660  StringRef p = path.toStringRef(path_storage);
661 
662  return !filename(p).empty();
663 }
664 
665 bool has_parent_path(const Twine &path) {
666  SmallString<128> path_storage;
667  StringRef p = path.toStringRef(path_storage);
668 
669  return !parent_path(p).empty();
670 }
671 
672 bool has_stem(const Twine &path) {
673  SmallString<128> path_storage;
674  StringRef p = path.toStringRef(path_storage);
675 
676  return !stem(p).empty();
677 }
678 
679 bool has_extension(const Twine &path) {
680  SmallString<128> path_storage;
681  StringRef p = path.toStringRef(path_storage);
682 
683  return !extension(p).empty();
684 }
685 
686 bool is_absolute(const Twine &path) {
687  SmallString<128> path_storage;
688  StringRef p = path.toStringRef(path_storage);
689 
690  bool rootDir = has_root_directory(p),
691 #ifdef LLVM_ON_WIN32
692  rootName = has_root_name(p);
693 #else
694  rootName = true;
695 #endif
696 
697  return rootDir && rootName;
698 }
699 
700 bool is_relative(const Twine &path) { return !is_absolute(path); }
701 
703  // Remove leading "./" (or ".//" or "././" etc.)
704  while (Path.size() > 2 && Path[0] == '.' && is_separator(Path[1])) {
705  Path = Path.substr(2);
706  while (Path.size() > 0 && is_separator(Path[0]))
707  Path = Path.substr(1);
708  }
709  return Path;
710 }
711 
712 static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot) {
713  SmallVector<StringRef, 16> components;
714 
715  // Skip the root path, then look for traversal in the components.
716  StringRef rel = path::relative_path(path);
717  for (StringRef C : llvm::make_range(path::begin(rel), path::end(rel))) {
718  if (C == ".")
719  continue;
720  // Leading ".." will remain in the path unless it's at the root.
721  if (remove_dot_dot && C == "..") {
722  if (!components.empty() && components.back() != "..") {
723  components.pop_back();
724  continue;
725  }
726  if (path::is_absolute(path))
727  continue;
728  }
729  components.push_back(C);
730  }
731 
732  SmallString<256> buffer = path::root_path(path);
733  for (StringRef C : components)
734  path::append(buffer, C);
735  return buffer;
736 }
737 
738 bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot) {
739  StringRef p(path.data(), path.size());
740 
741  SmallString<256> result = remove_dots(p, remove_dot_dot);
742  if (result == path)
743  return false;
744 
745  path.swap(result);
746  return true;
747 }
748 
749 } // end namespace path
750 
751 namespace fs {
752 
753 std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
755  std::error_code EC = status(Path, Status);
756  if (EC)
757  return EC;
758  Result = Status.getUniqueID();
759  return std::error_code();
760 }
761 
762 std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
763  SmallVectorImpl<char> &ResultPath,
764  unsigned Mode) {
765  return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
766 }
767 
768 std::error_code createUniqueFile(const Twine &Model,
769  SmallVectorImpl<char> &ResultPath) {
770  int Dummy;
771  return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
772 }
773 
774 static std::error_code
775 createTemporaryFile(const Twine &Model, int &ResultFD,
777  SmallString<128> Storage;
778  StringRef P = Model.toNullTerminatedStringRef(Storage);
779  assert(P.find_first_of(separators) == StringRef::npos &&
780  "Model must be a simple filename.");
781  // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
782  return createUniqueEntity(P.begin(), ResultFD, ResultPath,
783  true, owner_read | owner_write, Type);
784 }
785 
786 static std::error_code
787 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
789  const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
790  return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
791  Type);
792 }
793 
794 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
795  int &ResultFD,
796  SmallVectorImpl<char> &ResultPath) {
797  return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
798 }
799 
800 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
801  SmallVectorImpl<char> &ResultPath) {
802  int Dummy;
803  return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
804 }
805 
806 
807 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
808 // for consistency. We should try using mkdtemp.
809 std::error_code createUniqueDirectory(const Twine &Prefix,
810  SmallVectorImpl<char> &ResultPath) {
811  int Dummy;
812  return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
813  true, 0, FS_Dir);
814 }
815 
816 static std::error_code make_absolute(const Twine &current_directory,
817  SmallVectorImpl<char> &path,
818  bool use_current_directory) {
819  StringRef p(path.data(), path.size());
820 
821  bool rootDirectory = path::has_root_directory(p),
822 #ifdef LLVM_ON_WIN32
823  rootName = path::has_root_name(p);
824 #else
825  rootName = true;
826 #endif
827 
828  // Already absolute.
829  if (rootName && rootDirectory)
830  return std::error_code();
831 
832  // All of the following conditions will need the current directory.
833  SmallString<128> current_dir;
834  if (use_current_directory)
835  current_directory.toVector(current_dir);
836  else if (std::error_code ec = current_path(current_dir))
837  return ec;
838 
839  // Relative path. Prepend the current directory.
840  if (!rootName && !rootDirectory) {
841  // Append path to the current directory.
842  path::append(current_dir, p);
843  // Set path to the result.
844  path.swap(current_dir);
845  return std::error_code();
846  }
847 
848  if (!rootName && rootDirectory) {
849  StringRef cdrn = path::root_name(current_dir);
850  SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
851  path::append(curDirRootName, p);
852  // Set path to the result.
853  path.swap(curDirRootName);
854  return std::error_code();
855  }
856 
857  if (rootName && !rootDirectory) {
858  StringRef pRootName = path::root_name(p);
859  StringRef bRootDirectory = path::root_directory(current_dir);
860  StringRef bRelativePath = path::relative_path(current_dir);
861  StringRef pRelativePath = path::relative_path(p);
862 
863  SmallString<128> res;
864  path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
865  path.swap(res);
866  return std::error_code();
867  }
868 
869  llvm_unreachable("All rootName and rootDirectory combinations should have "
870  "occurred above!");
871 }
872 
873 std::error_code make_absolute(const Twine &current_directory,
874  SmallVectorImpl<char> &path) {
875  return make_absolute(current_directory, path, true);
876 }
877 
878 std::error_code make_absolute(SmallVectorImpl<char> &path) {
879  return make_absolute(Twine(), path, false);
880 }
881 
882 std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
883  perms Perms) {
884  SmallString<128> PathStorage;
885  StringRef P = Path.toStringRef(PathStorage);
886 
887  // Be optimistic and try to create the directory
888  std::error_code EC = create_directory(P, IgnoreExisting, Perms);
889  // If we succeeded, or had any error other than the parent not existing, just
890  // return it.
892  return EC;
893 
894  // We failed because of a no_such_file_or_directory, try to create the
895  // parent.
896  StringRef Parent = path::parent_path(P);
897  if (Parent.empty())
898  return EC;
899 
900  if ((EC = create_directories(Parent, IgnoreExisting, Perms)))
901  return EC;
902 
903  return create_directory(P, IgnoreExisting, Perms);
904 }
905 
906 std::error_code copy_file(const Twine &From, const Twine &To) {
907  int ReadFD, WriteFD;
908  if (std::error_code EC = openFileForRead(From, ReadFD))
909  return EC;
910  if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
911  close(ReadFD);
912  return EC;
913  }
914 
915  const size_t BufSize = 4096;
916  char *Buf = new char[BufSize];
917  int BytesRead = 0, BytesWritten = 0;
918  for (;;) {
919  BytesRead = read(ReadFD, Buf, BufSize);
920  if (BytesRead <= 0)
921  break;
922  while (BytesRead) {
923  BytesWritten = write(WriteFD, Buf, BytesRead);
924  if (BytesWritten < 0)
925  break;
926  BytesRead -= BytesWritten;
927  }
928  if (BytesWritten < 0)
929  break;
930  }
931  close(ReadFD);
932  close(WriteFD);
933  delete[] Buf;
934 
935  if (BytesRead < 0 || BytesWritten < 0)
936  return std::error_code(errno, std::generic_category());
937  return std::error_code();
938 }
939 
941  return status_known(status) && status.type() != file_type::file_not_found;
942 }
943 
945  return s.type() != file_type::status_error;
946 }
947 
949  return status.type() == file_type::directory_file;
950 }
951 
952 std::error_code is_directory(const Twine &path, bool &result) {
953  file_status st;
954  if (std::error_code ec = status(path, st))
955  return ec;
956  result = is_directory(st);
957  return std::error_code();
958 }
959 
961  return status.type() == file_type::regular_file;
962 }
963 
964 std::error_code is_regular_file(const Twine &path, bool &result) {
965  file_status st;
966  if (std::error_code ec = status(path, st))
967  return ec;
968  result = is_regular_file(st);
969  return std::error_code();
970 }
971 
973  return exists(status) &&
974  !is_regular_file(status) &&
975  !is_directory(status);
976 }
977 
978 std::error_code is_other(const Twine &Path, bool &Result) {
979  file_status FileStatus;
980  if (std::error_code EC = status(Path, FileStatus))
981  return EC;
982  Result = is_other(FileStatus);
983  return std::error_code();
984 }
985 
986 void directory_entry::replace_filename(const Twine &filename, file_status st) {
987  SmallString<128> path = path::parent_path(Path);
988  path::append(path, filename);
989  Path = path.str();
990  Status = st;
991 }
992 
993 template <size_t N>
994 static bool startswith(StringRef Magic, const char (&S)[N]) {
995  return Magic.startswith(StringRef(S, N - 1));
996 }
997 
998 /// @brief Identify the magic in magic.
1000  if (Magic.size() < 4)
1001  return file_magic::unknown;
1002  switch ((unsigned char)Magic[0]) {
1003  case 0x00: {
1004  // COFF bigobj, CL.exe's LTO object file, or short import library file
1005  if (startswith(Magic, "\0\0\xFF\xFF")) {
1006  size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
1007  if (Magic.size() < MinSize)
1008  return file_magic::coff_import_library;
1009 
1010  const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
1011  if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) == 0)
1012  return file_magic::coff_object;
1013  if (memcmp(Start, COFF::ClGlObjMagic, sizeof(COFF::BigObjMagic)) == 0)
1014  return file_magic::coff_cl_gl_object;
1015  return file_magic::coff_import_library;
1016  }
1017  // Windows resource file
1018  if (startswith(Magic, "\0\0\0\0\x20\0\0\0\xFF"))
1019  return file_magic::windows_resource;
1020  // 0x0000 = COFF unknown machine type
1021  if (Magic[1] == 0)
1022  return file_magic::coff_object;
1023  if (startswith(Magic, "\0asm"))
1024  return file_magic::wasm_object;
1025  break;
1026  }
1027  case 0xDE: // 0x0B17C0DE = BC wraper
1028  if (startswith(Magic, "\xDE\xC0\x17\x0B"))
1029  return file_magic::bitcode;
1030  break;
1031  case 'B':
1032  if (startswith(Magic, "BC\xC0\xDE"))
1033  return file_magic::bitcode;
1034  break;
1035  case '!':
1036  if (startswith(Magic, "!<arch>\n") || startswith(Magic, "!<thin>\n"))
1037  return file_magic::archive;
1038  break;
1039 
1040  case '\177':
1041  if (startswith(Magic, "\177ELF") && Magic.size() >= 18) {
1042  bool Data2MSB = Magic[5] == 2;
1043  unsigned high = Data2MSB ? 16 : 17;
1044  unsigned low = Data2MSB ? 17 : 16;
1045  if (Magic[high] == 0) {
1046  switch (Magic[low]) {
1047  default: return file_magic::elf;
1048  case 1: return file_magic::elf_relocatable;
1049  case 2: return file_magic::elf_executable;
1050  case 3: return file_magic::elf_shared_object;
1051  case 4: return file_magic::elf_core;
1052  }
1053  }
1054  // It's still some type of ELF file.
1055  return file_magic::elf;
1056  }
1057  break;
1058 
1059  case 0xCA:
1060  if (startswith(Magic, "\xCA\xFE\xBA\xBE") ||
1061  startswith(Magic, "\xCA\xFE\xBA\xBF")) {
1062  // This is complicated by an overlap with Java class files.
1063  // See the Mach-O section in /usr/share/file/magic for details.
1064  if (Magic.size() >= 8 && Magic[7] < 43)
1065  return file_magic::macho_universal_binary;
1066  }
1067  break;
1068 
1069  // The two magic numbers for mach-o are:
1070  // 0xfeedface - 32-bit mach-o
1071  // 0xfeedfacf - 64-bit mach-o
1072  case 0xFE:
1073  case 0xCE:
1074  case 0xCF: {
1075  uint16_t type = 0;
1076  if (startswith(Magic, "\xFE\xED\xFA\xCE") ||
1077  startswith(Magic, "\xFE\xED\xFA\xCF")) {
1078  /* Native endian */
1079  size_t MinSize;
1080  if (Magic[3] == char(0xCE))
1081  MinSize = sizeof(MachO::mach_header);
1082  else
1083  MinSize = sizeof(MachO::mach_header_64);
1084  if (Magic.size() >= MinSize)
1085  type = Magic[12] << 24 | Magic[13] << 12 | Magic[14] << 8 | Magic[15];
1086  } else if (startswith(Magic, "\xCE\xFA\xED\xFE") ||
1087  startswith(Magic, "\xCF\xFA\xED\xFE")) {
1088  /* Reverse endian */
1089  size_t MinSize;
1090  if (Magic[0] == char(0xCE))
1091  MinSize = sizeof(MachO::mach_header);
1092  else
1093  MinSize = sizeof(MachO::mach_header_64);
1094  if (Magic.size() >= MinSize)
1095  type = Magic[15] << 24 | Magic[14] << 12 |Magic[13] << 8 | Magic[12];
1096  }
1097  switch (type) {
1098  default: break;
1099  case 1: return file_magic::macho_object;
1100  case 2: return file_magic::macho_executable;
1101  case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
1102  case 4: return file_magic::macho_core;
1103  case 5: return file_magic::macho_preload_executable;
1104  case 6: return file_magic::macho_dynamically_linked_shared_lib;
1105  case 7: return file_magic::macho_dynamic_linker;
1106  case 8: return file_magic::macho_bundle;
1107  case 9: return file_magic::macho_dynamically_linked_shared_lib_stub;
1108  case 10: return file_magic::macho_dsym_companion;
1109  case 11: return file_magic::macho_kext_bundle;
1110  }
1111  break;
1112  }
1113  case 0xF0: // PowerPC Windows
1114  case 0x83: // Alpha 32-bit
1115  case 0x84: // Alpha 64-bit
1116  case 0x66: // MPS R4000 Windows
1117  case 0x50: // mc68K
1118  case 0x4c: // 80386 Windows
1119  case 0xc4: // ARMNT Windows
1120  if (Magic[1] == 0x01)
1121  return file_magic::coff_object;
1122 
1123  case 0x90: // PA-RISC Windows
1124  case 0x68: // mc68K Windows
1125  if (Magic[1] == 0x02)
1126  return file_magic::coff_object;
1127  break;
1128 
1129  case 'M': // Possible MS-DOS stub on Windows PE file
1130  if (startswith(Magic, "MZ")) {
1131  uint32_t off = read32le(Magic.data() + 0x3c);
1132  // PE/COFF file, either EXE or DLL.
1133  if (off < Magic.size() &&
1134  memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
1135  return file_magic::pecoff_executable;
1136  }
1137  break;
1138 
1139  case 0x64: // x86-64 Windows.
1140  if (Magic[1] == char(0x86))
1141  return file_magic::coff_object;
1142  break;
1143 
1144  default:
1145  break;
1146  }
1147  return file_magic::unknown;
1148 }
1149 
1150 std::error_code identify_magic(const Twine &Path, file_magic &Result) {
1151  int FD;
1152  if (std::error_code EC = openFileForRead(Path, FD))
1153  return EC;
1154 
1155  char Buffer[32];
1156  int Length = read(FD, Buffer, sizeof(Buffer));
1157  if (close(FD) != 0 || Length < 0)
1158  return std::error_code(errno, std::generic_category());
1159 
1160  Result = identify_magic(StringRef(Buffer, Length));
1161  return std::error_code();
1162 }
1163 
1164 std::error_code directory_entry::status(file_status &result) const {
1165  return fs::status(Path, result);
1166 }
1167 
1168 } // end namespace fs
1169 } // end namespace sys
1170 } // end namespace llvm
1171 
1172 // Include the truly platform-specific parts.
1173 #if defined(LLVM_ON_UNIX)
1174 #include "Unix/Path.inc"
1175 #endif
1176 #if defined(LLVM_ON_WIN32)
1177 #include "Windows/Path.inc"
1178 #endif
1179 
1180 namespace llvm {
1181 namespace sys {
1182 namespace path {
1183 
1185  const Twine &Path2, const Twine &Path3) {
1186  if (getUserCacheDir(Result)) {
1187  append(Result, Path1, Path2, Path3);
1188  return true;
1189  }
1190  return false;
1191 }
1192 
1193 } // end namespace path
1194 } // end namsspace sys
1195 } // end namespace llvm
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
Definition: Twine.cpp:32
void push_back(const T &Elt)
Definition: SmallVector.h:211
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
Definition: Path.cpp:882
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
bool isSingleStringRef() const
Return true if this twine can be dynamically accessed as a single StringRef value with getSingleStrin...
Definition: Twine.h:414
StringRef root_name(StringRef path)
Get root name.
Definition: Path.cpp:392
StringRef stem(StringRef path)
Get stem.
Definition: Path.cpp:588
SI Whole Quad Mode
size_t i
value_type read(const void *memory)
Read a value of a particular endianness from memory.
Definition: Endian.h:48
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, unsigned Mode=all_read|all_write)
Create a uniquely named file.
Definition: Path.cpp:762
std::error_code openFileForRead(const Twine &Name, int &ResultFD, SmallVectorImpl< char > *RealPath=nullptr)
F_Excl - When opening a file, this flag makes raw_fd_ostream report an error if the file already exis...
Definition: FileSystem.h:629
bool is_relative(const Twine &path)
Is path relative?
Definition: Path.cpp:700
static std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, llvm::SmallVectorImpl< char > &ResultPath, FSEntity Type)
Definition: Path.cpp:787
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension)
Replace the file extension of path with extension.
Definition: Path.cpp:507
UniqueID getUniqueID() const
bool has_stem(const Twine &path)
Has stem?
Definition: Path.cpp:672
StringRef root_directory(StringRef path)
Get root directory.
Definition: Path.cpp:414
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, unsigned Mode, FSEntity Type)
Definition: Path.cpp:161
bool has_root_directory(const Twine &path)
Has root directory?
Definition: Path.cpp:637
file_status - Represents the result of a call to stat and friends.
Definition: FileSystem.h:142
Definition: Path.cpp:156
static const char BigObjMagic[]
Definition: Support/COFF.h:39
bool status_known(file_status s)
Is status available?
Definition: Path.cpp:944
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:448
void remove_filename(SmallVectorImpl< char > &path)
Remove the last component from path unless it is the root dir.
Definition: Path.cpp:501
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
write bitcode
bool is_absolute(const Twine &path)
Is path absolute?
Definition: Path.cpp:686
StringRef extension(StringRef path)
Get extension.
Definition: Path.cpp:601
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:60
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
bool is_separator(char value)
Check whether the given char is a path separator on the host OS.
Definition: Path.cpp:614
static const char preferred_separator_string[]
Definition: Path.cpp:624
StringRef root_path(StringRef path)
Get root path.
Definition: Path.cpp:360
bool has_relative_path(const Twine &path)
Has relative path?
Definition: Path.cpp:651
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
Definition: Twine.h:447
Open the file for read and write.
Definition: FileSystem.h:641
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
iterator begin() const
Definition: StringRef.h:103
static const char ClGlObjMagic[]
Definition: Support/COFF.h:44
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
Definition: Path.cpp:906
#define P(N)
StringRef filename(StringRef path)
Get filename.
Definition: Path.cpp:584
static SmallString< 256 > remove_dots(StringRef path, bool remove_dot_dot)
Definition: Path.cpp:712
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void swap(SmallVectorImpl &RHS)
Definition: SmallVector.h:675
bool has_filename(const Twine &path)
Has filename?
Definition: Path.cpp:658
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:115
LLVM_NODISCARD size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
Definition: StringRef.h:418
bool is_other(file_status status)
Does this status represent something that exists but is not a directory, regular file, or symlink?
Definition: Path.cpp:972
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:587
bool user_cache_directory(SmallVectorImpl< char > &Result, const Twine &Path1, const Twine &Path2="", const Twine &Path3="")
Get the user's cache directory.
Definition: Path.cpp:1184
void replace_path_prefix(SmallVectorImpl< char > &Path, const StringRef &OldPrefix, const StringRef &NewPrefix)
Replace matching path prefix with another path.
Definition: Path.cpp:525
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
Definition: Path.cpp:753
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:225
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool is_directory(file_status status)
Does status represent a directory?
Definition: Path.cpp:948
StringRef remove_leading_dotslash(StringRef path)
Remove redundant leading "./" pieces and consecutive separators.
Definition: Path.cpp:702
static const char *const Magic
Definition: Archive.cpp:25
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Path.cpp:999
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
StringRef relative_path(StringRef path)
Get relative path.
Definition: Path.cpp:443
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
Definition: Twine.h:463
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
Definition: Path.cpp:809
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
StringRef parent_path(StringRef path)
Get parent path.
Definition: Path.cpp:493
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
bool is_regular_file(file_status status)
Does status represent a regular file?
Definition: Path.cpp:960
StringRef get_separator()
Return the preferred separator for this platform.
Definition: Path.cpp:626
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
Path iterator.
Definition: Path.h:49
Reverse path iterator.
Definition: Path.h:75
void write(void *memory, value_type value)
Write a value to memory with a particular endianness.
Definition: Endian.h:72
static bool startswith(StringRef Magic, const char(&S)[N])
Definition: Path.cpp:994
static unsigned GetRandomNumber()
Get the result of a process wide random number generator.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
void set_size(size_type N)
Set the array size to N, which the current array must have enough capacity for.
Definition: SmallVector.h:668
Provides a library for accessing information about this process and other processes on the operating ...
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: FileSystem.h:240
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:142
static const size_t npos
Definition: StringRef.h:51
reverse_iterator rbegin(StringRef path)
Get reverse begin iterator over path.
Definition: Path.cpp:309
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
uint32_t read32le(const void *P)
Definition: Endian.h:318
APInt operator-(APInt)
Definition: APInt.h:1731
static const char PEMagic[]
Definition: Support/COFF.h:37
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
bool has_root_path(const Twine &path)
Has root path?
Definition: Path.cpp:644
bool has_root_name(const Twine &path)
Has root name?
Definition: Path.cpp:630
reverse_iterator rend(StringRef path)
Get reverse end iterator over path.
Definition: Path.cpp:316
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:392
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef toNullTerminatedStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single null terminated StringRef if it can be represented as such...
Definition: Twine.cpp:37
bool isTriviallyEmpty() const
Check if this twine is trivially empty; a false return value does not necessarily mean the twine is e...
Definition: Twine.h:408
iterator end() const
Definition: StringRef.h:105
bool has_extension(const Twine &path)
Has extension?
Definition: Path.cpp:679
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1722
std::error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
bool exists(file_status status)
Does file exist?
Definition: Path.cpp:940
file_type type() const
Definition: FileSystem.h:211
std::string convert_to_slash(StringRef path)
Replaces backslashes with slashes if Windows.
Definition: Path.cpp:574
bool has_parent_path(const Twine &path)
Has parent path?
Definition: Path.cpp:665
FSEntity
Definition: Path.cpp:155
static std::error_code make_absolute(const Twine &current_directory, SmallVectorImpl< char > &path, bool use_current_directory)
Definition: Path.cpp:816
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags, unsigned Mode=0666)