1 //===- llvm/Support/FileUtilities.h - File System Utilities -----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines a family of utility functions which are useful for doing 10 // various things with files. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_SUPPORT_FILEUTILITIES_H 15 #define LLVM_SUPPORT_FILEUTILITIES_H 16 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Support/Errc.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/FileSystem.h" 21 #include "llvm/Support/Path.h" 22 23 namespace llvm { 24 25 /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if 26 /// the files match, 1 if they are different, and 2 if there is a file error. 27 /// This function allows you to specify an absolute and relative FP error that 28 /// is allowed to exist. If you specify a string to fill in for the error 29 /// option, it will set the string to an error message if an error occurs, or 30 /// if the files are different. 31 /// 32 int DiffFilesWithTolerance(StringRef FileA, 33 StringRef FileB, 34 double AbsTol, double RelTol, 35 std::string *Error = nullptr); 36 37 38 /// FileRemover - This class is a simple object meant to be stack allocated. 39 /// If an exception is thrown from a region, the object removes the filename 40 /// specified (if deleteIt is true). 41 /// 42 class FileRemover { 43 SmallString<128> Filename; 44 bool DeleteIt; 45 public: 46 FileRemover() : DeleteIt(false) {} 47 48 explicit FileRemover(const Twine& filename, bool deleteIt = true) 49 : DeleteIt(deleteIt) { 50 filename.toVector(Filename); 51 } 52 53 ~FileRemover() { 54 if (DeleteIt) { 55 // Ignore problems deleting the file. 56 sys::fs::remove(Filename); 57 } 58 } 59 60 /// setFile - Give ownership of the file to the FileRemover so it will 61 /// be removed when the object is destroyed. If the FileRemover already 62 /// had ownership of a file, remove it first. 63 void setFile(const Twine& filename, bool deleteIt = true) { 64 if (DeleteIt) { 65 // Ignore problems deleting the file. 66 sys::fs::remove(Filename); 67 } 68 69 Filename.clear(); 70 filename.toVector(Filename); 71 DeleteIt = deleteIt; 72 } 73 74 /// releaseFile - Take ownership of the file away from the FileRemover so it 75 /// will not be removed when the object is destroyed. 76 void releaseFile() { DeleteIt = false; } 77 }; 78 79 enum class atomic_write_error { 80 failed_to_create_uniq_file = 0, 81 output_stream_error, 82 failed_to_rename_temp_file 83 }; 84 85 class AtomicFileWriteError : public llvm::ErrorInfo<AtomicFileWriteError> { 86 public: 87 AtomicFileWriteError(atomic_write_error Error) : Error(Error) {} 88 89 void log(raw_ostream &OS) const override; 90 91 const atomic_write_error Error; 92 static char ID; 93 94 private: 95 // Users are not expected to use error_code. 96 std::error_code convertToErrorCode() const override { 97 return llvm::inconvertibleErrorCode(); 98 } 99 }; 100 101 // atomic_write_error + whatever the Writer can return 102 103 /// Creates a unique file with name according to the given \p TempPathModel, 104 /// writes content of \p Buffer to the file and renames it to \p FinalPath. 105 /// 106 /// \returns \c AtomicFileWriteError in case of error. 107 llvm::Error writeFileAtomically(StringRef TempPathModel, StringRef FinalPath, 108 StringRef Buffer); 109 110 llvm::Error 111 writeFileAtomically(StringRef TempPathModel, StringRef FinalPath, 112 std::function<llvm::Error(llvm::raw_ostream &)> Writer); 113 } // End llvm namespace 114 115 #endif 116