LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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/Path.h"
15 #include "llvm/Support/Endian.h"
18 #include <cctype>
19 #include <cstdio>
20 #include <cstring>
21 #include <fcntl.h>
22 
23 #if !defined(_MSC_VER) && !defined(__MINGW32__)
24 #include <unistd.h>
25 #else
26 #include <io.h>
27 #endif
28 
29 namespace {
30  using llvm::StringRef;
32 
33 #ifdef LLVM_ON_WIN32
34  const char *separators = "\\/";
35  const char prefered_separator = '\\';
36 #else
37  const char separators = '/';
38  const char prefered_separator = '/';
39 #endif
40 
41  StringRef find_first_component(StringRef path) {
42  // Look for this first component in the following order.
43  // * empty (in this case we return an empty string)
44  // * either C: or {//,\\}net.
45  // * {/,\}
46  // * {.,..}
47  // * {file,directory}name
48 
49  if (path.empty())
50  return path;
51 
52 #ifdef LLVM_ON_WIN32
53  // C:
54  if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
55  path[1] == ':')
56  return path.substr(0, 2);
57 #endif
58 
59  // //net
60  if ((path.size() > 2) &&
61  is_separator(path[0]) &&
62  path[0] == path[1] &&
63  !is_separator(path[2])) {
64  // Find the next directory separator.
65  size_t end = path.find_first_of(separators, 2);
66  return path.substr(0, end);
67  }
68 
69  // {/,\}
70  if (is_separator(path[0]))
71  return path.substr(0, 1);
72 
73  if (path.startswith(".."))
74  return path.substr(0, 2);
75 
76  if (path[0] == '.')
77  return path.substr(0, 1);
78 
79  // * {file,directory}name
80  size_t end = path.find_first_of(separators);
81  return path.substr(0, end);
82  }
83 
84  size_t filename_pos(StringRef str) {
85  if (str.size() == 2 &&
86  is_separator(str[0]) &&
87  str[0] == str[1])
88  return 0;
89 
90  if (str.size() > 0 && is_separator(str[str.size() - 1]))
91  return str.size() - 1;
92 
93  size_t pos = str.find_last_of(separators, str.size() - 1);
94 
95 #ifdef LLVM_ON_WIN32
96  if (pos == StringRef::npos)
97  pos = str.find_last_of(':', str.size() - 2);
98 #endif
99 
100  if (pos == StringRef::npos ||
101  (pos == 1 && is_separator(str[0])))
102  return 0;
103 
104  return pos + 1;
105  }
106 
107  size_t root_dir_start(StringRef str) {
108  // case "c:/"
109 #ifdef LLVM_ON_WIN32
110  if (str.size() > 2 &&
111  str[1] == ':' &&
112  is_separator(str[2]))
113  return 2;
114 #endif
115 
116  // case "//"
117  if (str.size() == 2 &&
118  is_separator(str[0]) &&
119  str[0] == str[1])
120  return StringRef::npos;
121 
122  // case "//net"
123  if (str.size() > 3 &&
124  is_separator(str[0]) &&
125  str[0] == str[1] &&
126  !is_separator(str[2])) {
127  return str.find_first_of(separators, 2);
128  }
129 
130  // case "/"
131  if (str.size() > 0 && is_separator(str[0]))
132  return 0;
133 
134  return StringRef::npos;
135  }
136 
137  size_t parent_path_end(StringRef path) {
138  size_t end_pos = filename_pos(path);
139 
140  bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
141 
142  // Skip separators except for root dir.
143  size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
144 
145  while(end_pos > 0 &&
146  (end_pos - 1) != root_dir_pos &&
147  is_separator(path[end_pos - 1]))
148  --end_pos;
149 
150  if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
151  return StringRef::npos;
152 
153  return end_pos;
154  }
155 } // end unnamed namespace
156 
157 enum FSEntity {
161 };
162 
163 // Implemented in Unix/Path.inc and Windows/Path.inc.
164 static llvm::error_code
165 createUniqueEntity(const llvm::Twine &Model, int &ResultFD,
166  llvm::SmallVectorImpl<char> &ResultPath,
167  bool MakeAbsolute, unsigned Mode, FSEntity Type);
168 
169 namespace llvm {
170 namespace sys {
171 namespace path {
172 
174  const_iterator i;
175  i.Path = path;
176  i.Component = find_first_component(path);
177  i.Position = 0;
178  return i;
179 }
180 
182  const_iterator i;
183  i.Path = path;
184  i.Position = path.size();
185  return i;
186 }
187 
189  assert(Position < Path.size() && "Tried to increment past end!");
190 
191  // Increment Position to past the current component
192  Position += Component.size();
193 
194  // Check for end.
195  if (Position == Path.size()) {
196  Component = StringRef();
197  return *this;
198  }
199 
200  // Both POSIX and Windows treat paths that begin with exactly two separators
201  // specially.
202  bool was_net = Component.size() > 2 &&
203  is_separator(Component[0]) &&
204  Component[1] == Component[0] &&
205  !is_separator(Component[2]);
206 
207  // Handle separators.
208  if (is_separator(Path[Position])) {
209  // Root dir.
210  if (was_net
211 #ifdef LLVM_ON_WIN32
212  // c:/
213  || Component.endswith(":")
214 #endif
215  ) {
216  Component = Path.substr(Position, 1);
217  return *this;
218  }
219 
220  // Skip extra separators.
221  while (Position != Path.size() &&
222  is_separator(Path[Position])) {
223  ++Position;
224  }
225 
226  // Treat trailing '/' as a '.'.
227  if (Position == Path.size()) {
228  --Position;
229  Component = ".";
230  return *this;
231  }
232  }
233 
234  // Find next component.
235  size_t end_pos = Path.find_first_of(separators, Position);
236  Component = Path.slice(Position, end_pos);
237 
238  return *this;
239 }
240 
242  // If we're at the end and the previous char was a '/', return '.'.
243  if (Position == Path.size() &&
244  Path.size() > 1 &&
245  is_separator(Path[Position - 1])
246 #ifdef LLVM_ON_WIN32
247  && Path[Position - 2] != ':'
248 #endif
249  ) {
250  --Position;
251  Component = ".";
252  return *this;
253  }
254 
255  // Skip separators unless it's the root directory.
256  size_t root_dir_pos = root_dir_start(Path);
257  size_t end_pos = Position;
258 
259  while(end_pos > 0 &&
260  (end_pos - 1) != root_dir_pos &&
261  is_separator(Path[end_pos - 1]))
262  --end_pos;
263 
264  // Find next separator.
265  size_t start_pos = filename_pos(Path.substr(0, end_pos));
266  Component = Path.slice(start_pos, end_pos);
267  Position = start_pos;
268  return *this;
269 }
270 
272  return Path.begin() == RHS.Path.begin() &&
273  Position == RHS.Position;
274 }
275 
277  return !(*this == RHS);
278 }
279 
280 ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
281  return Position - RHS.Position;
282 }
283 
285  const_iterator b = begin(path),
286  pos = b,
287  e = end(path);
288  if (b != e) {
289  bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
290  bool has_drive =
291 #ifdef LLVM_ON_WIN32
292  b->endswith(":");
293 #else
294  false;
295 #endif
296 
297  if (has_net || has_drive) {
298  if ((++pos != e) && is_separator((*pos)[0])) {
299  // {C:/,//net/}, so get the first two components.
300  return path.substr(0, b->size() + pos->size());
301  } else {
302  // just {C:,//net}, return the first component.
303  return *b;
304  }
305  }
306 
307  // POSIX style root directory.
308  if (is_separator((*b)[0])) {
309  return *b;
310  }
311  }
312 
313  return StringRef();
314 }
315 
317  const_iterator b = begin(path),
318  e = end(path);
319  if (b != e) {
320  bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
321  bool has_drive =
322 #ifdef LLVM_ON_WIN32
323  b->endswith(":");
324 #else
325  false;
326 #endif
327 
328  if (has_net || has_drive) {
329  // just {C:,//net}, return the first component.
330  return *b;
331  }
332  }
333 
334  // No path or no name.
335  return StringRef();
336 }
337 
339  const_iterator b = begin(path),
340  pos = b,
341  e = end(path);
342  if (b != e) {
343  bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
344  bool has_drive =
345 #ifdef LLVM_ON_WIN32
346  b->endswith(":");
347 #else
348  false;
349 #endif
350 
351  if ((has_net || has_drive) &&
352  // {C:,//net}, skip to the next component.
353  (++pos != e) && is_separator((*pos)[0])) {
354  return *pos;
355  }
356 
357  // POSIX style root directory.
358  if (!has_net && is_separator((*b)[0])) {
359  return *b;
360  }
361  }
362 
363  // No path or no root.
364  return StringRef();
365 }
366 
368  StringRef root = root_path(path);
369  return path.substr(root.size());
370 }
371 
372 void append(SmallVectorImpl<char> &path, const Twine &a,
373  const Twine &b,
374  const Twine &c,
375  const Twine &d) {
376  SmallString<32> a_storage;
377  SmallString<32> b_storage;
378  SmallString<32> c_storage;
379  SmallString<32> d_storage;
380 
381  SmallVector<StringRef, 4> components;
382  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
383  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
384  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
385  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
386 
388  e = components.end();
389  i != e; ++i) {
390  bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
391  bool component_has_sep = !i->empty() && is_separator((*i)[0]);
392  bool is_root_name = has_root_name(*i);
393 
394  if (path_has_sep) {
395  // Strip separators from beginning of component.
396  size_t loc = i->find_first_not_of(separators);
397  StringRef c = i->substr(loc);
398 
399  // Append it.
400  path.append(c.begin(), c.end());
401  continue;
402  }
403 
404  if (!component_has_sep && !(path.empty() || is_root_name)) {
405  // Add a separator.
406  path.push_back(prefered_separator);
407  }
408 
409  path.append(i->begin(), i->end());
410  }
411 }
412 
415  for (; begin != end; ++begin)
416  path::append(path, *begin);
417 }
418 
420  size_t end_pos = parent_path_end(path);
421  if (end_pos == StringRef::npos)
422  return StringRef();
423  else
424  return path.substr(0, end_pos);
425 }
426 
428  size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
429  if (end_pos != StringRef::npos)
430  path.set_size(end_pos);
431 }
432 
434  StringRef p(path.begin(), path.size());
435  SmallString<32> ext_storage;
436  StringRef ext = extension.toStringRef(ext_storage);
437 
438  // Erase existing extension.
439  size_t pos = p.find_last_of('.');
440  if (pos != StringRef::npos && pos >= filename_pos(p))
441  path.set_size(pos);
442 
443  // Append '.' if needed.
444  if (ext.size() > 0 && ext[0] != '.')
445  path.push_back('.');
446 
447  // Append extension.
448  path.append(ext.begin(), ext.end());
449 }
450 
451 void native(const Twine &path, SmallVectorImpl<char> &result) {
452  assert((!path.isSingleStringRef() ||
453  path.getSingleStringRef().data() != result.data()) &&
454  "path and result are not allowed to overlap!");
455  // Clear result.
456  result.clear();
457  path.toVector(result);
458  native(result);
459 }
460 
462 #ifdef LLVM_ON_WIN32
463  std::replace(path.begin(), path.end(), '/', '\\');
464 #endif
465 }
466 
468  return *(--end(path));
469 }
470 
471 const StringRef stem(StringRef path) {
472  StringRef fname = filename(path);
473  size_t pos = fname.find_last_of('.');
474  if (pos == StringRef::npos)
475  return fname;
476  else
477  if ((fname.size() == 1 && fname == ".") ||
478  (fname.size() == 2 && fname == ".."))
479  return fname;
480  else
481  return fname.substr(0, pos);
482 }
483 
485  StringRef fname = filename(path);
486  size_t pos = fname.find_last_of('.');
487  if (pos == StringRef::npos)
488  return StringRef();
489  else
490  if ((fname.size() == 1 && fname == ".") ||
491  (fname.size() == 2 && fname == ".."))
492  return StringRef();
493  else
494  return fname.substr(pos);
495 }
496 
497 bool is_separator(char value) {
498  switch(value) {
499 #ifdef LLVM_ON_WIN32
500  case '\\': // fall through
501 #endif
502  case '/': return true;
503  default: return false;
504  }
505 }
506 
507 void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
508  result.clear();
509 
510 #ifdef __APPLE__
511  // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
512  int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
513  : _CS_DARWIN_USER_CACHE_DIR;
514  size_t ConfLen = confstr(ConfName, 0, 0);
515  if (ConfLen > 0) {
516  do {
517  result.resize(ConfLen);
518  ConfLen = confstr(ConfName, result.data(), result.size());
519  } while (ConfLen > 0 && ConfLen != result.size());
520 
521  if (ConfLen > 0) {
522  assert(result.back() == 0);
523  result.pop_back();
524  return;
525  }
526 
527  result.clear();
528  }
529 #endif
530 
531  // Check whether the temporary directory is specified by an environment
532  // variable.
533  const char *EnvironmentVariable;
534 #ifdef LLVM_ON_WIN32
535  EnvironmentVariable = "TEMP";
536 #else
537  EnvironmentVariable = "TMPDIR";
538 #endif
539  if (char *RequestedDir = getenv(EnvironmentVariable)) {
540  result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
541  return;
542  }
543 
544  // Fall back to a system default.
545  const char *DefaultResult;
546 #ifdef LLVM_ON_WIN32
547  (void)erasedOnReboot;
548  DefaultResult = "C:\\TEMP";
549 #else
550  if (erasedOnReboot)
551  DefaultResult = "/tmp";
552  else
553  DefaultResult = "/var/tmp";
554 #endif
555  result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
556 }
557 
558 bool has_root_name(const Twine &path) {
559  SmallString<128> path_storage;
560  StringRef p = path.toStringRef(path_storage);
561 
562  return !root_name(p).empty();
563 }
564 
565 bool has_root_directory(const Twine &path) {
566  SmallString<128> path_storage;
567  StringRef p = path.toStringRef(path_storage);
568 
569  return !root_directory(p).empty();
570 }
571 
572 bool has_root_path(const Twine &path) {
573  SmallString<128> path_storage;
574  StringRef p = path.toStringRef(path_storage);
575 
576  return !root_path(p).empty();
577 }
578 
579 bool has_relative_path(const Twine &path) {
580  SmallString<128> path_storage;
581  StringRef p = path.toStringRef(path_storage);
582 
583  return !relative_path(p).empty();
584 }
585 
586 bool has_filename(const Twine &path) {
587  SmallString<128> path_storage;
588  StringRef p = path.toStringRef(path_storage);
589 
590  return !filename(p).empty();
591 }
592 
593 bool has_parent_path(const Twine &path) {
594  SmallString<128> path_storage;
595  StringRef p = path.toStringRef(path_storage);
596 
597  return !parent_path(p).empty();
598 }
599 
600 bool has_stem(const Twine &path) {
601  SmallString<128> path_storage;
602  StringRef p = path.toStringRef(path_storage);
603 
604  return !stem(p).empty();
605 }
606 
607 bool has_extension(const Twine &path) {
608  SmallString<128> path_storage;
609  StringRef p = path.toStringRef(path_storage);
610 
611  return !extension(p).empty();
612 }
613 
614 bool is_absolute(const Twine &path) {
615  SmallString<128> path_storage;
616  StringRef p = path.toStringRef(path_storage);
617 
618  bool rootDir = has_root_directory(p),
619 #ifdef LLVM_ON_WIN32
620  rootName = has_root_name(p);
621 #else
622  rootName = true;
623 #endif
624 
625  return rootDir && rootName;
626 }
627 
628 bool is_relative(const Twine &path) {
629  return !is_absolute(path);
630 }
631 
632 } // end namespace path
633 
634 namespace fs {
635 
636 error_code getUniqueID(const Twine Path, UniqueID &Result) {
638  error_code EC = status(Path, Status);
639  if (EC)
640  return EC;
641  Result = Status.getUniqueID();
642  return error_code::success();
643 }
644 
645 error_code createUniqueFile(const Twine &Model, int &ResultFd,
646  SmallVectorImpl<char> &ResultPath, unsigned Mode) {
647  return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
648 }
649 
651  SmallVectorImpl<char> &ResultPath) {
652  int Dummy;
653  return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
654 }
655 
656 static error_code createTemporaryFile(const Twine &Model, int &ResultFD,
657  llvm::SmallVectorImpl<char> &ResultPath,
658  FSEntity Type) {
659  SmallString<128> Storage;
660  StringRef P = Model.toNullTerminatedStringRef(Storage);
661  assert(P.find_first_of(separators) == StringRef::npos &&
662  "Model must be a simple filename.");
663  // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
664  return createUniqueEntity(P.begin(), ResultFD, ResultPath,
665  true, owner_read | owner_write, Type);
666 }
667 
668 static error_code
669 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
670  llvm::SmallVectorImpl<char> &ResultPath,
671  FSEntity Type) {
672  const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
673  return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
674  Type);
675 }
676 
677 
679  int &ResultFD,
680  SmallVectorImpl<char> &ResultPath) {
681  return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
682 }
683 
685  SmallVectorImpl<char> &ResultPath) {
686  int Dummy;
687  return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
688 }
689 
690 
691 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
692 // for consistency. We should try using mkdtemp.
694  SmallVectorImpl<char> &ResultPath) {
695  int Dummy;
696  return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
697  true, 0, FS_Dir);
698 }
699 
701  StringRef p(path.data(), path.size());
702 
703  bool rootDirectory = path::has_root_directory(p),
704 #ifdef LLVM_ON_WIN32
705  rootName = path::has_root_name(p);
706 #else
707  rootName = true;
708 #endif
709 
710  // Already absolute.
711  if (rootName && rootDirectory)
712  return error_code::success();
713 
714  // All of the following conditions will need the current directory.
715  SmallString<128> current_dir;
716  if (error_code ec = current_path(current_dir)) return ec;
717 
718  // Relative path. Prepend the current directory.
719  if (!rootName && !rootDirectory) {
720  // Append path to the current directory.
721  path::append(current_dir, p);
722  // Set path to the result.
723  path.swap(current_dir);
724  return error_code::success();
725  }
726 
727  if (!rootName && rootDirectory) {
728  StringRef cdrn = path::root_name(current_dir);
729  SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
730  path::append(curDirRootName, p);
731  // Set path to the result.
732  path.swap(curDirRootName);
733  return error_code::success();
734  }
735 
736  if (rootName && !rootDirectory) {
737  StringRef pRootName = path::root_name(p);
738  StringRef bRootDirectory = path::root_directory(current_dir);
739  StringRef bRelativePath = path::relative_path(current_dir);
740  StringRef pRelativePath = path::relative_path(p);
741 
742  SmallString<128> res;
743  path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
744  path.swap(res);
745  return error_code::success();
746  }
747 
748  llvm_unreachable("All rootName and rootDirectory combinations should have "
749  "occurred above!");
750 }
751 
752 error_code create_directories(const Twine &path, bool &existed) {
753  SmallString<128> path_storage;
754  StringRef p = path.toStringRef(path_storage);
755 
756  StringRef parent = path::parent_path(p);
757  if (!parent.empty()) {
758  bool parent_exists;
759  if (error_code ec = fs::exists(parent, parent_exists)) return ec;
760 
761  if (!parent_exists)
762  if (error_code ec = create_directories(parent, existed)) return ec;
763  }
764 
765  return create_directory(p, existed);
766 }
767 
769  return status_known(status) && status.type() != file_type::file_not_found;
770 }
771 
773  return s.type() != file_type::status_error;
774 }
775 
777  return status.type() == file_type::directory_file;
778 }
779 
780 error_code is_directory(const Twine &path, bool &result) {
781  file_status st;
782  if (error_code ec = status(path, st))
783  return ec;
784  result = is_directory(st);
785  return error_code::success();
786 }
787 
789  return status.type() == file_type::regular_file;
790 }
791 
792 error_code is_regular_file(const Twine &path, bool &result) {
793  file_status st;
794  if (error_code ec = status(path, st))
795  return ec;
796  result = is_regular_file(st);
797  return error_code::success();
798 }
799 
801  return status.type() == file_type::symlink_file;
802 }
803 
804 error_code is_symlink(const Twine &path, bool &result) {
805  file_status st;
806  if (error_code ec = status(path, st))
807  return ec;
808  result = is_symlink(st);
809  return error_code::success();
810 }
811 
813  return exists(status) &&
814  !is_regular_file(status) &&
815  !is_directory(status) &&
816  !is_symlink(status);
817 }
818 
820  SmallString<128> path(Path.begin(), Path.end());
821  path::remove_filename(path);
822  path::append(path, filename);
823  Path = path.str();
824  Status = st;
825 }
826 
827 error_code has_magic(const Twine &path, const Twine &magic, bool &result) {
828  SmallString<32> MagicStorage;
829  StringRef Magic = magic.toStringRef(MagicStorage);
830  SmallString<32> Buffer;
831 
832  if (error_code ec = get_magic(path, Magic.size(), Buffer)) {
833  if (ec == errc::value_too_large) {
834  // Magic.size() > file_size(Path).
835  result = false;
836  return error_code::success();
837  }
838  return ec;
839  }
840 
841  result = Magic == Buffer;
842  return error_code::success();
843 }
844 
845 /// @brief Identify the magic in magic.
847  if (Magic.size() < 4)
848  return file_magic::unknown;
849  switch ((unsigned char)Magic[0]) {
850  case 0x00: {
851  // COFF short import library file
852  if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff &&
853  Magic[3] == (char)0xff)
855  // Windows resource file
856  const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' };
857  if (Magic.size() >= sizeof(Expected) &&
858  memcmp(Magic.data(), Expected, sizeof(Expected)) == 0)
860  // 0x0000 = COFF unknown machine type
861  if (Magic[1] == 0)
863  break;
864  }
865  case 0xDE: // 0x0B17C0DE = BC wraper
866  if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
867  Magic[3] == (char)0x0B)
868  return file_magic::bitcode;
869  break;
870  case 'B':
871  if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
872  return file_magic::bitcode;
873  break;
874  case '!':
875  if (Magic.size() >= 8)
876  if (memcmp(Magic.data(),"!<arch>\n",8) == 0)
877  return file_magic::archive;
878  break;
879 
880  case '\177':
881  if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
882  Magic[3] == 'F') {
883  bool Data2MSB = Magic[5] == 2;
884  unsigned high = Data2MSB ? 16 : 17;
885  unsigned low = Data2MSB ? 17 : 16;
886  if (Magic[high] == 0)
887  switch (Magic[low]) {
888  default: break;
889  case 1: return file_magic::elf_relocatable;
890  case 2: return file_magic::elf_executable;
891  case 3: return file_magic::elf_shared_object;
892  case 4: return file_magic::elf_core;
893  }
894  }
895  break;
896 
897  case 0xCA:
898  if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
899  Magic[3] == char(0xBE)) {
900  // This is complicated by an overlap with Java class files.
901  // See the Mach-O section in /usr/share/file/magic for details.
902  if (Magic.size() >= 8 && Magic[7] < 43)
904  }
905  break;
906 
907  // The two magic numbers for mach-o are:
908  // 0xfeedface - 32-bit mach-o
909  // 0xfeedfacf - 64-bit mach-o
910  case 0xFE:
911  case 0xCE:
912  case 0xCF: {
913  uint16_t type = 0;
914  if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
915  Magic[2] == char(0xFA) &&
916  (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
917  /* Native endian */
918  if (Magic.size() >= 16) type = Magic[14] << 8 | Magic[15];
919  } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
920  Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
921  Magic[3] == char(0xFE)) {
922  /* Reverse endian */
923  if (Magic.size() >= 14) type = Magic[13] << 8 | Magic[12];
924  }
925  switch (type) {
926  default: break;
927  case 1: return file_magic::macho_object;
928  case 2: return file_magic::macho_executable;
930  case 4: return file_magic::macho_core;
933  case 7: return file_magic::macho_dynamic_linker;
934  case 8: return file_magic::macho_bundle;
935  case 9: return file_magic::macho_dynamic_linker;
936  case 10: return file_magic::macho_dsym_companion;
937  }
938  break;
939  }
940  case 0xF0: // PowerPC Windows
941  case 0x83: // Alpha 32-bit
942  case 0x84: // Alpha 64-bit
943  case 0x66: // MPS R4000 Windows
944  case 0x50: // mc68K
945  case 0x4c: // 80386 Windows
946  if (Magic[1] == 0x01)
948 
949  case 0x90: // PA-RISC Windows
950  case 0x68: // mc68K Windows
951  if (Magic[1] == 0x02)
953  break;
954 
955  case 0x4d: // Possible MS-DOS stub on Windows PE file
956  if (Magic[1] == 0x5a) {
957  uint32_t off =
958  *reinterpret_cast<const support::ulittle32_t*>(Magic.data() + 0x3c);
959  // PE/COFF file, either EXE or DLL.
960  if (off < Magic.size() && memcmp(Magic.data() + off, "PE\0\0",4) == 0)
962  }
963  break;
964 
965  case 0x64: // x86-64 Windows.
966  if (Magic[1] == char(0x86))
968  break;
969 
970  default:
971  break;
972  }
973  return file_magic::unknown;
974 }
975 
976 error_code identify_magic(const Twine &path, file_magic &result) {
978  error_code ec = get_magic(path, Magic.capacity(), Magic);
979  if (ec && ec != errc::value_too_large)
980  return ec;
981 
982  result = identify_magic(Magic);
983  return error_code::success();
984 }
985 
986 namespace {
987 error_code remove_all_r(StringRef path, file_type ft, uint32_t &count) {
988  if (ft == file_type::directory_file) {
989  // This code would be a lot better with exceptions ;/.
990  error_code ec;
991  directory_iterator i(path, ec);
992  if (ec) return ec;
993  for (directory_iterator e; i != e; i.increment(ec)) {
994  if (ec) return ec;
995  file_status st;
996  if (error_code ec = i->status(st)) return ec;
997  if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec;
998  }
999  bool obviously_this_exists;
1000  if (error_code ec = remove(path, obviously_this_exists)) return ec;
1001  assert(obviously_this_exists);
1002  ++count; // Include the directory itself in the items removed.
1003  } else {
1004  bool obviously_this_exists;
1005  if (error_code ec = remove(path, obviously_this_exists)) return ec;
1006  assert(obviously_this_exists);
1007  ++count;
1008  }
1009 
1010  return error_code::success();
1011 }
1012 } // end unnamed namespace
1013 
1014 error_code remove_all(const Twine &path, uint32_t &num_removed) {
1015  SmallString<128> path_storage;
1016  StringRef p = path.toStringRef(path_storage);
1017 
1018  file_status fs;
1019  if (error_code ec = status(path, fs))
1020  return ec;
1021  num_removed = 0;
1022  return remove_all_r(p, fs.type(), num_removed);
1023 }
1024 
1026  return fs::status(Path, result);
1027 }
1028 
1029 } // end namespace fs
1030 } // end namespace sys
1031 } // end namespace llvm
1032 
1033 // Include the truly platform-specific parts.
1034 #if defined(LLVM_ON_UNIX)
1035 #include "Unix/Path.inc"
1036 #endif
1037 #if defined(LLVM_ON_WIN32)
1038 #include "Windows/Path.inc"
1039 #endif
void toVector(SmallVectorImpl< char > &Out) const
Definition: Twine.cpp:26
void set_size(unsigned N)
Definition: SmallVector.h:702
COFF::RelocationTypeX86 Type
Definition: COFFYAML.cpp:227
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:181
bool isSingleStringRef() const
Definition: Twine.h:393
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
error_code status(file_status &result) const
Definition: Path.cpp:1025
bool is_relative(const Twine &path)
Is path relative?
Definition: Path.cpp:628
const StringRef parent_path(StringRef path)
Get parent path.
Definition: Path.cpp:419
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:217
void replace_filename(const Twine &filename, file_status st=file_status())
Definition: Path.cpp:819
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension)
Replace the file extension of path with extension.
Definition: Path.cpp:433
UniqueID getUniqueID() const
bool has_stem(const Twine &path)
Has stem?
Definition: Path.cpp:600
const StringRef extension(StringRef path)
Get extension.
Definition: Path.cpp:484
StringRef substr(size_t Start, size_t N=npos) const
Definition: StringRef.h:392
error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:173
ELF Relocatable object file.
Definition: FileSystem.h:225
bool has_root_directory(const Twine &path)
Has root directory?
Definition: Path.cpp:565
Definition: Path.cpp:158
bool status_known(file_status s)
Is status available?
Definition: Path.cpp:772
bool operator==(const const_iterator &RHS) const
Definition: Path.cpp:271
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:372
void native(const Twine &path, SmallVectorImpl< char > &result)
Definition: Path.cpp:451
void remove_filename(SmallVectorImpl< char > &path)
Remove the last component from path unless it is the root dir.
Definition: Path.cpp:427
#define llvm_unreachable(msg)
error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
Definition: Path.cpp:693
bool is_absolute(const Twine &path)
Is path absolute?
Definition: Path.cpp:614
bool operator!=(const const_iterator &RHS) const
Definition: Path.cpp:276
ELF dynamically linked shared lib.
Definition: FileSystem.h:227
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:56
bool is_separator(char value)
Check whether the given char is a path separator on the host OS.
Definition: Path.cpp:497
const char * data() const
Definition: StringRef.h:107
const StringRef stem(StringRef path)
Get stem.
Definition: Path.cpp:471
bool has_relative_path(const Twine &path)
Has relative path?
Definition: Path.cpp:579
Windows compiled resource file (.rc)
Definition: FileSystem.h:243
StringRef getSingleStringRef() const
Definition: Twine.h:426
error_code getUniqueID(const Twine Path, UniqueID &Result)
Definition: Path.cpp:636
iterator begin() const
Definition: StringRef.h:97
static llvm::error_code createUniqueEntity(const llvm::Twine &Model, int &ResultFD, llvm::SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, unsigned Mode, FSEntity Type)
int memcmp(const void *s1, const void *s2, size_t n);
#define P(N)
ar style archive file
Definition: FileSystem.h:224
error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
void swap(SmallVectorImpl &RHS)
Definition: SmallVector.h:710
bool has_filename(const Twine &path)
Has filename?
Definition: Path.cpp:586
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:812
error_code make_absolute(SmallVectorImpl< char > &path)
Make path an absolute path.
Definition: Path.cpp:700
error_code remove_all(const Twine &path, uint32_t &num_removed)
Recursively remove all files below path, then path. Files are removed as if by POSIX remove()...
Definition: Path.cpp:1014
const StringRef root_directory(StringRef path)
Get root directory.
Definition: Path.cpp:338
const_iterator & operator++()
Definition: Path.cpp:188
ptrdiff_t operator-(const const_iterator &RHS) const
Difference in bytes between this and RHS.
Definition: Path.cpp:280
bool is_symlink(file_status status)
Does status represent a symlink?
Definition: Path.cpp:800
void append(in_iter in_start, in_iter in_end)
Definition: SmallVector.h:445
const std::string & path() const
Definition: FileSystem.h:810
error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath)
Create a file in the system temporary directory.
Definition: Path.cpp:678
bool is_directory(file_status status)
Does status represent a directory?
Definition: Path.cpp:776
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:645
static const char *const Magic
Definition: Archive.cpp:24
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Path.cpp:846
const StringRef root_path(StringRef path)
Get root path.
Definition: Path.cpp:284
size_t find_last_of(char C, size_t From=npos) const
Definition: StringRef.h:291
const_iterator & operator--()
Definition: Path.cpp:241
StringRef toStringRef(SmallVectorImpl< char > &Out) const
Definition: Twine.cpp:31
error_code create_directories(const Twine &path, bool &existed)
Create all the non-existent directories in path.
Definition: Path.cpp:752
size_t strlen(const char *s);
error_code has_magic(const Twine &path, const Twine &magic, bool &result)
Are path's first bytes magic?
Definition: Path.cpp:827
bool is_regular_file(file_status status)
Does status represent a regular file?
Definition: Path.cpp:788
Path iterator.
Definition: Path.h:50
pointer data()
data - Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:135
error_code create_directory(const Twine &path, bool &existed)
Create the directory in path.
static const size_t npos
Definition: StringRef.h:45
static error_code success()
Definition: system_error.h:732
void resize(unsigned N)
Definition: SmallVector.h:401
bool has_root_path(const Twine &path)
Has root path?
Definition: Path.cpp:572
bool has_root_name(const Twine &path)
Has root name?
Definition: Path.cpp:558
const StringRef relative_path(StringRef path)
Get relative path.
Definition: Path.cpp:367
size_t find_first_of(char C, size_t From=0) const
Definition: StringRef.h:269
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
Definition: Path.cpp:507
StringRef toNullTerminatedStringRef(SmallVectorImpl< char > &Out) const
Definition: Twine.cpp:38
bool isTriviallyEmpty() const
Definition: Twine.h:387
iterator end() const
Definition: StringRef.h:99
bool has_extension(const Twine &path)
Has extension?
Definition: Path.cpp:607
const StringRef filename(StringRef path)
Get filename.
Definition: Path.cpp:467
StringRef slice(size_t Start, size_t End) const
Definition: StringRef.h:421
bool exists(file_status status)
Does file exist?
Definition: Path.cpp:768
file_type type() const
Definition: FileSystem.h:192
const StringRef root_name(StringRef path)
Get root name.
Definition: Path.cpp:316
char *getenv(const char *name);
error_code get_magic(const Twine &path, uint32_t len, SmallVectorImpl< char > &result)
Get path's first len bytes.
bool has_parent_path(const Twine &path)
Has parent path?
Definition: Path.cpp:593
FSEntity
Definition: Path.cpp:157
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110