Split openFileForWrite into windows and unix versions.
[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 <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;
31   using llvm::sys::path::is_separator;
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, 2);
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 {
158   FS_Dir,
159   FS_File,
160   FS_Name
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
173 const_iterator begin(StringRef path) {
174   const_iterator i;
175   i.Path      = path;
176   i.Component = find_first_component(path);
177   i.Position  = 0;
178   return i;
179 }
180
181 const_iterator end(StringRef path) {
182   const_iterator i;
183   i.Path      = path;
184   i.Position  = path.size();
185   return i;
186 }
187
188 const_iterator &const_iterator::operator++() {
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
241 const_iterator &const_iterator::operator--() {
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
271 bool const_iterator::operator==(const const_iterator &RHS) const {
272   return Path.begin() == RHS.Path.begin() &&
273          Position == RHS.Position;
274 }
275
276 bool const_iterator::operator!=(const const_iterator &RHS) const {
277   return !(*this == RHS);
278 }
279
280 ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
281   return Position - RHS.Position;
282 }
283
284 const StringRef root_path(StringRef path) {
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
316 const StringRef root_name(StringRef path) {
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
338 const StringRef root_directory(StringRef path) {
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
367 const StringRef relative_path(StringRef path) {
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
387   for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(),
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
413 void append(SmallVectorImpl<char> &path,
414             const_iterator begin, const_iterator end) {
415   for (; begin != end; ++begin)
416     path::append(path, *begin);
417 }
418
419 const StringRef parent_path(StringRef path) {
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
427 void remove_filename(SmallVectorImpl<char> &path) {
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
433 void replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
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   // Clear result.
453   result.clear();
454 #ifdef LLVM_ON_WIN32
455   SmallString<128> path_storage;
456   StringRef p = path.toStringRef(path_storage);
457   result.reserve(p.size());
458   for (StringRef::const_iterator i = p.begin(),
459                                  e = p.end();
460                                  i != e;
461                                  ++i) {
462     if (*i == '/')
463       result.push_back('\\');
464     else
465       result.push_back(*i);
466   }
467 #else
468   path.toVector(result);
469 #endif
470 }
471
472 const StringRef filename(StringRef path) {
473   return *(--end(path));
474 }
475
476 const StringRef stem(StringRef path) {
477   StringRef fname = filename(path);
478   size_t pos = fname.find_last_of('.');
479   if (pos == StringRef::npos)
480     return fname;
481   else
482     if ((fname.size() == 1 && fname == ".") ||
483         (fname.size() == 2 && fname == ".."))
484       return fname;
485     else
486       return fname.substr(0, pos);
487 }
488
489 const StringRef extension(StringRef path) {
490   StringRef fname = filename(path);
491   size_t pos = fname.find_last_of('.');
492   if (pos == StringRef::npos)
493     return StringRef();
494   else
495     if ((fname.size() == 1 && fname == ".") ||
496         (fname.size() == 2 && fname == ".."))
497       return StringRef();
498     else
499       return fname.substr(pos);
500 }
501
502 bool is_separator(char value) {
503   switch(value) {
504 #ifdef LLVM_ON_WIN32
505     case '\\': // fall through
506 #endif
507     case '/': return true;
508     default: return false;
509   }
510 }
511
512 void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
513   result.clear();
514
515 #ifdef __APPLE__
516   // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
517   int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
518                                : _CS_DARWIN_USER_CACHE_DIR;
519   size_t ConfLen = confstr(ConfName, 0, 0);
520   if (ConfLen > 0) {
521     do {
522       result.resize(ConfLen);
523       ConfLen = confstr(ConfName, result.data(), result.size());
524     } while (ConfLen > 0 && ConfLen != result.size());
525
526     if (ConfLen > 0) {
527       assert(result.back() == 0);
528       result.pop_back();
529       return;
530     }
531
532     result.clear();
533   }
534 #endif
535
536   // Check whether the temporary directory is specified by an environment
537   // variable.
538   const char *EnvironmentVariable;
539 #ifdef LLVM_ON_WIN32
540   EnvironmentVariable = "TEMP";
541 #else
542   EnvironmentVariable = "TMPDIR";
543 #endif
544   if (char *RequestedDir = getenv(EnvironmentVariable)) {
545     result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
546     return;
547   }
548
549   // Fall back to a system default.
550   const char *DefaultResult;
551 #ifdef LLVM_ON_WIN32
552   (void)erasedOnReboot;
553   DefaultResult = "C:\\TEMP";
554 #else
555   if (erasedOnReboot)
556     DefaultResult = "/tmp";
557   else
558     DefaultResult = "/var/tmp";
559 #endif
560   result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
561 }
562
563 bool has_root_name(const Twine &path) {
564   SmallString<128> path_storage;
565   StringRef p = path.toStringRef(path_storage);
566
567   return !root_name(p).empty();
568 }
569
570 bool has_root_directory(const Twine &path) {
571   SmallString<128> path_storage;
572   StringRef p = path.toStringRef(path_storage);
573
574   return !root_directory(p).empty();
575 }
576
577 bool has_root_path(const Twine &path) {
578   SmallString<128> path_storage;
579   StringRef p = path.toStringRef(path_storage);
580
581   return !root_path(p).empty();
582 }
583
584 bool has_relative_path(const Twine &path) {
585   SmallString<128> path_storage;
586   StringRef p = path.toStringRef(path_storage);
587
588   return !relative_path(p).empty();
589 }
590
591 bool has_filename(const Twine &path) {
592   SmallString<128> path_storage;
593   StringRef p = path.toStringRef(path_storage);
594
595   return !filename(p).empty();
596 }
597
598 bool has_parent_path(const Twine &path) {
599   SmallString<128> path_storage;
600   StringRef p = path.toStringRef(path_storage);
601
602   return !parent_path(p).empty();
603 }
604
605 bool has_stem(const Twine &path) {
606   SmallString<128> path_storage;
607   StringRef p = path.toStringRef(path_storage);
608
609   return !stem(p).empty();
610 }
611
612 bool has_extension(const Twine &path) {
613   SmallString<128> path_storage;
614   StringRef p = path.toStringRef(path_storage);
615
616   return !extension(p).empty();
617 }
618
619 bool is_absolute(const Twine &path) {
620   SmallString<128> path_storage;
621   StringRef p = path.toStringRef(path_storage);
622
623   bool rootDir = has_root_directory(p),
624 #ifdef LLVM_ON_WIN32
625        rootName = has_root_name(p);
626 #else
627        rootName = true;
628 #endif
629
630   return rootDir && rootName;
631 }
632
633 bool is_relative(const Twine &path) {
634   return !is_absolute(path);
635 }
636
637 } // end namespace path
638
639 namespace fs {
640
641 error_code createUniqueFile(const Twine &Model, int &ResultFd,
642                             SmallVectorImpl<char> &ResultPath, unsigned Mode) {
643   return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
644 }
645
646 error_code createUniqueFile(const Twine &Model,
647                             SmallVectorImpl<char> &ResultPath) {
648   int Dummy;
649   return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
650 }
651
652 static error_code createTemporaryFile(const Twine &Model, int &ResultFD,
653                                       llvm::SmallVectorImpl<char> &ResultPath,
654                                       FSEntity Type) {
655   SmallString<128> Storage;
656   StringRef P = Model.toNullTerminatedStringRef(Storage);
657   assert(P.find_first_of(separators) == StringRef::npos &&
658          "Model must be a simple filename.");
659   // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
660   return createUniqueEntity(P.begin(), ResultFD, ResultPath,
661                             true, owner_read | owner_write, Type);
662 }
663
664 static error_code
665 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
666                     llvm::SmallVectorImpl<char> &ResultPath,
667                     FSEntity Type) {
668   return createTemporaryFile(Prefix + "-%%%%%%." + Suffix, ResultFD, ResultPath,
669                              Type);
670 }
671
672
673 error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
674                                int &ResultFD,
675                                SmallVectorImpl<char> &ResultPath) {
676   return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
677 }
678
679 error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
680                                SmallVectorImpl<char> &ResultPath) {
681   int Dummy;
682   return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
683 }
684
685
686 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
687 // for consistency. We should try using mkdtemp.
688 error_code createUniqueDirectory(const Twine &Prefix,
689                                  SmallVectorImpl<char> &ResultPath) {
690   int Dummy;
691   return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
692                             true, 0, FS_Dir);
693 }
694
695 error_code make_absolute(SmallVectorImpl<char> &path) {
696   StringRef p(path.data(), path.size());
697
698   bool rootDirectory = path::has_root_directory(p),
699 #ifdef LLVM_ON_WIN32
700        rootName = path::has_root_name(p);
701 #else
702        rootName = true;
703 #endif
704
705   // Already absolute.
706   if (rootName && rootDirectory)
707     return error_code::success();
708
709   // All of the following conditions will need the current directory.
710   SmallString<128> current_dir;
711   if (error_code ec = current_path(current_dir)) return ec;
712
713   // Relative path. Prepend the current directory.
714   if (!rootName && !rootDirectory) {
715     // Append path to the current directory.
716     path::append(current_dir, p);
717     // Set path to the result.
718     path.swap(current_dir);
719     return error_code::success();
720   }
721
722   if (!rootName && rootDirectory) {
723     StringRef cdrn = path::root_name(current_dir);
724     SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
725     path::append(curDirRootName, p);
726     // Set path to the result.
727     path.swap(curDirRootName);
728     return error_code::success();
729   }
730
731   if (rootName && !rootDirectory) {
732     StringRef pRootName      = path::root_name(p);
733     StringRef bRootDirectory = path::root_directory(current_dir);
734     StringRef bRelativePath  = path::relative_path(current_dir);
735     StringRef pRelativePath  = path::relative_path(p);
736
737     SmallString<128> res;
738     path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
739     path.swap(res);
740     return error_code::success();
741   }
742
743   llvm_unreachable("All rootName and rootDirectory combinations should have "
744                    "occurred above!");
745 }
746
747 error_code create_directories(const Twine &path, bool &existed) {
748   SmallString<128> path_storage;
749   StringRef p = path.toStringRef(path_storage);
750
751   StringRef parent = path::parent_path(p);
752   if (!parent.empty()) {
753     bool parent_exists;
754     if (error_code ec = fs::exists(parent, parent_exists)) return ec;
755
756     if (!parent_exists)
757       if (error_code ec = create_directories(parent, existed)) return ec;
758   }
759
760   return create_directory(p, existed);
761 }
762
763 bool exists(file_status status) {
764   return status_known(status) && status.type() != file_type::file_not_found;
765 }
766
767 bool status_known(file_status s) {
768   return s.type() != file_type::status_error;
769 }
770
771 bool is_directory(file_status status) {
772   return status.type() == file_type::directory_file;
773 }
774
775 error_code is_directory(const Twine &path, bool &result) {
776   file_status st;
777   if (error_code ec = status(path, st))
778     return ec;
779   result = is_directory(st);
780   return error_code::success();
781 }
782
783 bool is_regular_file(file_status status) {
784   return status.type() == file_type::regular_file;
785 }
786
787 error_code is_regular_file(const Twine &path, bool &result) {
788   file_status st;
789   if (error_code ec = status(path, st))
790     return ec;
791   result = is_regular_file(st);
792   return error_code::success();
793 }
794
795 bool is_symlink(file_status status) {
796   return status.type() == file_type::symlink_file;
797 }
798
799 error_code is_symlink(const Twine &path, bool &result) {
800   file_status st;
801   if (error_code ec = status(path, st))
802     return ec;
803   result = is_symlink(st);
804   return error_code::success();
805 }
806
807 bool is_other(file_status status) {
808   return exists(status) &&
809          !is_regular_file(status) &&
810          !is_directory(status) &&
811          !is_symlink(status);
812 }
813
814 void directory_entry::replace_filename(const Twine &filename, file_status st) {
815   SmallString<128> path(Path.begin(), Path.end());
816   path::remove_filename(path);
817   path::append(path, filename);
818   Path = path.str();
819   Status = st;
820 }
821
822 error_code has_magic(const Twine &path, const Twine &magic, bool &result) {
823   SmallString<32>  MagicStorage;
824   StringRef Magic = magic.toStringRef(MagicStorage);
825   SmallString<32> Buffer;
826
827   if (error_code ec = get_magic(path, Magic.size(), Buffer)) {
828     if (ec == errc::value_too_large) {
829       // Magic.size() > file_size(Path).
830       result = false;
831       return error_code::success();
832     }
833     return ec;
834   }
835
836   result = Magic == Buffer;
837   return error_code::success();
838 }
839
840 /// @brief Identify the magic in magic.
841   file_magic identify_magic(StringRef Magic) {
842   if (Magic.size() < 4)
843     return file_magic::unknown;
844   switch ((unsigned char)Magic[0]) {
845     case 0xDE:  // 0x0B17C0DE = BC wraper
846       if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
847           Magic[3] == (char)0x0B)
848         return file_magic::bitcode;
849       break;
850     case 'B':
851       if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
852         return file_magic::bitcode;
853       break;
854     case '!':
855       if (Magic.size() >= 8)
856         if (memcmp(Magic.data(),"!<arch>\n",8) == 0)
857           return file_magic::archive;
858       break;
859
860     case '\177':
861       if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
862           Magic[3] == 'F') {
863         bool Data2MSB = Magic[5] == 2;
864         unsigned high = Data2MSB ? 16 : 17;
865         unsigned low  = Data2MSB ? 17 : 16;
866         if (Magic[high] == 0)
867           switch (Magic[low]) {
868             default: break;
869             case 1: return file_magic::elf_relocatable;
870             case 2: return file_magic::elf_executable;
871             case 3: return file_magic::elf_shared_object;
872             case 4: return file_magic::elf_core;
873           }
874       }
875       break;
876
877     case 0xCA:
878       if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
879           Magic[3] == char(0xBE)) {
880         // This is complicated by an overlap with Java class files.
881         // See the Mach-O section in /usr/share/file/magic for details.
882         if (Magic.size() >= 8 && Magic[7] < 43)
883           return file_magic::macho_universal_binary;
884       }
885       break;
886
887       // The two magic numbers for mach-o are:
888       // 0xfeedface - 32-bit mach-o
889       // 0xfeedfacf - 64-bit mach-o
890     case 0xFE:
891     case 0xCE:
892     case 0xCF: {
893       uint16_t type = 0;
894       if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
895           Magic[2] == char(0xFA) &&
896           (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
897         /* Native endian */
898         if (Magic.size() >= 16) type = Magic[14] << 8 | Magic[15];
899       } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
900                  Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
901                  Magic[3] == char(0xFE)) {
902         /* Reverse endian */
903         if (Magic.size() >= 14) type = Magic[13] << 8 | Magic[12];
904       }
905       switch (type) {
906         default: break;
907         case 1: return file_magic::macho_object;
908         case 2: return file_magic::macho_executable;
909         case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
910         case 4: return file_magic::macho_core;
911         case 5: return file_magic::macho_preload_executable;
912         case 6: return file_magic::macho_dynamically_linked_shared_lib;
913         case 7: return file_magic::macho_dynamic_linker;
914         case 8: return file_magic::macho_bundle;
915         case 9: return file_magic::macho_dynamic_linker;
916         case 10: return file_magic::macho_dsym_companion;
917       }
918       break;
919     }
920     case 0xF0: // PowerPC Windows
921     case 0x83: // Alpha 32-bit
922     case 0x84: // Alpha 64-bit
923     case 0x66: // MPS R4000 Windows
924     case 0x50: // mc68K
925     case 0x4c: // 80386 Windows
926       if (Magic[1] == 0x01)
927         return file_magic::coff_object;
928
929     case 0x90: // PA-RISC Windows
930     case 0x68: // mc68K Windows
931       if (Magic[1] == 0x02)
932         return file_magic::coff_object;
933       break;
934
935     case 0x4d: // Possible MS-DOS stub on Windows PE file
936       if (Magic[1] == 0x5a) {
937         uint32_t off =
938           *reinterpret_cast<const support::ulittle32_t*>(Magic.data() + 0x3c);
939         // PE/COFF file, either EXE or DLL.
940         if (off < Magic.size() && memcmp(Magic.data() + off, "PE\0\0",4) == 0)
941           return file_magic::pecoff_executable;
942       }
943       break;
944
945     case 0x64: // x86-64 Windows.
946       if (Magic[1] == char(0x86))
947         return file_magic::coff_object;
948       break;
949
950     default:
951       break;
952   }
953   return file_magic::unknown;
954 }
955
956 error_code identify_magic(const Twine &path, file_magic &result) {
957   SmallString<32> Magic;
958   error_code ec = get_magic(path, Magic.capacity(), Magic);
959   if (ec && ec != errc::value_too_large)
960     return ec;
961
962   result = identify_magic(Magic);
963   return error_code::success();
964 }
965
966 namespace {
967 error_code remove_all_r(StringRef path, file_type ft, uint32_t &count) {
968   if (ft == file_type::directory_file) {
969     // This code would be a lot better with exceptions ;/.
970     error_code ec;
971     directory_iterator i(path, ec);
972     if (ec) return ec;
973     for (directory_iterator e; i != e; i.increment(ec)) {
974       if (ec) return ec;
975       file_status st;
976       if (error_code ec = i->status(st)) return ec;
977       if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec;
978     }
979     bool obviously_this_exists;
980     if (error_code ec = remove(path, obviously_this_exists)) return ec;
981     assert(obviously_this_exists);
982     ++count; // Include the directory itself in the items removed.
983   } else {
984     bool obviously_this_exists;
985     if (error_code ec = remove(path, obviously_this_exists)) return ec;
986     assert(obviously_this_exists);
987     ++count;
988   }
989
990   return error_code::success();
991 }
992 } // end unnamed namespace
993
994 error_code remove_all(const Twine &path, uint32_t &num_removed) {
995   SmallString<128> path_storage;
996   StringRef p = path.toStringRef(path_storage);
997
998   file_status fs;
999   if (error_code ec = status(path, fs))
1000     return ec;
1001   num_removed = 0;
1002   return remove_all_r(p, fs.type(), num_removed);
1003 }
1004
1005 error_code directory_entry::status(file_status &result) const {
1006   return fs::status(Path, result);
1007 }
1008
1009 } // end namespace fs
1010 } // end namespace sys
1011 } // end namespace llvm
1012
1013 // Include the truly platform-specific parts.
1014 #if defined(LLVM_ON_UNIX)
1015 #include "Unix/Path.inc"
1016 #endif
1017 #if defined(LLVM_ON_WIN32)
1018 #include "Windows/Path.inc"
1019 #endif