FileUtilities.h revision 360784
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
23namespace 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