aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm16/include/llvm/Support/FileUtilities.h
blob: 38efd554cd8aba6741db598d8f03eb456bd6ebc3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===- llvm/Support/FileUtilities.h - File System Utilities -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines a family of utility functions which are useful for doing
// various things with files.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_FILEUTILITIES_H
#define LLVM_SUPPORT_FILEUTILITIES_H

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"

#include <system_error>

namespace llvm {

  /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
  /// the files match, 1 if they are different, and 2 if there is a file error.
  /// This function allows you to specify an absolute and relative FP error that
  /// is allowed to exist.  If you specify a string to fill in for the error
  /// option, it will set the string to an error message if an error occurs, or
  /// if the files are different.
  ///
  int DiffFilesWithTolerance(StringRef FileA,
                             StringRef FileB,
                             double AbsTol, double RelTol,
                             std::string *Error = nullptr);


  /// FileRemover - This class is a simple object meant to be stack allocated.
  /// If an exception is thrown from a region, the object removes the filename
  /// specified (if deleteIt is true).
  ///
  class FileRemover {
    SmallString<128> Filename;
    bool DeleteIt;
  public:
    FileRemover() : DeleteIt(false) {}

    explicit FileRemover(const Twine& filename, bool deleteIt = true)
      : DeleteIt(deleteIt) {
      filename.toVector(Filename);
    }

    ~FileRemover() {
      if (DeleteIt) {
        // Ignore problems deleting the file.
        sys::fs::remove(Filename);
      }
    }

    /// setFile - Give ownership of the file to the FileRemover so it will
    /// be removed when the object is destroyed.  If the FileRemover already
    /// had ownership of a file, remove it first.
    void setFile(const Twine& filename, bool deleteIt = true) {
      if (DeleteIt) {
        // Ignore problems deleting the file.
        sys::fs::remove(Filename);
      }

      Filename.clear();
      filename.toVector(Filename);
      DeleteIt = deleteIt;
    }

    /// releaseFile - Take ownership of the file away from the FileRemover so it
    /// will not be removed when the object is destroyed.
    void releaseFile() { DeleteIt = false; }
  };

  enum class atomic_write_error {
    failed_to_create_uniq_file = 0,
    output_stream_error,
    failed_to_rename_temp_file
  };

  class AtomicFileWriteError : public llvm::ErrorInfo<AtomicFileWriteError> {
  public:
    AtomicFileWriteError(atomic_write_error Error) : Error(Error) {}

    void log(raw_ostream &OS) const override;

    const atomic_write_error Error;
    static char ID;

  private:
    // Users are not expected to use error_code.
    std::error_code convertToErrorCode() const override {
      return llvm::inconvertibleErrorCode();
    }
  };

  // atomic_write_error + whatever the Writer can return

  /// Creates a unique file with name according to the given \p TempPathModel,
  /// writes content of \p Buffer to the file and renames it to \p FinalPath.
  ///
  /// \returns \c AtomicFileWriteError in case of error.
  llvm::Error writeFileAtomically(StringRef TempPathModel, StringRef FinalPath,
                                  StringRef Buffer);

  llvm::Error
  writeFileAtomically(StringRef TempPathModel, StringRef FinalPath,
                      std::function<llvm::Error(llvm::raw_ostream &)> Writer);

  /// FilePermssionsApplier helps to copy permissions from an input file to
  /// an output one. It memorizes the status of the input file and can apply
  /// permissions and dates to the output file.
  class FilePermissionsApplier {
  public:
    static Expected<FilePermissionsApplier> create(StringRef InputFilename);

    /// Apply stored permissions to the \p OutputFilename.
    /// Copy LastAccess and ModificationTime if \p CopyDates is true.
    /// Overwrite stored permissions if \p OverwritePermissions is specified.
    Error
    apply(StringRef OutputFilename, bool CopyDates = false,
          std::optional<sys::fs::perms> OverwritePermissions = std::nullopt);

  private:
    FilePermissionsApplier(StringRef InputFilename, sys::fs::file_status Status)
        : InputFilename(InputFilename), InputStatus(Status) {}

    StringRef InputFilename;
    sys::fs::file_status InputStatus;
  };
} // End llvm namespace

#endif

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif