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