Line data Source code
1 : /* RAII class for managing FILE * for diagnostic formats.
2 : Copyright (C) 2024-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef GCC_DIAGNOSTICS_OUTPUT_FILE_H
22 : #define GCC_DIAGNOSTICS_OUTPUT_FILE_H
23 :
24 : #include "label-text.h"
25 :
26 : namespace diagnostics {
27 :
28 : /* RAII class for wrapping a FILE * that could be borrowed or owned,
29 : along with the underlying filename. */
30 :
31 : class output_file
32 : {
33 : public:
34 38 : output_file ()
35 38 : : m_outf (nullptr),
36 38 : m_owned (false),
37 38 : m_filename ()
38 : {
39 : }
40 128 : output_file (FILE *outf, bool owned, label_text filename)
41 128 : : m_outf (outf),
42 128 : m_owned (owned),
43 128 : m_filename (std::move (filename))
44 : {
45 128 : gcc_assert (m_filename.get ());
46 128 : if (m_owned)
47 128 : gcc_assert (m_outf);
48 128 : }
49 460 : ~output_file ()
50 : {
51 460 : if (m_owned)
52 : {
53 128 : gcc_assert (m_outf);
54 128 : fclose (m_outf);
55 : }
56 460 : }
57 : output_file (const output_file &other) = delete;
58 294 : output_file (output_file &&other)
59 294 : : m_outf (other.m_outf),
60 294 : m_owned (other.m_owned),
61 294 : m_filename (std::move (other.m_filename))
62 : {
63 294 : other.m_outf = nullptr;
64 294 : other.m_owned = false;
65 :
66 294 : gcc_assert (m_filename.get ());
67 294 : if (m_owned)
68 294 : gcc_assert (m_outf);
69 294 : }
70 : output_file &
71 : operator= (const output_file &other) = delete;
72 : output_file &
73 38 : operator= (output_file &&other)
74 : {
75 38 : if (m_owned)
76 : {
77 0 : gcc_assert (m_outf);
78 0 : fclose (m_outf);
79 : }
80 :
81 38 : m_outf = other.m_outf;
82 38 : other.m_outf = nullptr;
83 :
84 38 : m_owned = other.m_owned;
85 38 : other.m_owned = false;
86 :
87 38 : m_filename = std::move (other.m_filename);
88 :
89 38 : if (m_owned)
90 38 : gcc_assert (m_outf);
91 38 : return *this;
92 : }
93 :
94 38 : operator bool () const { return m_outf != nullptr; }
95 256 : FILE *get_open_file () const { return m_outf; }
96 128 : const char *get_filename () const { return m_filename.get (); }
97 :
98 : static output_file
99 : try_to_open (context &dc,
100 : line_maps *line_maps,
101 : const char *base_file_name,
102 : const char *extension,
103 : bool binary);
104 :
105 : private:
106 : FILE *m_outf;
107 : bool m_owned;
108 : label_text m_filename;
109 : };
110 :
111 : } // namespace diagnostics
112 :
113 : #endif /* ! GCC_DIAGNOSTICS_OUTPUT_FILE_H */
|